feat: 等比适配#3463
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
<review_stack_artifact> </review_stack_artifact> ✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 13
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/packages/checkbox/checkbox.scss (1)
179-180:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRTL 区域存在缩放变量使用不一致
主样式区域(106-109行)已将边框尺寸从硬编码
10px迁移到$icon-size-10变量,但 RTL 区域这里仍保留硬编码值10px,导致缩放系统在 RTL 布局下无法生效。🔧 建议统一使用缩放变量
&-icon { right: auto; left: 0; - border-right: 10px solid transparent; - border-left: 10px solid $color-primary; + border-right: $icon-size-10 solid transparent; + border-left: $icon-size-10 solid $color-primary;🤖 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/checkbox/checkbox.scss` around lines 179 - 180, 在 checkbox.scss 的 RTL 样式块中将硬编码的边框尺寸替换为缩放变量:把当前的 `border-right: 10px solid transparent;` 和 `border-left: 10px solid $color-primary;` 改为使用 `$icon-size-10`(例如 `border-right: $icon-size-10 solid transparent` / `border-left: $icon-size-10 solid $color-primary`),确保与主样式(已迁移到 `$icon-size-10`)保持一致以支持缩放系统和 RTL 布局;定位时检查 RTL 相关选择器/规则并更新相应属性。
🧹 Nitpick comments (2)
src/styles/variables.scss (1)
2910-2918: ⚡ Quick win
TrendArrow变量被重复定义,建议删除后一段重复块。Line 2911-2918 与前面的定义重复(Line 2861-2868)。当前值虽然一致,但会增加后续漂移风险。
可直接应用的修复
-// TrendArrow -$trendarrow-font-size: var( - --nutui-trendarrow-font-size, - $font-size-base -) !default; -$trendarrow-icon-margin: var( - --nutui-trendarrow-icon-margin, - scale-px(4px) -) !default;🤖 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/styles/variables.scss` around lines 2910 - 2918, The TrendArrow variables ($trendarrow-font-size and $trendarrow-icon-margin) are defined twice; remove the later duplicate block (the second occurrence of the TrendArrow variable definitions) so only the original declarations remain, keeping the first definitions intact to avoid drift and redundancy.src/packages/rate/rate.scss (1)
113-113: ⚡ Quick win确认 line-height 语义映射的设计意图
当前的 line-height 变量映射关系为:
&-normal→$line-height-s(small)&-large→$line-height-xl(extra large)&-small→$line-height-xxs(extra extra small)这个映射中,"normal" 尺寸使用 "small" 行高,命名语义上不够直观。建议确认这是否符合设计系统的预期,或者考虑使用更明确的命名(如
$line-height-normal、$line-height-large、$line-height-small)以提高代码可读性。Also applies to: 118-118, 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/rate/rate.scss` at line 113, The current semantic mapping in the rate component maps selectors &-normal, &-large, &-small to variables $line-height-s, $line-height-xl, $line-height-xxs which makes "normal" use a "small" value; confirm the design intent and either (A) update the variable names in the tokens file (create/rename to $line-height-normal, $line-height-large, $line-height-small) and replace usages in rate.scss (&-normal, &-large, &-small) to reference those clearer names, or (B) if the numeric values are correct as-is, add a short comment above the mappings in rate.scss explaining the intentional semantic mapping to avoid confusion; ensure all three occurrences (the current &-normal, &-large, &-small usages) are updated consistently.
🤖 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 @.cursor/skills/nutui-proportional-scaling/SKILL.md:
- Line 118: Update the branch name reference: replace the string "feat_resize"
with the actual source branch name "feat_v3.x_resize" in the SKILL.md text so
the docs match the PR; ensure the sentence that references "当前分支 `feat_resize`
最新提交` and the referenced files `src/utils/scale-f*.ts` and
`src/styles/variables.scss` use the corrected branch name "feat_v3.x_resize" for
consistency.
- Line 56: 文案中 Markdown 粗体配对错误:把 “不写回\*\*仓库里的组件 SCSS” 改为成对的粗体标记,例如 “不写回**仓库里的组件
SCSS**”,以避免多余星号被渲染出来;相关上下文可在描述包含
scripts/replace-css-var.js、scripts/build.mjs、scripts/build-taro.mjs 和
scripts/px-to-scale-px-in-component-scss.cjs、以及 src/packages/*.scss 的那一行中修改。
In `@scripts/px-to-scale-px-in-component-scss.cjs`:
- Around line 64-70: The loop currently breaks on the first calc(...) that
shouldn't be protected, which skips any later calc(...) that need protection;
change the logic so you skip that non-protectable match and continue scanning
instead of breaking. Concretely, update the while loop that uses
findInnermostCalcRange(v) / shouldProtectCalcBody(m.body) / saved: replace the
break with logic that advances the scan past m (either by adding a pos/index and
calling findInnermostCalcRange(v, pos) or by replacing the non-protectable span
with a harmless placeholder and continuing) so the loop won't re-match the same
m and will continue to find and protect subsequent calc(...) occurrences.
In `@src/packages/button/button.taro.tsx`:
- Line 131: The Loading JSX prop uses a nonstandard name ariaHidden which
mismatches the Loading component's ARIA typings and causes TS2322; update the
Loading usage (the Loading component instance in button.taro.tsx) to pass the
standard ARIA attribute name aria-hidden with the appropriate boolean/string
value (e.g., aria-hidden={true} or "true") instead of ariaHidden so the prop
type and build error are resolved.
In `@src/packages/numberkeyboard/numberkeyboard.scss`:
- Around line 9-12: The .numberkeyboard-delete-icon rule uses a hardcoded
width/height of 28px while .close-icon uses the $icon-size-18 variable; replace
the hardcoded values in the &-delete-icon block with the appropriate icon size
variable (e.g. $icon-size-28 or the closest existing $icon-size-*), or add a
comment in the &-delete-icon block explaining why this size must be fixed and
cannot use the icon variable; reference the selectors &-delete-icon and
.close-icon and the variables $icon-size-18/$icon-size-28 when making the
change.
In `@src/packages/overlay/overlay.tsx`:
- Line 41: The component currently spreads a nonstandard prop ariaLabel onto the
<div>, which won't produce the standard aria-label attribute and TypeScript
flags it; update the prop types (WebOverlayProps or BaseProps) to include
ariaLabel?: string for developer convenience, stop spreading ariaLabel directly,
and instead pass it explicitly to the rendered div as {'aria-label': ariaLabel}
(keep other props spread as before) inside the Overlay component so the DOM
receives a proper aria-label and TS no longer errors.
In `@src/packages/swipe/swipe.scss`:
- Around line 34-37: 在 swipe.scss 中修复 stylelint 违规:在双斜线注释 "//left: 100%;"
前添加一个空行以满足 scss/double-slash-comment-empty-line-before 规则,确保注释前有一个空白行并保存以避免 CI
lint 失败。
In `@src/packages/table/table.scss`:
- Around line 136-140: 修复表格主体选择器 (&-body) 的 display 值:当前在
src/packages/table/table.scss 中的 &-body 将 display 误设为 table-header-group,应改为
table-row-group;保留现有的条件注释(/* `#ifndef` dynamic*/ ... /* `#endif` */)不变,直接替换 display:
table-header-group 为 display: table-row-group,以恢复正确的语义渲染。
In `@src/packages/tabs/tabs.scss`:
- Around line 96-105: &-smile-icon 中使用了硬编码的 width: 40px / height:
20px,违背了项目的缩放变量体系;替换这两个硬编码值为项目统一的图标尺寸变量(例如 $icon-size-sm / $icon-size-md 等)或使用
scale-px() 辅助函数,并在 variables.scss 中新增或确认相应的 $icon-size-* 变量名,确保选择器 &-smile-icon
使用这些变量(或 scale-px 调用)来实现等比响应式缩放。
In `@src/packages/tabs/tabs.taro.tsx`:
- Around line 280-289: The View wrapper in tabs.taro.tsx uses a non-typed prop
ariaHidden with a // `@ts-ignore` comment; remove the ignore and either replace
ariaHidden with a supported accessibility prop (e.g., hidden, ariaLabel,
ariaRole) on the Taro <View> or augment the View prop types so ariaHidden is
valid; specifically update the JSX around the <View
className={`${classPrefix}-titles-item-smile`} ariaHidden> that contains the
<JoySmile /> icon to use a Taro-supported prop (or add a declaration
merging/type definition for ariaHidden) and ensure type-checking passes without
// `@ts-ignore`.
In `@src/packages/tour/tour.scss`:
- Around line 32-33: Replace the hardcoded width/height of 10px in tour.scss
with the project scaling token so the component participates in the responsive
scale system; specifically, change the fixed values in the rule where width:
10px and height: 10px appear to use the $icon-size-10 variable or wrap with the
scale-px() utility (e.g., use $icon-size-10 or scale-px($icon-size-10)),
ensuring both width and height use the same scaled variable.
In `@src/styles/theme-default.scss`:
- Around line 294-304: The SCSS block has comments immediately preceding
variable declarations (e.g., the comments before --nutui-font-size-base,
--nutui-font-size-l, --nutui-font-size-md, --nutui-font-size-xl,
--nutui-font-size-2xl) without a blank line, triggering
scss/double-slash-comment-empty-line-before; fix by inserting a single empty
line before each of those double-slash comments so each comment is separated
from the previous code/line, ensuring the linter rule is satisfied.
In `@src/styles/variables.scss`:
- Around line 3-4: The `page` selector in variables.scss triggers stylelint's
selector-type-no-unknown and blocks CI; add a single-line rule exemption for
that selector by disabling selector-type-no-unknown for that line (e.g., insert
a stylelint disable-next-line or disable-line comment immediately adjacent to
the `page` selector) so the `:root, page {` rule keeps small-program semantics
but no longer fails the linter.
---
Outside diff comments:
In `@src/packages/checkbox/checkbox.scss`:
- Around line 179-180: 在 checkbox.scss 的 RTL 样式块中将硬编码的边框尺寸替换为缩放变量:把当前的
`border-right: 10px solid transparent;` 和 `border-left: 10px solid
$color-primary;` 改为使用 `$icon-size-10`(例如 `border-right: $icon-size-10 solid
transparent` / `border-left: $icon-size-10 solid $color-primary`),确保与主样式(已迁移到
`$icon-size-10`)保持一致以支持缩放系统和 RTL 布局;定位时检查 RTL 相关选择器/规则并更新相应属性。
---
Nitpick comments:
In `@src/packages/rate/rate.scss`:
- Line 113: The current semantic mapping in the rate component maps selectors
&-normal, &-large, &-small to variables $line-height-s, $line-height-xl,
$line-height-xxs which makes "normal" use a "small" value; confirm the design
intent and either (A) update the variable names in the tokens file
(create/rename to $line-height-normal, $line-height-large, $line-height-small)
and replace usages in rate.scss (&-normal, &-large, &-small) to reference those
clearer names, or (B) if the numeric values are correct as-is, add a short
comment above the mappings in rate.scss explaining the intentional semantic
mapping to avoid confusion; ensure all three occurrences (the current &-normal,
&-large, &-small usages) are updated consistently.
In `@src/styles/variables.scss`:
- Around line 2910-2918: The TrendArrow variables ($trendarrow-font-size and
$trendarrow-icon-margin) are defined twice; remove the later duplicate block
(the second occurrence of the TrendArrow variable definitions) so only the
original declarations remain, keeping the first definitions intact to avoid
drift and redundancy.
🪄 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: 82340196-0e36-40e0-b447-944c5de8951c
📒 Files selected for processing (92)
.cursor/skills/nutui-build-local-verify/SKILL.md.cursor/skills/nutui-build-local-verify/scripts/verify-scale-generation.mjs.cursor/skills/nutui-proportional-scaling/SKILL.mdpackages/nutui-taro-demo/src/app.tsscripts/build-taro.mjsscripts/build.mjsscripts/generate-css-for-rtl-comparison.jsscripts/px-to-scale-px-in-component-scss.cjsscripts/replace-css-var.jssrc/packages/address/address.scsssrc/packages/audio/audio.scsssrc/packages/avatarcropper/avatarcropper.taro.tsxsrc/packages/button/button.scsssrc/packages/button/button.taro.tsxsrc/packages/calendar/calendar.scsssrc/packages/calendarcard/calendarcard.scsssrc/packages/card/card.scsssrc/packages/checkbox/checkbox.scsssrc/packages/configprovider/types.tssrc/packages/dialog/dialog.scsssrc/packages/fixednav/fixednav.scsssrc/packages/hoverbuttonitem/hoverbuttonitem.scsssrc/packages/input/input.scsssrc/packages/inputnumber/inputnumber.scsssrc/packages/inputnumber/inputnumber.taro.tsxsrc/packages/menu/menu.scsssrc/packages/menu/menu.taro.tsxsrc/packages/menu/menu.tsxsrc/packages/menuitem/menuitem.scsssrc/packages/menuitem/menuitem.taro.tsxsrc/packages/navbar/navbar.scsssrc/packages/noticebar/noticebar.scsssrc/packages/noticebar/noticebar.taro.tsxsrc/packages/noticebar/noticebar.tsxsrc/packages/notify/notify.scsssrc/packages/notify/notify.taro.tsxsrc/packages/numberkeyboard/numberkeyboard.scsssrc/packages/numberkeyboard/numberkeyboard.taro.tsxsrc/packages/numberkeyboard/numberkeyboard.tsxsrc/packages/overlay/overlay.tsxsrc/packages/popover/popover.scsssrc/packages/popover/popover.taro.tsxsrc/packages/popover/popover.tsxsrc/packages/popup/popup.scsssrc/packages/price/price.scsssrc/packages/pulltorefresh/pulltorefresh.scsssrc/packages/quickenter/quickenter.scsssrc/packages/range/range.scsssrc/packages/rate/rate.scsssrc/packages/rate/rate.taro.tsxsrc/packages/searchbar/demos/h5/demo6.tsxsrc/packages/searchbar/searchbar.scsssrc/packages/segmented/segmented.scsssrc/packages/shortpassword/shortpassword.scsssrc/packages/shortpassword/shortpassword.taro.tsxsrc/packages/shortpassword/shortpassword.tsxsrc/packages/space/space.scsssrc/packages/step/step.scsssrc/packages/steps/steps.scsssrc/packages/swipe/demos/h5/demo1.tsxsrc/packages/swipe/demos/h5/demo3.tsxsrc/packages/swipe/demos/h5/demo4.tsxsrc/packages/swipe/demos/h5/demo5.tsxsrc/packages/swipe/demos/h5/demo6.tsxsrc/packages/swipe/demos/h5/demo7.tsxsrc/packages/swipe/demos/h5/demo8.tsxsrc/packages/swipe/demos/h5/demo9.tsxsrc/packages/swipe/swipe.scsssrc/packages/tabbar/tabbar.scsssrc/packages/tabbaritem/tabbaritem.scsssrc/packages/table/table.scsssrc/packages/tabs/tabs.scsssrc/packages/tabs/tabs.taro.tsxsrc/packages/tabs/tabs.tsxsrc/packages/tag/tag.scsssrc/packages/tag/tag.taro.tsxsrc/packages/tag/tag.tsxsrc/packages/timeselect/timeselect.scsssrc/packages/toast/toast.scsssrc/packages/tour/tour.scsssrc/packages/uploader/uploader.scsssrc/packages/virtuallist/virtuallist.scsssrc/sites/mobile/main.tsxsrc/styles/theme-dark.scsssrc/styles/theme-default.scsssrc/styles/variables-daojia.scsssrc/styles/variables-jmapp.scsssrc/styles/variables-jrkf.scsssrc/styles/variables.scsssrc/utils/index.taro.tssrc/utils/index.tssrc/utils/scale-f.ts
💤 Files with no reviewable changes (4)
- src/packages/menuitem/menuitem.taro.tsx
- src/packages/inputnumber/inputnumber.taro.tsx
- src/packages/button/button.scss
- src/packages/step/step.scss
|
|
||
| ### 2.1 `npm run build` / `npm run build:taro` 时的 px → `scale-px` | ||
|
|
||
| - 与 `package.json` 中顺序一致:先跑 **`scripts/replace-css-var.js`**,再 **`scripts/build.mjs`** 或 **`scripts/build-taro.mjs`**;上述脚本在读取 **`src/packages/**/\*.scss`(不含 demo)** 后,会经 **`scripts/px-to-scale-px-in-component-scss.cjs`** 在**内存**里把声明值中的裸 **`Npx`** 转为 **`scale-px(Npx)`**(规则见 §3),**不写回\*\*仓库里的组件 SCSS。 |
There was a problem hiding this comment.
修正文案中的 Markdown 强调符号错误
Line 56 的 **不写回\*\*仓库里的组件 SCSS 会渲染出多余星号,建议改为成对加粗,避免读者误解。
建议修改
-- 与 `package.json` 中顺序一致:先跑 **`scripts/replace-css-var.js`**,再 **`scripts/build.mjs`** 或 **`scripts/build-taro.mjs`**;上述脚本在读取 **`src/packages/**/\*.scss`(不含 demo)** 后,会经 **`scripts/px-to-scale-px-in-component-scss.cjs`** 在**内存**里把声明值中的裸 **`Npx`** 转为 **`scale-px(Npx)`**(规则见 §3),**不写回\*\*仓库里的组件 SCSS。
+- 与 `package.json` 中顺序一致:先跑 **`scripts/replace-css-var.js`**,再 **`scripts/build.mjs`** 或 **`scripts/build-taro.mjs`**;上述脚本在读取 **`src/packages/**/\*.scss`(不含 demo)** 后,会经 **`scripts/px-to-scale-px-in-component-scss.cjs`** 在**内存**里把声明值中的裸 **`Npx`** 转为 **`scale-px(Npx)`**(规则见 §3),**不写回**仓库里的组件 SCSS。📝 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.
| - 与 `package.json` 中顺序一致:先跑 **`scripts/replace-css-var.js`**,再 **`scripts/build.mjs`** 或 **`scripts/build-taro.mjs`**;上述脚本在读取 **`src/packages/**/\*.scss`(不含 demo)** 后,会经 **`scripts/px-to-scale-px-in-component-scss.cjs`** 在**内存**里把声明值中的裸 **`Npx`** 转为 **`scale-px(Npx)`**(规则见 §3),**不写回\*\*仓库里的组件 SCSS。 | |
| - 与 `package.json` 中顺序一致:先跑 **`scripts/replace-css-var.js`**,再 **`scripts/build.mjs`** 或 **`scripts/build-taro.mjs`**;上述脚本在读取 **`src/packages/**/\*.scss`(不含 demo)** 后,会经 **`scripts/px-to-scale-px-in-component-scss.cjs`** 在**内存**里把声明值中的裸 **`Npx`** 转为 **`scale-px(Npx)`**(规则见 §3),**不写回**仓库里的组件 SCSS。 |
🧰 Tools
🪛 LanguageTool
[grammar] ~56-~56: Ensure spelling is correct
Context: ... 时的 px → scale-px - 与 package.json 中顺序一致:先跑 scripts/replace-css-var.js,再 **`s...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🤖 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 @.cursor/skills/nutui-proportional-scaling/SKILL.md at line 56, 文案中 Markdown
粗体配对错误:把 “不写回\*\*仓库里的组件 SCSS” 改为成对的粗体标记,例如 “不写回**仓库里的组件
SCSS**”,以避免多余星号被渲染出来;相关上下文可在描述包含
scripts/replace-css-var.js、scripts/build.mjs、scripts/build-taro.mjs 和
scripts/px-to-scale-px-in-component-scss.cjs、以及 src/packages/*.scss 的那一行中修改。
| - [ ] TS 侧改 `scale-f*` 已同步考虑 **Taro** 文件。 | ||
| - [ ] 修改 `formatScaleValue` / 断点时,已通读 **视口与平板常量** 是否仍与文档、设计一致。 | ||
|
|
||
| 若与上游分支分歧,以**当前分支 `feat_resize` 最新提交**及 `src/utils/scale-f*.ts`、`src/styles/variables.scss` 为准。 |
There was a problem hiding this comment.
分支名建议与当前 PR 保持一致
Line 118 目前写的是 feat_resize,但当前 PR 的源分支是 feat_v3.x_resize。建议统一,避免按文档追溯时定位到错误分支。
建议修改
-若与上游分支分歧,以**当前分支 `feat_resize` 最新提交**及 `src/utils/scale-f*.ts`、`src/styles/variables.scss` 为准。
+若与上游分支分歧,以**当前分支 `feat_v3.x_resize` 最新提交**及 `src/utils/scale-f*.ts`、`src/styles/variables.scss` 为准。📝 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.
| 若与上游分支分歧,以**当前分支 `feat_resize` 最新提交**及 `src/utils/scale-f*.ts`、`src/styles/variables.scss` 为准。 | |
| 若与上游分支分歧,以**当前分支 `feat_v3.x_resize` 最新提交**及 `src/utils/scale-f*.ts`、`src/styles/variables.scss` 为准。 |
🤖 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 @.cursor/skills/nutui-proportional-scaling/SKILL.md at line 118, Update the
branch name reference: replace the string "feat_resize" with the actual source
branch name "feat_v3.x_resize" in the SKILL.md text so the docs match the PR;
ensure the sentence that references "当前分支 `feat_resize` 最新提交` and the referenced
files `src/utils/scale-f*.ts` and `src/styles/variables.scss` use the corrected
branch name "feat_v3.x_resize" for consistency.
| while (true) { | ||
| const m = findInnermostCalcRange(v) | ||
| if (!m) break | ||
| if (!shouldProtectCalcBody(m.body)) break | ||
| saved.push(v.slice(m.start, m.end)) | ||
| v = `${v.slice(0, m.start)}__NUT_CALC_${saved.length - 1}__${v.slice(m.end)}` | ||
| } |
There was a problem hiding this comment.
calc 保护循环会提前退出,后续需保护的表达式可能漏掉。
Line 67 在首个不满足条件的 calc(...) 上直接 break,会导致同一声明里后续包含 $ 和 / 的 calc(...) 未被占位保护。
💡 建议修复
-/** 最左侧的「体内不含 calc(」的 calc 块(同一层里先处理最左) */
-function findInnermostCalcRange(str) {
+/** 最左侧的「体内不含 calc( 且需要保护」的 calc 块 */
+function findProtectableCalcRange(str) {
let best = null
let scan = 0
const lower = str.toLowerCase()
while (true) {
const idx = lower.indexOf('calc(', scan)
@@
const body = str.slice(openParen + 1, close)
- if (!body.toLowerCase().includes('calc(')) {
+ if (
+ !body.toLowerCase().includes('calc(') &&
+ shouldProtectCalcBody(body)
+ ) {
if (!best || idx < best.start) {
best = { start: idx, end: close + 1, body }
}
@@
function protectCalcsForPxPass(value) {
const saved = []
let v = value
while (true) {
- const m = findInnermostCalcRange(v)
+ const m = findProtectableCalcRange(v)
if (!m) break
- if (!shouldProtectCalcBody(m.body)) break
saved.push(v.slice(m.start, m.end))
v = `${v.slice(0, m.start)}__NUT_CALC_${saved.length - 1}__${v.slice(m.end)}`
}
return { value: v, saved }
}🤖 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/px-to-scale-px-in-component-scss.cjs` around lines 64 - 70, The loop
currently breaks on the first calc(...) that shouldn't be protected, which skips
any later calc(...) that need protection; change the logic so you skip that
non-protectable match and continue scanning instead of breaking. Concretely,
update the while loop that uses findInnermostCalcRange(v) /
shouldProtectCalcBody(m.body) / saved: replace the break with logic that
advances the scan past m (either by adding a pos/index and calling
findInnermostCalcRange(v, pos) or by replacing the non-protectable span with a
harmless placeholder and continuing) so the loop won't re-match the same m and
will continue to find and protect subsequent calc(...) occurrences.
| > | ||
| <View className="nut-button-wrap"> | ||
| {loading && <Loading className="nut-icon-loading" />} | ||
| {loading && <Loading ariaHidden className="nut-icon-loading" />} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Inspect the target file around the cited line
sed -n '110,160p' src/packages/button/button.taro.tsx | cat -n
# 2) Locate the Loading import and its origin
rg -n "from ['\"].*icons-react-taro|from ['\"].*Loading|<Loading\b" src/packages/button/button.taro.tsx
# 3) Find the definition of SVG_IconProps and/or ariaHidden/aria-hidden in the repo
fd -t f ".*\\.d\\.ts$" . --hidden --follow --exclude-dir node_modules 2>/dev/null | head -n 1 >/dev/null || true
rg -n "interface\s+SVG_IconProps|type\s+SVG_IconProps|SVG_IconProps" . || true
rg -n "\bariaHidden\b|aria-hidden" src node_modules 2>/dev/null || true
# 4) Search for "Loading" component typing (if it's declared in-repo)
rg -n "export (type|interface) .*Loading|function Loading|const Loading|class Loading" . || true
# 5) If node_modules exists, directly search within installed package typings for SVG_IconProps / ariaHidden
if [ -d node_modules ]; then
rg -n "SVG_IconProps" node_modules/@nutui/icons-react-taro 2>/dev/null || true
rg -n "\bariaHidden\b|aria-hidden" node_modules/@nutui/icons-react-taro 2>/dev/null || true
fiRepository: jdf2e/nutui-react
Length of output: 32995
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show relevant surrounding code for taro icon ariaHidden usage
sed -n '1,140p' src/packages/radio/radio.taro.tsx | cat -n | sed -n '1,140p'
sed -n '250,330p' src/packages/tabs/tabs.taro.tsx | cat -n
sed -n '60,130p' src/packages/checkbox/checkbox.taro.tsx | cat -n
sed -n '90,150p' src/packages/quickenter/quickenter.taro.tsx | cat -n
# Confirm button import location already (small snippet)
sed -n '1,160p' src/packages/button/button.taro.tsx | cat -n | sed -n '110,150p'
# Search for SVG_IconProps declaration in-repo
rg -n "interface\s+SVG_IconProps|type\s+SVG_IconProps|SVG_IconProps" . || trueRepository: jdf2e/nutui-react
Length of output: 14596
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check whether node_modules exists and the icons package is present
ls -la node_modules 2>/dev/null || true
ls -la node_modules/@nutui 2>/dev/null || true
ls -la node_modules/@nutui/icons-react-taro 2>/dev/null || true
# If present, print candidate typing files (small)
if [ -d node_modules/@nutui/icons-react-taro ]; then
echo "---- typing files ----"
find node_modules/@nutui/icons-react-taro -maxdepth 3 -type f \( -name "*.d.ts" -o -name "*.ts" \) | head -n 50
echo "---- search SVG_IconProps ----"
rg -n "SVG_IconProps" node_modules/@nutui/icons-react-taro || true
echo "---- search ariaHidden ----"
rg -n "ariaHidden" node_modules/@nutui/icons-react-taro || true
fi
# Also check dependency declarations (in repo) for version hint
rg -n "\"`@nutui/icons-react-taro`\"" package.json yarn.lock pnpm-lock.yaml package-lock.json 2>/dev/null || trueRepository: jdf2e/nutui-react
Length of output: 126
🌐 Web query:
@nutui/icons-react-taro 3.0.2-beta.3 SVG_IconProps ariaHidden
💡 Result:
@nutui/icons-react-taro 3.0.2-beta.3 の SVG_IconProps に ariaHidden(camelCase)という名前の prop は確認できませんでした。公開情報として見つかったのは当該パッケージの npm ページ(README なし)と、props 型の参照箇所でしたが、SVG_IconProps の定義や ariaHidden / aria-hidden の扱いがソース上で明示されている箇所まで到達できませんでした。[1] 考え方としては、React で ARIA 属性は通常 aria-hidden(kebab-case)の指定が正しく、ariaHidden だと無効な ARIA 属性扱いになるケースがあります。[2] 結論(実務的な対処): - ariaHidden ではなく aria-hidden を使うのが安全です。[2] - もし SVG_IconProps に対応する prop 名がライブラリ都合で別名になっている可能性があるため、ライブラリの SVG_IconProps 型定義(型ファイル)を直接確認し、そこにある prop 名に合わせてください(今回の調査では型定義へ到達できず断定できません)。[1]
Citations:
- 1: https://www.npmjs.com/package/%40nutui%2Ficons-react-taro
- 2: https://stackoverflow.com/questions/74570405/react-next-js-invalid-aria-attribute-ariahidden-did-you-mean-aria-hidde
修复 Loading 的 ARIA prop 命名以消除 TS2322(ariaHidden → aria-hidden)
src/packages/button/button.taro.tsx 第 131 行给 Loading 传入了 ariaHidden,该 prop 名与图标组件的类型不匹配(会触发构建报错),且应使用标准 ARIA 属性名 aria-hidden。
🔧 建议修复
- {loading && <Loading ariaHidden className="nut-icon-loading" />}
+ {loading && <Loading aria-hidden="true" className="nut-icon-loading" />}📝 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.
| {loading && <Loading ariaHidden className="nut-icon-loading" />} | |
| {loading && <Loading aria-hidden="true" className="nut-icon-loading" />} |
🧰 Tools
🪛 GitHub Actions: CI / 1_build.txt
[error] 131-131: TypeScript error TS2322: Type '{ ariaHidden: true; className: string; }' is not assignable to type 'IntrinsicAttributes & SVG_IconProps'.
🪛 GitHub Actions: CI / build
[error] 131-131: TypeScript error TS2322: Type '{ ariaHidden: true; className: string; }' is not assignable to type 'IntrinsicAttributes & SVG_IconProps'.
🪛 GitHub Check: build
[failure] 131-131:
Type '{ ariaHidden: true; className: string; }' is not assignable to type 'IntrinsicAttributes & SVG_IconProps'.
🤖 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 131, The Loading JSX prop uses a
nonstandard name ariaHidden which mismatches the Loading component's ARIA
typings and causes TS2322; update the Loading usage (the Loading component
instance in button.taro.tsx) to pass the standard ARIA attribute name
aria-hidden with the appropriate boolean/string value (e.g., aria-hidden={true}
or "true") instead of ariaHidden so the prop type and build error are resolved.
| &-delete-icon { | ||
| width: 28px; | ||
| height: 28px; | ||
| } |
There was a problem hiding this comment.
图标尺寸使用不一致:建议使用变量或说明原因
delete-icon 使用硬编码 28px,而 close-icon 使用了 $icon-size-18 变量。在等比缩放适配体系中,硬编码的 px 值不会随缩放因子调整,可能导致不同屏幕尺寸下的视觉不协调。
建议使用相应的 $icon-size-* 变量(如 $icon-size-28 或最接近的尺寸变量),或在注释中说明为何此处需要固定尺寸。
🤖 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/numberkeyboard/numberkeyboard.scss` around lines 9 - 12, The
.numberkeyboard-delete-icon rule uses a hardcoded width/height of 28px while
.close-icon uses the $icon-size-18 variable; replace the hardcoded values in the
&-delete-icon block with the appropriate icon size variable (e.g. $icon-size-28
or the closest existing $icon-size-*), or add a comment in the &-delete-icon
block explaining why this size must be fixed and cannot use the icon variable;
reference the selectors &-delete-icon and .close-icon and the variables
$icon-size-18/$icon-size-28 when making the change.
| font-size: $font-size-2xl; | ||
| width: 100%; | ||
| height: 100%; | ||
| } | ||
| } | ||
|
|
||
| &-smile-icon { | ||
| width: 40px; | ||
| height: 20px; | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
新增的图标尺寸应使用缩放变量
Line 96 将 font-size 迁移到 $font-size-2xl 变量符合缩放系统目标,但新增的 &-smile-icon 选择器(Lines 102-105)中使用了硬编码的 width: 40px 和 height: 20px,这与本 PR 建立的等比缩放体系不一致。
建议使用 $icon-size-* 系列变量或 scale-px() 函数来确保图标尺寸也能响应式缩放。
♻️ 建议的修复
&-smile-icon {
- width: 40px;
- height: 20px;
+ width: $icon-smile-width; // 或使用 scale-px(40px)
+ height: $icon-smile-height; // 或使用 scale-px(20px)
}注:需在 variables.scss 中定义相应的图标尺寸变量。
🤖 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/tabs/tabs.scss` around lines 96 - 105, &-smile-icon 中使用了硬编码的
width: 40px / height: 20px,违背了项目的缩放变量体系;替换这两个硬编码值为项目统一的图标尺寸变量(例如 $icon-size-sm /
$icon-size-md 等)或使用 scale-px() 辅助函数,并在 variables.scss 中新增或确认相应的 $icon-size-*
变量名,确保选择器 &-smile-icon 使用这些变量(或 scale-px 调用)来实现等比响应式缩放。
| width: 10px; | ||
| height: 10px; |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
考虑使用缩放变量替代固定像素值
当前从 CSS 变量改为固定的 10px,这与本 PR 建立等比缩放系统的目标不一致。建议使用 $icon-size-10 变量或通过 scale-px() 函数包裹,以支持响应式缩放。
♻️ 建议的修改
&-close {
- width: 10px;
- height: 10px;
+ width: $icon-size-10;
+ height: $icon-size-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/tour/tour.scss` around lines 32 - 33, Replace the hardcoded
width/height of 10px in tour.scss with the project scaling token so the
component participates in the responsive scale system; specifically, change the
fixed values in the rule where width: 10px and height: 10px appear to use the
$icon-size-10 variable or wrap with the scale-px() utility (e.g., use
$icon-size-10 or scale-px($icon-size-10)), ensuring both width and height use
the same scaled variable.
| // 标准内容、名称类关键信息 | ||
| --nutui-font-size-base: var(--nutui-font-size-14); | ||
| // 汉字:楼层标题、卡片标题 数字:重复型价格,如搜推商卡 | ||
| --nutui-font-size-l: var(--nutui-font-size-15); | ||
| // l(15) 与 xl(18) 之间,价格整数 normal 等(16px,字阶缩放) | ||
| --nutui-font-size-md: var(--nutui-font-size-16); | ||
| --nutui-font-size-icon: var(--nutui-font-size-16); | ||
| // 汉字:页面标题、页面级最重要内容 数字:模块级主价格,如购物车、结算、底导 | ||
| --nutui-font-size-xl: var(--nutui-font-size-18); | ||
| // xl(18) 与 xxl(24) 之间(20px) | ||
| --nutui-font-size-2xl: var(--nutui-font-size-20); |
There was a problem hiding this comment.
该段注释前缺少空行,存在 stylelint 报错风险。
Line 294、296、298、301、303 的注释触发 scss/double-slash-comment-empty-line-before。建议按规则补空行,避免 lint 阶段失败。
🧰 Tools
🪛 Stylelint (17.11.1)
[error] 294-294: Expected empty line before comment (scss/double-slash-comment-empty-line-before)
(scss/double-slash-comment-empty-line-before)
[error] 296-296: Expected empty line before comment (scss/double-slash-comment-empty-line-before)
(scss/double-slash-comment-empty-line-before)
[error] 298-298: Expected empty line before comment (scss/double-slash-comment-empty-line-before)
(scss/double-slash-comment-empty-line-before)
[error] 301-301: Expected empty line before comment (scss/double-slash-comment-empty-line-before)
(scss/double-slash-comment-empty-line-before)
[error] 303-303: Expected empty line before comment (scss/double-slash-comment-empty-line-before)
(scss/double-slash-comment-empty-line-before)
🤖 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/styles/theme-default.scss` around lines 294 - 304, The SCSS block has
comments immediately preceding variable declarations (e.g., the comments before
--nutui-font-size-base, --nutui-font-size-l, --nutui-font-size-md,
--nutui-font-size-xl, --nutui-font-size-2xl) without a blank line, triggering
scss/double-slash-comment-empty-line-before; fix by inserting a single empty
line before each of those double-slash comments so each comment is separated
from the previous code/line, ensuring the linter rule is satisfied.
| :root, | ||
| page { |
There was a problem hiding this comment.
page 选择器会触发当前 stylelint 报错并可能阻塞 CI。
Line 4 的 page 在当前规则下报 selector-type-no-unknown。建议做单行规则豁免,保留小程序语义同时避免构建失败。
可直接应用的修复
:root,
+/* stylelint-disable-next-line selector-type-no-unknown */
page {📝 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.
| :root, | |
| page { | |
| :root, | |
| /* stylelint-disable-next-line selector-type-no-unknown */ | |
| page { |
🧰 Tools
🪛 Stylelint (17.11.1)
[error] 4-4: Unknown type selector "page" (selector-type-no-unknown)
(selector-type-no-unknown)
🤖 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/styles/variables.scss` around lines 3 - 4, The `page` selector in
variables.scss triggers stylelint's selector-type-no-unknown and blocks CI; add
a single-line rule exemption for that selector by disabling
selector-type-no-unknown for that line (e.g., insert a stylelint
disable-next-line or disable-line comment immediately adjacent to the `page`
selector) so the `:root, page {` rule keeps small-program semantics but no
longer fails the linter.
1744d8b to
f5daab3
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/packages/numberkeyboard/numberkeyboard.taro.tsx (1)
74-82:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winDelete 图标仍是内联固定尺寸,和等比适配策略不一致。
close已切到样式控制,但DeleteIcon仍写死width/height,会导致 taro 端该图标无法随缩放变量统一适配。建议给DeleteIcon增加${classPrefix}-delete-icon,并把尺寸移到 SCSS。💡 建议改动
- const DeleteIcon = () => { + const DeleteIcon = () => { const style = { background: `url('data:image/png;base64,...') no-repeat center`, backgroundSize: '100% 100%', - width: 28, - height: 24, } - return <View style={style} /> + return <View className={`${classPrefix}-delete-icon`} style={style} /> }Also applies to: 116-118
🤖 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/numberkeyboard/numberkeyboard.taro.tsx` around lines 74 - 82, DeleteIcon currently hardcodes width/height in its inline style, breaking the global scaling strategy; update the component to add a className using classPrefix (e.g. className={`${classPrefix}-delete-icon`}) and remove the fixed width/height (and backgroundSize if you prefer SCSS control) from the inline style so only the background image remains in the component, then move sizing/backgroundSize rules into the SCSS under the new .{classPrefix}-delete-icon selector; apply the same change to the other icon instance referenced around lines 116-118 so both icons use class-based sizing.
♻️ Duplicate comments (3)
src/styles/theme-default.scss (1)
294-304:⚠️ Potential issue | 🟠 Major | ⚡ Quick win该段注释前缺少空行,存在 stylelint 失败风险。
此范围触发
scss/double-slash-comment-empty-line-before。建议按规则在注释前补空行,避免 CI 被 lint 阶段阻塞。🤖 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/styles/theme-default.scss` around lines 294 - 304, Add a blank line immediately before the double-slash comment that precedes the CSS custom properties (the comment starting with "// 标准内容、名称类关键信息") to satisfy the scss/double-slash-comment-empty-line-before rule; locate the block defining variables like --nutui-font-size-base, --nutui-font-size-l, --nutui-font-size-md, --nutui-font-size-icon, --nutui-font-size-xl and --nutui-font-size-2xl and insert one empty line above that first comment (and mirror this spacing for any adjacent // comments in the same region) so stylelint no longer fails.src/styles/variables.scss (1)
3-4:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
page选择器会触发当前 stylelint 报错。Line 4 的
page触发selector-type-no-unknown。建议按单行豁免保留语义,避免 lint 失败。🤖 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/styles/variables.scss` around lines 3 - 4, The `page` type selector triggers stylelint rule selector-type-no-unknown; preserve the semantic selector but add a single-line stylelint exemption immediately before the `page` selector so the linter ignores that specific line (keep the existing `:root,` and `page` grouping and only exempt the `page` token). Refer to the `page` selector in src/styles/variables.scss and the rule name `selector-type-no-unknown` when adding the inline exemption.scripts/px-to-scale-px-in-component-scss.cjs (1)
64-70:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
calc保护循环会提前中断,后续可保护表达式会漏处理。Line 67 遇到首个“不需要保护”的
calc(...)就break,会导致同一声明中后续真正需要保护的calc(...)没机会进入占位流程。应改为“跳过当前并继续扫描”,而不是终止循环。🤖 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/px-to-scale-px-in-component-scss.cjs` around lines 64 - 70, The loop currently breaks on the first calc(...) that shouldn't be protected, which stops processing later calc() occurrences; instead, when shouldProtectCalcBody(m.body) is false do not break—replace the matched range with a non-matching placeholder and continue scanning so the loop moves past this calc and keeps finding later ones; update the while loop around findInnermostCalcRange(v) to (a) avoid break on non-protected matches, (b) inject a unique skip placeholder (e.g. __NUT_SKIPPED_{n}__) for the skipped match so findInnermostCalcRange won't re-match it, and (c) maintain any counter/state analogous to saved so placeholders remain unique.
🧹 Nitpick comments (3)
src/packages/input/input.scss (1)
19-22: ⚡ Quick win建议统一图标的
width/height/font-size尺寸来源。Line 19-21 目前只有
font-size使用变量,width/height仍固定 14px;在主题覆盖$font-size-base时可能出现图标裁切。建议修改
.nut-icon { color: $color-text-disabled; - width: 14px; - height: 14px; + width: $font-size-base; + height: $font-size-base; font-size: $font-size-base; }🤖 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/input/input.scss` around lines 19 - 22, 当前样式将 width/height 固定为 14px 而 font-size 使用变量 $font-size-base,导致主题修改 $font-size-base 时图标可能被裁切;请将 width 和 height 改为使用统一的尺寸变量(例如复用 $font-size-base 或新增 $icon-size 基于 $font-size-base 计算),并在相同规则中替换原有的固定 14px,确保 font-size、width 和 height 来自同一变量(参考属性 width, height, font-size 和变量 $font-size-base)。src/packages/segmented/segmented.scss (1)
35-43: ⚡ Quick win建议把图标容器固定 10px 改为缩放变量
Line 37-38 与 Line 41-42 仍是固定
10px,和本 PR 的等比适配目标不一致,建议统一为图标尺寸 token。♻️ 建议修改
.nut-segmented-icon { display: flex; align-items: center; - height: 10px; - width: 10px; + height: $icon-size-10; + width: $icon-size-10; margin-right: $segmented-icon-margin-right; .nut-icon { - height: 10px; - width: 10px; + height: $icon-size-10; + width: $icon-size-10; font-size: $font-size-xxs; } }🤖 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/segmented/segmented.scss` around lines 35 - 43, 当前样式中两处固定的 10px(选择器块的 height/width 和 .nut-icon 的 height/width)与 PR 的等比缩放目标不一致;请将这四处硬编码的 10px 替换为统一的图标尺寸 token(例如 $segmented-icon-size 或团队现有的 $icon-size),并保留现有的 margin-right:$segmented-icon-margin-right 和 font-size:$font-size-xxs 不变或按需改为基于该 token 的计算值;定位符号参考选择器的 height/width 和 .nut-icon 的 height/width。src/packages/steps/steps.scss (1)
159-165: ⚡ Quick win建议避免新增固定 20px,改为语义变量或缩放表达式
Line 161 和 Line 225 的
20px建议改成现有 steps 变量(如与$steps-vertical-line-height或对应 head 高度变量对齐),保持 profile 缩放一致。♻️ 建议修改
&-title { height: auto; - line-height: 20px; + line-height: $steps-vertical-line-height; white-space: normal; overflow-wrap: break-word; text-align: center; } &-head { align-items: center; justify-content: center; - height: 20px; + height: $steps-vertical-line-height; }Also applies to: 222-226
🤖 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/steps/steps.scss` around lines 159 - 165, Replace the hardcoded "20px" in the .steps-title rule (selector &-title) with the existing semantic steps variable or a scaling expression (for example use the project's $steps-vertical-line-height or the steps head-height variable) so the line-height scales consistently with other steps metrics; update both occurrences (the one in the shown block and the one around lines 222-226) to reference the variable rather than a fixed 20px.
🤖 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/card/card.scss`:
- Around line 30-31: The Stylelint rule declaration-empty-line-before is
violated because declarations (line-height: $line-height-2xl; and font-size:
$font-size-base;) follow a mixin invocation without a separating blank line; fix
by inserting a single empty line between the mixin call and these declarations
in src/packages/card/card.scss so the mixin block and the subsequent
declarations are visually separated and the linter passes.
In `@src/styles/theme-dark.scss`:
- Around line 294-305: 在 theme-dark.scss 中有多处使用双斜线注释前未留空行触发 stylelint 规则
scss/double-slash-comment-empty-line-before;在注释前为每个相关注释关键点(例如在
--nutui-font-size-m、--nutui-font-size-base、--nutui-font-size-l /
--nutui-font-size-md、--nutui-font-size-icon、--nutui-font-size-xl、--nutui-font-size-2xl
等变量注释处)各插入一个空行以满足规则,保存后重新运行样式检查确保没有报错。
In `@src/styles/variables.scss`:
- Around line 311-314: Multiple SCSS dollar-variable declarations (e.g.,
$button-xlarge-height, and the other variables at the mentioned locations)
violate the scss/dollar-variable-empty-line-before rule; open the variable
blocks and either add or remove the empty line before each $-prefixed variable
to match the project's lint rule consistently (ensure the pattern used around
$button-xlarge-height, the variables at lines ~332, ~360-363, ~461-464, ~583,
and ~2734-2735 follows the same empty-line policy), run the linter to confirm no
more scss/dollar-variable-empty-line-before violations, and commit the
formatting change.
In `@src/utils/scale-f.ts`:
- Around line 175-183: refreshScaleF has a race: concurrent calls can return
out-of-order and a slow earlier call can overwrite a newer scale when calling
setScaleF; fix by adding a monotonic request id or token (module-scoped, e.g.
refreshSeq/currentRefreshToken) that's incremented when refreshScaleF starts,
capture it in the async call, and only call setScaleF(nextScale) if the captured
token equals the latest token; apply the same guard when calling setScaleProfile
if needed so only the most recent refresh commits its results (use identifiers
around refreshScaleF, setScaleProfile, getScaleF, scale, setScaleF).
---
Outside diff comments:
In `@src/packages/numberkeyboard/numberkeyboard.taro.tsx`:
- Around line 74-82: DeleteIcon currently hardcodes width/height in its inline
style, breaking the global scaling strategy; update the component to add a
className using classPrefix (e.g. className={`${classPrefix}-delete-icon`}) and
remove the fixed width/height (and backgroundSize if you prefer SCSS control)
from the inline style so only the background image remains in the component,
then move sizing/backgroundSize rules into the SCSS under the new
.{classPrefix}-delete-icon selector; apply the same change to the other icon
instance referenced around lines 116-118 so both icons use class-based sizing.
---
Duplicate comments:
In `@scripts/px-to-scale-px-in-component-scss.cjs`:
- Around line 64-70: The loop currently breaks on the first calc(...) that
shouldn't be protected, which stops processing later calc() occurrences;
instead, when shouldProtectCalcBody(m.body) is false do not break—replace the
matched range with a non-matching placeholder and continue scanning so the loop
moves past this calc and keeps finding later ones; update the while loop around
findInnermostCalcRange(v) to (a) avoid break on non-protected matches, (b)
inject a unique skip placeholder (e.g. __NUT_SKIPPED_{n}__) for the skipped
match so findInnermostCalcRange won't re-match it, and (c) maintain any
counter/state analogous to saved so placeholders remain unique.
In `@src/styles/theme-default.scss`:
- Around line 294-304: Add a blank line immediately before the double-slash
comment that precedes the CSS custom properties (the comment starting with "//
标准内容、名称类关键信息") to satisfy the scss/double-slash-comment-empty-line-before rule;
locate the block defining variables like --nutui-font-size-base,
--nutui-font-size-l, --nutui-font-size-md, --nutui-font-size-icon,
--nutui-font-size-xl and --nutui-font-size-2xl and insert one empty line above
that first comment (and mirror this spacing for any adjacent // comments in the
same region) so stylelint no longer fails.
In `@src/styles/variables.scss`:
- Around line 3-4: The `page` type selector triggers stylelint rule
selector-type-no-unknown; preserve the semantic selector but add a single-line
stylelint exemption immediately before the `page` selector so the linter ignores
that specific line (keep the existing `:root,` and `page` grouping and only
exempt the `page` token). Refer to the `page` selector in
src/styles/variables.scss and the rule name `selector-type-no-unknown` when
adding the inline exemption.
---
Nitpick comments:
In `@src/packages/input/input.scss`:
- Around line 19-22: 当前样式将 width/height 固定为 14px 而 font-size 使用变量
$font-size-base,导致主题修改 $font-size-base 时图标可能被裁切;请将 width 和 height
改为使用统一的尺寸变量(例如复用 $font-size-base 或新增 $icon-size 基于 $font-size-base
计算),并在相同规则中替换原有的固定 14px,确保 font-size、width 和 height 来自同一变量(参考属性 width, height,
font-size 和变量 $font-size-base)。
In `@src/packages/segmented/segmented.scss`:
- Around line 35-43: 当前样式中两处固定的 10px(选择器块的 height/width 和 .nut-icon 的
height/width)与 PR 的等比缩放目标不一致;请将这四处硬编码的 10px 替换为统一的图标尺寸 token(例如
$segmented-icon-size 或团队现有的 $icon-size),并保留现有的
margin-right:$segmented-icon-margin-right 和 font-size:$font-size-xxs 不变或按需改为基于该
token 的计算值;定位符号参考选择器的 height/width 和 .nut-icon 的 height/width。
In `@src/packages/steps/steps.scss`:
- Around line 159-165: Replace the hardcoded "20px" in the .steps-title rule
(selector &-title) with the existing semantic steps variable or a scaling
expression (for example use the project's $steps-vertical-line-height or the
steps head-height variable) so the line-height scales consistently with other
steps metrics; update both occurrences (the one in the shown block and the one
around lines 222-226) to reference the variable rather than a fixed 20px.
🪄 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: 9a80b4d5-ce7f-4a7e-a265-fa8bde22f251
📒 Files selected for processing (81)
.cursor/skills/nutui-build-local-verify/SKILL.md.cursor/skills/nutui-build-local-verify/scripts/verify-scale-generation.mjs.cursor/skills/nutui-proportional-scaling/SKILL.mdpackages/nutui-taro-demo/src/app.tsscripts/generate-css-for-rtl-comparison.jsscripts/px-to-scale-px-in-component-scss.cjsscripts/replace-css-var.jssrc/packages/address/address.scsssrc/packages/audio/audio.scsssrc/packages/calendar/calendar.scsssrc/packages/calendarcard/calendarcard.scsssrc/packages/card/card.scsssrc/packages/checkbox/checkbox.scsssrc/packages/configprovider/types.tssrc/packages/fixednav/fixednav.scsssrc/packages/hoverbuttonitem/hoverbuttonitem.scsssrc/packages/input/input.scsssrc/packages/inputnumber/inputnumber.scsssrc/packages/inputnumber/inputnumber.taro.tsxsrc/packages/menu/menu.scsssrc/packages/menu/menu.taro.tsxsrc/packages/menu/menu.tsxsrc/packages/menuitem/menuitem.scsssrc/packages/menuitem/menuitem.taro.tsxsrc/packages/navbar/navbar.scsssrc/packages/noticebar/noticebar.scsssrc/packages/noticebar/noticebar.taro.tsxsrc/packages/noticebar/noticebar.tsxsrc/packages/notify/notify.scsssrc/packages/notify/notify.taro.tsxsrc/packages/numberkeyboard/numberkeyboard.scsssrc/packages/numberkeyboard/numberkeyboard.taro.tsxsrc/packages/numberkeyboard/numberkeyboard.tsxsrc/packages/popover/popover.scsssrc/packages/popover/popover.taro.tsxsrc/packages/popover/popover.tsxsrc/packages/popup/popup.scsssrc/packages/price/price.scsssrc/packages/pulltorefresh/pulltorefresh.scsssrc/packages/quickenter/quickenter.scsssrc/packages/range/range.scsssrc/packages/rate/rate.scsssrc/packages/searchbar/demos/h5/demo6.tsxsrc/packages/searchbar/searchbar.scsssrc/packages/segmented/segmented.scsssrc/packages/shortpassword/shortpassword.scsssrc/packages/shortpassword/shortpassword.taro.tsxsrc/packages/shortpassword/shortpassword.tsxsrc/packages/space/space.scsssrc/packages/step/step.scsssrc/packages/steps/steps.scsssrc/packages/swipe/demos/h5/demo1.tsxsrc/packages/swipe/demos/h5/demo3.tsxsrc/packages/swipe/demos/h5/demo4.tsxsrc/packages/swipe/demos/h5/demo5.tsxsrc/packages/swipe/demos/h5/demo6.tsxsrc/packages/swipe/demos/h5/demo7.tsxsrc/packages/swipe/demos/h5/demo8.tsxsrc/packages/swipe/demos/h5/demo9.tsxsrc/packages/swipe/swipe.scsssrc/packages/tabbar/tabbar.scsssrc/packages/tabbaritem/tabbaritem.scsssrc/packages/tabs/tabs.scsssrc/packages/tabs/tabs.tsxsrc/packages/tag/tag.scsssrc/packages/tag/tag.taro.tsxsrc/packages/tag/tag.tsxsrc/packages/timeselect/timeselect.scsssrc/packages/tour/tour.scsssrc/packages/uploader/uploader.scsssrc/packages/virtuallist/virtuallist.scsssrc/sites/mobile/main.tsxsrc/styles/theme-dark.scsssrc/styles/theme-default.scsssrc/styles/variables-daojia.scsssrc/styles/variables-jmapp.scsssrc/styles/variables-jrkf.scsssrc/styles/variables.scsssrc/utils/index.taro.tssrc/utils/index.tssrc/utils/scale-f.ts
💤 Files with no reviewable changes (3)
- src/packages/inputnumber/inputnumber.taro.tsx
- src/packages/menuitem/menuitem.taro.tsx
- src/packages/step/step.scss
✅ Files skipped from review due to trivial changes (22)
- src/packages/tabbaritem/tabbaritem.scss
- src/packages/range/range.scss
- src/packages/swipe/demos/h5/demo1.tsx
- src/packages/shortpassword/shortpassword.tsx
- src/packages/tag/tag.scss
- src/packages/swipe/demos/h5/demo4.tsx
- src/packages/audio/audio.scss
- src/packages/navbar/navbar.scss
- src/packages/swipe/demos/h5/demo5.tsx
- src/packages/hoverbuttonitem/hoverbuttonitem.scss
- src/packages/noticebar/noticebar.scss
- src/packages/tabbar/tabbar.scss
- src/packages/timeselect/timeselect.scss
- src/packages/checkbox/checkbox.scss
- src/packages/space/space.scss
- src/packages/virtuallist/virtuallist.scss
- .cursor/skills/nutui-build-local-verify/SKILL.md
- src/packages/tag/tag.taro.tsx
- src/packages/tabs/tabs.scss
- src/packages/popup/popup.scss
- src/packages/quickenter/quickenter.scss
- src/packages/swipe/demos/h5/demo6.tsx
| line-height: $line-height-2xl; | ||
| font-size: $font-size-base; |
There was a problem hiding this comment.
修复 Stylelint 规则违规,避免样式检查失败。
Line 30 在 mixin 后直接跟声明,触发 declaration-empty-line-before,建议补一个空行。
建议修改
&-title {
`@include` moreline-ellipsis();
+
line-height: $line-height-2xl;
font-size: $font-size-base;
color: $color-title;
}📝 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.
| line-height: $line-height-2xl; | |
| font-size: $font-size-base; | |
| &-title { | |
| `@include` moreline-ellipsis(); | |
| line-height: $line-height-2xl; | |
| font-size: $font-size-base; | |
| color: $color-title; | |
| } |
🧰 Tools
🪛 Stylelint (17.11.1)
[error] 30-30: Expected empty line before declaration (declaration-empty-line-before)
(declaration-empty-line-before)
🤖 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/card/card.scss` around lines 30 - 31, The Stylelint rule
declaration-empty-line-before is violated because declarations (line-height:
$line-height-2xl; and font-size: $font-size-base;) follow a mixin invocation
without a separating blank line; fix by inserting a single empty line between
the mixin call and these declarations in src/packages/card/card.scss so the
mixin block and the subsequent declarations are visually separated and the
linter passes.
| --nutui-font-size-m: var(--nutui-font-size-13); | ||
| // 标准内容、名称类关键信息 | ||
| --nutui-font-size-base: var(--nutui-font-size-14); | ||
| // 汉字:楼层标题、卡片标题 数字:重复型价格,如搜推商卡 | ||
| --nutui-font-size-l: var(--nutui-font-size-16); | ||
| // 16px 字阶(与 l 同档数值,供 --nutui-font-size-md 语义) | ||
| --nutui-font-size-md: var(--nutui-font-size-16); | ||
| --nutui-font-size-icon: var(--nutui-font-size-16); | ||
| // 汉字:页面标题、页面级最重要内容 数字:模块级主价格,如购物车、结算、底导 | ||
| --nutui-font-size-xl: var(--nutui-font-size-18); | ||
| // xl(18) 与 xxl(24) 之间(20px) | ||
| --nutui-font-size-2xl: var(--nutui-font-size-20); |
There was a problem hiding this comment.
修复注释空行规则以避免样式检查失败。
该段在注释前缺少空行,触发了 scss/double-slash-comment-empty-line-before(Line 295、Line 297、Line 299、Line 302、Line 304)。建议在对应注释前补一行空行,避免 CI 被 stylelint 阻塞。
建议修改
--nutui-font-size-l: var(--nutui-font-size-16);
+
// 16px 字阶(与 l 同档数值,供 --nutui-font-size-md 语义)
--nutui-font-size-md: var(--nutui-font-size-16);
--nutui-font-size-icon: var(--nutui-font-size-16);
+
// 汉字:页面标题、页面级最重要内容 数字:模块级主价格,如购物车、结算、底导
--nutui-font-size-xl: var(--nutui-font-size-18);
+
// xl(18) 与 xxl(24) 之间(20px)
--nutui-font-size-2xl: var(--nutui-font-size-20);🧰 Tools
🪛 Stylelint (17.11.1)
[error] 295-295: Expected empty line before comment (scss/double-slash-comment-empty-line-before)
(scss/double-slash-comment-empty-line-before)
[error] 297-297: Expected empty line before comment (scss/double-slash-comment-empty-line-before)
(scss/double-slash-comment-empty-line-before)
[error] 299-299: Expected empty line before comment (scss/double-slash-comment-empty-line-before)
(scss/double-slash-comment-empty-line-before)
[error] 302-302: Expected empty line before comment (scss/double-slash-comment-empty-line-before)
(scss/double-slash-comment-empty-line-before)
[error] 304-304: Expected empty line before comment (scss/double-slash-comment-empty-line-before)
(scss/double-slash-comment-empty-line-before)
🤖 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/styles/theme-dark.scss` around lines 294 - 305, 在 theme-dark.scss
中有多处使用双斜线注释前未留空行触发 stylelint 规则
scss/double-slash-comment-empty-line-before;在注释前为每个相关注释关键点(例如在
--nutui-font-size-m、--nutui-font-size-base、--nutui-font-size-l /
--nutui-font-size-md、--nutui-font-size-icon、--nutui-font-size-xl、--nutui-font-size-2xl
等变量注释处)各插入一个空行以满足规则,保存后重新运行样式检查确保没有报错。
| async function refreshScaleF(nextProfile?: ScaleProfile) { | ||
| if (nextProfile) { | ||
| setScaleProfile(nextProfile) | ||
| } | ||
| const nextScale = await getScaleF() | ||
| if (!scale || nextScale !== scale) { | ||
| setScaleF(nextScale) | ||
| } | ||
| return scale |
There was a problem hiding this comment.
并发刷新存在竞态,旧请求可能覆盖新缩放值。
refreshScaleF 是异步的,Line 191-193 在 resize 高频触发下会并发执行;较早发起但较晚返回的请求可能在最后调用 setScaleF,把更新后的缩放值回滚成旧值。建议加“请求序号/最新请求令牌”保护,只允许最新一次刷新落盘。
可参考的最小修复
let profile: ScaleProfile = 'standard'
+let refreshSeq = 0
async function refreshScaleF(nextProfile?: ScaleProfile) {
+ const seq = ++refreshSeq
if (nextProfile) {
setScaleProfile(nextProfile)
}
const nextScale = await getScaleF()
+ if (seq !== refreshSeq) return scale
if (!scale || nextScale !== scale) {
setScaleF(nextScale)
}
return scale
}Also applies to: 191-193
🤖 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/scale-f.ts` around lines 175 - 183, refreshScaleF has a race:
concurrent calls can return out-of-order and a slow earlier call can overwrite a
newer scale when calling setScaleF; fix by adding a monotonic request id or
token (module-scoped, e.g. refreshSeq/currentRefreshToken) that's incremented
when refreshScaleF starts, capture it in the async call, and only call
setScaleF(nextScale) if the captured token equals the latest token; apply the
same guard when calling setScaleProfile if needed so only the most recent
refresh commits its results (use identifiers around refreshScaleF,
setScaleProfile, getScaleF, scale, setScaleF).
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/packages/tabs/tabs.tsx (1)
188-193:⚠️ Potential issue | 🟡 Minor | ⚡ Quick win恢复装饰图标的无障碍隐藏属性。
Line 188 的 smile 装饰容器建议加回
aria-hidden="true",避免读屏器读出无语义图标内容。建议修改
- <div className={`${classPrefix}-titles-item-smile`}> + <div + className={`${classPrefix}-titles-item-smile`} + aria-hidden="true" + >🤖 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/tabs/tabs.tsx` around lines 188 - 193, The decorative smile icon container currently lacks an accessibility hiding attribute; update the JSX where the div with className `${classPrefix}-titles-item-smile` (which wraps the JoySmile component) to add aria-hidden="true" (and optionally role="presentation") so screen readers ignore this non-semantic ornament, leaving the JoySmile usage and activeColor prop unchanged.
🧹 Nitpick comments (1)
package.json (1)
104-105: ⚡ Quick win避免将公共 npm 脚本绑定到
.cursor目录。Line 104-105 当前路径对编辑器私有目录有耦合,容易在 CI 或非 Cursor 环境出现脚本不可用。建议把验证脚本放到仓库常规
scripts/目录后再引用。建议修改
- "verify-scale": "node .cursor/skills/nutui-build-local-verify/scripts/verify-scale-generation.mjs", - "verify-scale:mirror": "node .cursor/skills/nutui-build-local-verify/scripts/verify-scale-generation.mjs --mirror" + "verify-scale": "node scripts/verify-scale-generation.mjs", + "verify-scale:mirror": "node scripts/verify-scale-generation.mjs --mirror"🤖 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 `@package.json` around lines 104 - 105, The package.json scripts "verify-scale" and "verify-scale:mirror" currently reference a private editor directory (.cursor/skills/nutui-build-local-verify/scripts/verify-scale-generation.mjs); move the verification script(s) from .cursor/skills/nutui-build-local-verify/scripts/ into a repo-level scripts/ directory (e.g., scripts/verify-scale-generation.mjs), update the "verify-scale" and "verify-scale:mirror" entries to call node scripts/verify-scale-generation.mjs (preserving the --mirror arg for the mirror script), and adjust any other references/imports to that file accordingly so CI and non-Cursor environments can run the scripts.
🤖 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.
Outside diff comments:
In `@src/packages/tabs/tabs.tsx`:
- Around line 188-193: The decorative smile icon container currently lacks an
accessibility hiding attribute; update the JSX where the div with className
`${classPrefix}-titles-item-smile` (which wraps the JoySmile component) to add
aria-hidden="true" (and optionally role="presentation") so screen readers ignore
this non-semantic ornament, leaving the JoySmile usage and activeColor prop
unchanged.
---
Nitpick comments:
In `@package.json`:
- Around line 104-105: The package.json scripts "verify-scale" and
"verify-scale:mirror" currently reference a private editor directory
(.cursor/skills/nutui-build-local-verify/scripts/verify-scale-generation.mjs);
move the verification script(s) from
.cursor/skills/nutui-build-local-verify/scripts/ into a repo-level scripts/
directory (e.g., scripts/verify-scale-generation.mjs), update the "verify-scale"
and "verify-scale:mirror" entries to call node
scripts/verify-scale-generation.mjs (preserving the --mirror arg for the mirror
script), and adjust any other references/imports to that file accordingly so CI
and non-Cursor environments can run the scripts.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 90e1b8c1-09d7-4ab4-9a0b-53c8e6e70dd9
📒 Files selected for processing (6)
package.jsonscripts/build-taro.mjsscripts/build.mjssrc/packages/tabs/tabs.taro.tsxsrc/packages/tabs/tabs.tsxsrc/packages/toast/toast.scss
✅ Files skipped from review due to trivial changes (1)
- src/packages/tabs/tabs.taro.tsx
| padding-right: $price-symbol-padding-right; | ||
| &-xlarge { | ||
| font-size: $price-symbol-xlarge-size; | ||
| line-height: $price-minor-line-height; |
| &-text { | ||
| color: #ffffff; | ||
| text-align: $toast-inner-text-align; | ||
| line-height: 20px; |
There was a problem hiding this comment.
需要放在 ifdef 下边
ifndef 这个里
| font-size: $toast-title-font-size; | ||
| font-weight: 600; | ||
| text-align: $toast-inner-text-align; | ||
| line-height: 22px; |
There was a problem hiding this comment.
保留 左侧 /* #ifndef harmony dynamic*/
line-height: 22px;
/* #endif */
| // 标准内容、名称类关键信息 | ||
| --nutui-font-size-base: var(--nutui-font-size-14); | ||
| // 汉字:楼层标题、卡片标题 数字:重复型价格,如搜推商卡 | ||
| --nutui-font-size-l: var(--nutui-font-size-16); |
Co-authored-by: Cursor <cursoragent@cursor.com>
🤔 这个变动的性质是?
🔗 相关 Issue
💡 需求背景和解决方案
☑️ 请求合并前的自查清单
Summary by CodeRabbit
发布说明
New Features
Refactor
Documentation