Skip to content

feat: 等比多尺寸适配#3457

Open
irisSong wants to merge 19 commits into
jdf2e:feat_v3.x_cppfrom
irisSong:feat_resize_optimize
Open

feat: 等比多尺寸适配#3457
irisSong wants to merge 19 commits into
jdf2e:feat_v3.x_cppfrom
irisSong:feat_resize_optimize

Conversation

@irisSong
Copy link
Copy Markdown
Collaborator

@irisSong irisSong commented May 12, 2026

🤔 这个变动的性质是?

  • 新特性提交
  • 日常 bug 修复
  • 站点、文档改进
  • 演示代码改进
  • 组件样式/交互改进
  • TypeScript 定义更新
  • 包体积优化
  • 性能优化
  • 功能增强
  • 国际化改进
  • 重构
  • 代码风格优化
  • 测试用例
  • 分支合并
  • 其他改动(是关于什么的改动?)

🔗 相关 Issue

💡 需求背景和解决方案

☑️ 请求合并前的自查清单

⚠️ 请自检并全部勾选全部选项⚠️

  • 文档已补充或无须补充
  • 代码演示已提供或无须提供
  • TypeScript 定义已补充或无须补充
  • fork仓库代码是否为最新避免文件冲突
  • Files changed 没有 package.json lock 等无关文件

Summary by CodeRabbit

  • New Features

    • 引入全局响应式等比缩放系统,支持标准/大号/老年三种模式并统一字体、图标与间距缩放。
  • Improvements

    • 大量组件样式由硬编码像素替换为设计令牌,提升一致性与可适配性。
    • 构建流程新增 SCSS 预处理以在构建时应用缩放转换;H5/Taro 入口已集成缩放初始化与卸载。
  • Documentation

    • 补充缩放使用指南、提交规范与校验清单。

Review Change Stack

@github-actions github-actions Bot added the action:review This PR needs more reviews (less than 2 approvals) label May 12, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

新增运行时缩放工具(scale-f)、构建时 SCSS px->scale-px 转换器并集成到构建脚本、在全局样式中添加缩放函数与大量设计令牌替换,迁移并调整 40+ 组件样式与若干渲染代码,应用入口与 demo 集成初始化,并添加技能文档与白皮书微调。

Changes

NutUI React 等比适配系统

Layer / File(s) Summary
运行时缩放基础设施与初始化
src/utils/scale-f.ts, src/utils/index.ts, src/utils/index.taro.ts, packages/nutui-taro-demo/src/app.ts, src/sites/mobile/main.tsx
新增 scale-f 运行时实现,导出 initScaleFcalcByProfile,并在示例与移动入口调用初始化与卸载清理;在 utils barrel 中重导出。
构建时 SCSS 像素转换与脚本集成
scripts/px-to-scale-px-in-component-scss.cjs, scripts/build.mjs, scripts/build-taro.mjs, scripts/replace-css-var.js, scripts/generate-css-for-rtl-comparison.js
新增 PostCSS/SCSS 转换器以在内存中把组件 .scss 中裸 Npx 包装为 scale-px(Npx),并在构建/RTL/替换流程中预处理 SCSS,含 calc()/Sass 保护与跳过规则。
全局设计令牌与缩放函数
src/styles/variables.scss, src/styles/theme-default.scss, src/styles/theme-dark.scss, src/styles/variables-*.scss
:root 添加 --nut-scale-* 变量并声明 scale-px/scale-font-px/scale-icon-px,大规模将字体/行高/间距/图标/组件尺寸替换为缩放函数或语义令牌,并扩展主题行高语义映射。
组件样式迁移与渲染调整
src/packages/*/{*.scss,*.tsx,*.taro.tsx}, src/packages/swipe/demos/h5/*, src/packages/searchbar/demos/h5/demo6.tsx
跨 40+ 组件替换硬编码像素为设计令牌或缩放函数;移除图标组件显式 width/height/size,改用 className + SCSS 控制;调整 line-height/对齐/布局,以及示例中按钮高度填充改动等。
技能文档与白皮书微调
.cursor/skills/nutui-proportional-scaling/SKILL.md, NutUI-React_组件标准白皮书.md
新增比例缩放技能文档,记录运行时契约、构建管道、SCSS 编辑规范、集成清单与自检清单;对白皮书的两处占位/空白段落做微调。

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 分钟

Possibly related PRs

  • jdf2e/nutui-react#3316: build-taro 构建流程与 buildHarmonyCSS 相关改动,与本 PR 的构建时 SCSS 转换集成直接相关。
  • jdf2e/nutui-react#3220: 变更构建管道以处理组件 SCSS 的预处理步骤,可能与本次脚本集成内容冲突或互补。
  • jdf2e/nutui-react#2810: 早期对 src/styles/variables.scss 的修改,涉及相同令牌集,可能存在重叠或合并注意项。

Suggested reviewers

  • xiaoyatong
  • Alex-huxiyang

🐰 我是缩放兔子来报到,
根变量轻舞把屏宽照,
PostCSS 守护 calc 不跑,
百行令牌换新貌,
组件暖心随手调。

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning PR描述完全未填写。仅包含空的模板内容,所有复选框均未勾选,未提供变动类型、相关Issue、需求背景、解决方案或自查清单的任何信息。 需要填写PR描述,明确选择变动性质(新特性/功能增强等),链接相关Issue,说明需求背景与解决方案,并完成自查清单。根据提交信息与变动内容,应勾选"新特性提交"和"功能增强"。
Docstring Coverage ⚠️ Warning Docstring coverage is 72.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed 标题清晰准确地反映了这个拉取请求的核心变更——实现等比例的多尺寸适配系统。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/packages/avatarcropper/avatarcropper.taro.tsx (1)

141-153: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

修复 useLayoutEffect 中的闭包陷阱和时序风险。

  1. 闭包问题(确认):第 149 行使用 setCanvasAll({ ...canvasAll, cropperCanvas: canvas }) 中的 canvasAll,但它不在第 153 行的依赖数组 [showAlipayCanvas2D, state.displayHeight, state.displayWidth] 中,导致读取过期状态。改用函数式更新避免:setCanvasAll(prev => ({ ...prev, cropperCanvas: canvas }))

  2. 生命周期不一致:项目中其他需要 DOM 查询的组件(如 swipe.taro.tsxrange.taro.tsx)均采用 useReady + nextTick 模式,并有明确注释说明"需要参考小程序的事件周期"。avatarcropper 使用 useLayoutEffect 存在与小程序生命周期不匹配的风险,特别是支付宝小程序的 Canvas2D 初始化时序更为敏感。

建议改用 useReady + nextTick 的标准模式,或至少补充 nextTick 确保 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/avatarcropper/avatarcropper.taro.tsx` around lines 141 - 153,
The effect uses a stale closure over canvasAll and runs in useLayoutEffect which
can mismatch the mini-program lifecycle; change setCanvasAll({ ...canvasAll,
cropperCanvas: canvas }) to a functional updater setCanvasAll(prev => ({
...prev, cropperCanvas: canvas })) to avoid the closure bug, and replace (or
wrap) the useLayoutEffect block that reads the DOM (showAlipayCanvas2D /
createSelectorQuery / canvasId) with the mini-program pattern useReady +
nextTick (or call nextTick before querying) so the canvas node is queried only
after the platform DOM is reliably ready.
src/packages/lottie/lottiemp.taro.tsx (1)

26-75: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

useLayoutEffect 重跑时缺少清理,可能重复创建动画实例与事件监听。

当前初始化逻辑会因依赖变化反复执行,但旧实例只在 useUnload 时销毁,导致同一组件生命周期内可能出现实例/监听累积。

建议修复(在 effect 内增加 cleanup)
  useLayoutEffect(() => {
+    let disposed = false
     createSelectorQuery()
       .select(`#${id}`)
       .fields(
         {
           node: true,
           size: true,
         },
         (res) => {
+          if (disposed) return
           try {
             const canvas = res.node
             const context = canvas.getContext('2d')
@@
             lottie.setup(canvas)
             animation.current = lottie.loadAnimation({
@@
             inited.current = true
           } catch (error) {
             console.error(error)
           }
         }
       )
       .exec()
+
+    return () => {
+      disposed = true
+      if (onComplete && animation.current) {
+        animation.current.removeEventListener('complete', onComplete)
+      }
+      if (animation.current) {
+        animation.current.destroy()
+        animation.current = null
+      }
+      inited.current = false
+    }
   }, [autoPlay, dpr, id, loop, onComplete, source, speed, style])
🤖 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/lottie/lottiemp.taro.tsx` around lines 26 - 75, The effect using
useLayoutEffect (which calls lottie.loadAnimation and adds event listeners via
animation.current.addEventListener) lacks a cleanup so repeated runs leak
animation instances and listeners; update the effect to (1) before creating a
new animation check if animation.current exists and call its removeEventListener
(for the onComplete handler) and destroy method (or lottie.destroy on the
instance) and null it, (2) store the onComplete handler reference so you can
remove it reliably, and (3) return a cleanup function from useLayoutEffect that
removes the event listener and destroys the current animation and sets
inited.current/animation.current to false/null; target symbols: useLayoutEffect,
animation.current, inited.current, lottie.loadAnimation,
addEventListener/removeEventListener, and the onComplete handler.
🧹 Nitpick comments (7)
src/packages/searchbar/demos/h5/demo6.tsx (1)

18-20: ⚡ Quick win

简化状态切换逻辑

当前的三元表达式可以简化为更简洁的布尔取反形式。

♻️ 建议的简化方案
           <Popover
             visible={lightTheme}
             onClick={() => {
-              lightTheme ? setLightTheme(false) : setLightTheme(true)
+              setLightTheme(!lightTheme)
             }}
             list={itemList}
           >
🤖 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/searchbar/demos/h5/demo6.tsx` around lines 18 - 20, 在 onClick
的处理器中,当前用三元表达式切换状态 (lightTheme ? setLightTheme(false) :
setLightTheme(true)),请改为直接取反布尔值并传入 setLightTheme,例如在 onClick 回调中调用
setLightTheme(!lightTheme);定位到包含 lightTheme 和 setLightTheme 的 onClick
匿名函数并替换为布尔取反形式以简化逻辑。
src/packages/timeselect/timeselect.scss (1)

16-16: ⚡ Quick win

考虑移除或恢复注释掉的代码。

如果 width: $timeselect-date-width; 不再需要,建议完全删除该行而不是注释掉。如果这是临时测试(考虑到 PR 标题"仅对比使用"),请在最终合并前明确处理。保留注释的代码会增加代码库的维护负担。

🤖 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/timeselect/timeselect.scss` at line 16, 在
src/packages/timeselect/timeselect.scss 中处理被注释的样式行 `width:
$timeselect-date-width;`:如果该样式确实不再需要,直接删除这行;如果是临时注释用于对比/测试,则恢复该行并添加简短注释说明原因和何时可删除(或在
PR 合并前再确认);确保变量 `$timeselect-date-width` 在恢复时可用且样式不会引入布局回归。
src/sites/mobile/main.tsx (1)

32-32: ⚡ Quick win

建议为 initScaleF 增加清理钩子,避免重复注册副作用

Line [32] 当前直接调用 initScaleF('elderly')。建议保存返回的 disposer,并在 HMR dispose 阶段清理,避免开发态重复执行带来的监听叠加风险。

可参考修改
 if (rootElement != null) {
-  initScaleF('elderly')
+  const disposeScale = initScaleF('elderly')
+  if (import.meta.hot) {
+    import.meta.hot.dispose(() => {
+      disposeScale?.()
+    })
+  }
   const root = ReactDOM.createRoot(rootElement)
   root.render(<App />)
 }
🤖 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/sites/mobile/main.tsx` at line 32, 当前直接调用 initScaleF('elderly') 会在开发态 HMR
多次执行时重复注册副作用;修改为保存 initScaleF 的返回值(比如 const disposeScale = initScaleF('elderly')
或类似变量),并在 HMR 卸载阶段调用该 disposer(在 import.meta.hot?.dispose(() =>
disposeScale?.()) 内清理)以避免监听/副作用叠加;确保在非 HMR 环境也能安全忽略或调用该 disposer。
src/packages/tour/tour.scss (1)

32-33: ⚡ Quick win

建议 close 图标尺寸改为缩放函数,保持与适配体系一致

Line [32]-[33] 建议避免固定 10px,改为 scale-icon-px(10px),避免在大字版/等比适配下尺寸不一致。

可参考修改
       &-close {
-        width: 10px;
-        height: 10px;
+        width: scale-icon-px(10px);
+        height: scale-icon-px(10px);
       }
🤖 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 fixed 10px
sizing for the close icon in src/packages/tour/tour.scss by using the scaling
helper so it respects the adaptive system: change the width and height
properties currently set to 10px to use scale-icon-px(10px) (i.e., width:
scale-icon-px(10px); height: scale-icon-px(10px);) so the close icon sizing is
consistent with the app's scaling system.
src/utils/scale-f.ts (2)

226-242: 💤 Low value

options.scale 校验可以更直接。

Number.isFinite(options.scale) && Number(options.scale) > 0 ? Number(options.scale) : scale 这一段调用了 3 次 Number(options.scale),可读性不佳。options.scale 类型已经是 number | undefined,可改成:

简化建议
-  const currentScale =
-    Number.isFinite(options.scale) && Number(options.scale) > 0
-      ? Number(options.scale)
-      : scale
+  const overrideScale = options.scale
+  const currentScale =
+    typeof overrideScale === 'number' &&
+    Number.isFinite(overrideScale) &&
+    overrideScale > 0
+      ? overrideScale
+      : scale
🤖 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 226 - 242, The scale validation in
calcByProfile repeats Number(options.scale) three times; convert options.scale
to a local numeric variable once (e.g., let s = options.scale as number |
undefined; or const providedScale = options.scale) then coerce/validate that
single value (Number or Number.isFinite and > 0) and use it as currentScale,
falling back to the module-level scale; update calcByProfile to reference this
single-local variable instead of calling Number(options.scale) multiple times.

178-188: 💤 Low value

!scale 判断为冗余防御。

scale 在模块顶层初始化为 1,且 setScaleF 内部已通过 Number.isFinite(nextScale) && nextScale > 0 ? nextScale : 1 保证落库的值始终 > 0。因此 !scale 永远为 false,整个条件可以简化为 nextScale !== scale

🤖 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 178 - 188, The condition in refreshScaleF
contains a redundant defensive check "!scale" because scale is initialized to 1
and setScaleF already ensures stored values are > 0; remove the "!scale" part
and simplify the if to only compare nextScale !== scale so the body calls
setScaleF(nextScale) only when the fetched value differs; keep the existing
profile-switching logic (setScaleProfile(nextProfile)) and the function return
behavior unchanged.
scripts/px-to-scale-px-in-component-scss.cjs (1)

31-54: 💤 Low value

findInnermostCalcRange 命名与实际行为不符。

函数注释也写明了"最左侧的「体内不含 calc(」的 calc 块"。实际返回的是最左侧的叶子 calc(body 内不再含 calc(),并不是 "innermost"。在外层有嵌套 calc 时容易让阅读者误以为是按深度优先寻找最内层。建议改名以匹配语义,例如 findLeftmostLeafCalcRange

建议改名
-/** 最左侧的「体内不含 calc(」的 calc 块(同一层里先处理最左) */
-function findInnermostCalcRange(str) {
+/** 同一层中最左侧的叶子 calc 块(体内不再含 calc()。 */
+function findLeftmostLeafCalcRange(str) {
@@
-    const m = findInnermostCalcRange(v)
+    const m = findLeftmostLeafCalcRange(v)
🤖 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 31 - 54, The
function name findInnermostCalcRange is misleading because it actually finds the
leftmost leaf calc (a calc(...) whose body does not contain another calc), so
rename the function to findLeftmostLeafCalcRange and update its comment
accordingly; update every reference/usage of findInnermostCalcRange in this
module to the new name (e.g., callers that expect the "innermost" behavior), and
run/adjust any tests or examples that mention findInnermostCalcRange to reflect
the new identifier.
🤖 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/px-to-scale-px-in-component-scss.cjs`:
- Line 16: The script's PROP_SKIP constant currently lists font-size exceptions
but lacks documentation about how demo files are treated relative to the
SKILL.md constraint; update the top-of-file comment in the script (near
PROP_SKIP) to state the SKILL.md 3.3 rule for "scale-font-px" vs theme tokens,
clarify that the script only transforms component SCSS (not demo files) unless
repo policy changes, and explicitly note the expected exemptions (e.g.,
skeleton's 0px) and recommended next steps: either exclude demo directories from
processing in this script or add a CI lint rule to enforce scaling in demos
and/or update SKILL.md to declare demos exempt.

In `@src/packages/inputnumber/inputnumber.scss`:
- Around line 26-27: The .nut-icon rules were changed to hardcoded sizes (10px /
16px) which breaks the global CSS variable scaling; restore usage of the global
CSS variables by replacing the hardcoded width and height in the .nut-icon
selector(s) with var(--nut-icon-width) and var(--nut-icon-height) so the
component respects --nut-scale-icon and matches radio/checkbox behavior (update
both small and default/large .nut-icon occurrences to use the variables).

In `@src/packages/searchbar/demos/h5/demo6.tsx`:
- Around line 24-29: The inline styles in the demo (the style object with
fontSize and width in src/packages/searchbar/demos/h5/demo6.tsx) use hard-coded
'12px' and '50px' which bypass the project's scaling CSS variables; update the
style to remove fixed px values or replace them with calc() using the scale
variable (e.g., calc(12px * var(--nut-scale-font))) or reference the appropriate
CSS variables so fontSize and width respect --nut-scale-font and other sizing
tokens; apply the same change to the corresponding style block in
src/packages/searchbar/demos/taro/demo6.tsx.

In `@src/packages/shortpassword/shortpassword.scss`:
- Line 13: The change incorrectly assigns a pixel font-size variable
($font-size-l) to line-height, causing semantic and spacing issues; update the
rule that sets line-height to use the unitless/design token $line-height-base
(or another dedicated line-height variable) instead of $font-size-l so that the
selector using line-height gets a proper proportional value; locate the line
containing "line-height: $font-size-l;" in
src/packages/shortpassword/shortpassword.scss and replace it with use of
$line-height-base (or a numeric unitless value like 1.5) to fix the semantics.

In `@src/packages/swipe/swipe.scss`:
- Line 35: 在包含注释文本 `//left: 100%;` 的位置前插入一个空行以修复
scss/double-slash-comment-empty-line-before lint 违规;也就是在 swipe.scss
中找到该注释并在其上一行添加一个空行,提交后 lint 应通过。

In `@src/styles/variables.scss`:
- Line 7: Several SCSS stylelint errors stem from missing empty lines before
double-slash section comments and from extraneous blank lines before the first
dollar-variable in variable groups; fix by ensuring there is exactly one blank
line immediately before section comments like "// ---- icon size ----" and by
removing the empty line that appears directly above the first $ variable in each
group (addresses rules scss/double-slash-comment-empty-line-before and
scss/dollar-variable-empty-line-before for the occurrences around the mentioned
comment and the $ variable blocks at the reported locations).
- Line 1353: The SCSS token $swiper-indicator-bottom is being assigned
unconditionally which overrides external presets; update the declaration of
$swiper-indicator-bottom to append !default (i.e., change the assignment so it
becomes a defaultable variable) so it can be overridden by consumers and remain
consistent with other tokens in the file.
- Around line 7-17: 移除未被使用的 CSS 变量
--nut-icon-height、--nut-icon-width、--nut-icon-line-height(当前在 :root 中带
!important 的三条定义),因为仓库实际使用的是 --nutui-icon-*
系列;在文件中删除这三条冗余变量定义以统一命名空间并避免维护负担;如果确实想保留兼容性可改名为 --nutui-icon-* 并验证与现有
scale-icon-px() 的回退逻辑(位于原文件的第 555–557 行)不会被破坏。

In `@src/utils/scale-f.ts`:
- Around line 190-205: The resize handler in initScaleF can cause high-frequency
concurrent refreshScaleF() calls (which await getScaleByNative()) and also
allows duplicate listeners; make initScaleF idempotent by storing a module-level
disposer and calling it at start to remove any existing listener before
registering a new one, debounce/coalesce resize events using
requestAnimationFrame (or a short timer) inside the handler to avoid rapid
concurrent calls, and implement a monotonically incremented token/version in
refreshScaleF/getScaleByNative flow so each async response compares its token
before writing CSS variables (drop outdated responses); ensure the same handler
reference is used for addEventListener/removeEventListener so the disposer
reliably removes the listener.

---

Outside diff comments:
In `@src/packages/avatarcropper/avatarcropper.taro.tsx`:
- Around line 141-153: The effect uses a stale closure over canvasAll and runs
in useLayoutEffect which can mismatch the mini-program lifecycle; change
setCanvasAll({ ...canvasAll, cropperCanvas: canvas }) to a functional updater
setCanvasAll(prev => ({ ...prev, cropperCanvas: canvas })) to avoid the closure
bug, and replace (or wrap) the useLayoutEffect block that reads the DOM
(showAlipayCanvas2D / createSelectorQuery / canvasId) with the mini-program
pattern useReady + nextTick (or call nextTick before querying) so the canvas
node is queried only after the platform DOM is reliably ready.

In `@src/packages/lottie/lottiemp.taro.tsx`:
- Around line 26-75: The effect using useLayoutEffect (which calls
lottie.loadAnimation and adds event listeners via
animation.current.addEventListener) lacks a cleanup so repeated runs leak
animation instances and listeners; update the effect to (1) before creating a
new animation check if animation.current exists and call its removeEventListener
(for the onComplete handler) and destroy method (or lottie.destroy on the
instance) and null it, (2) store the onComplete handler reference so you can
remove it reliably, and (3) return a cleanup function from useLayoutEffect that
removes the event listener and destroys the current animation and sets
inited.current/animation.current to false/null; target symbols: useLayoutEffect,
animation.current, inited.current, lottie.loadAnimation,
addEventListener/removeEventListener, and the onComplete handler.

---

Nitpick comments:
In `@scripts/px-to-scale-px-in-component-scss.cjs`:
- Around line 31-54: The function name findInnermostCalcRange is misleading
because it actually finds the leftmost leaf calc (a calc(...) whose body does
not contain another calc), so rename the function to findLeftmostLeafCalcRange
and update its comment accordingly; update every reference/usage of
findInnermostCalcRange in this module to the new name (e.g., callers that expect
the "innermost" behavior), and run/adjust any tests or examples that mention
findInnermostCalcRange to reflect the new identifier.

In `@src/packages/searchbar/demos/h5/demo6.tsx`:
- Around line 18-20: 在 onClick 的处理器中,当前用三元表达式切换状态 (lightTheme ?
setLightTheme(false) : setLightTheme(true)),请改为直接取反布尔值并传入 setLightTheme,例如在
onClick 回调中调用 setLightTheme(!lightTheme);定位到包含 lightTheme 和 setLightTheme 的
onClick 匿名函数并替换为布尔取反形式以简化逻辑。

In `@src/packages/timeselect/timeselect.scss`:
- Line 16: 在 src/packages/timeselect/timeselect.scss 中处理被注释的样式行 `width:
$timeselect-date-width;`:如果该样式确实不再需要,直接删除这行;如果是临时注释用于对比/测试,则恢复该行并添加简短注释说明原因和何时可删除(或在
PR 合并前再确认);确保变量 `$timeselect-date-width` 在恢复时可用且样式不会引入布局回归。

In `@src/packages/tour/tour.scss`:
- Around line 32-33: Replace the fixed 10px sizing for the close icon in
src/packages/tour/tour.scss by using the scaling helper so it respects the
adaptive system: change the width and height properties currently set to 10px to
use scale-icon-px(10px) (i.e., width: scale-icon-px(10px); height:
scale-icon-px(10px);) so the close icon sizing is consistent with the app's
scaling system.

In `@src/sites/mobile/main.tsx`:
- Line 32: 当前直接调用 initScaleF('elderly') 会在开发态 HMR 多次执行时重复注册副作用;修改为保存 initScaleF
的返回值(比如 const disposeScale = initScaleF('elderly') 或类似变量),并在 HMR 卸载阶段调用该
disposer(在 import.meta.hot?.dispose(() => disposeScale?.()) 内清理)以避免监听/副作用叠加;确保在非
HMR 环境也能安全忽略或调用该 disposer。

In `@src/utils/scale-f.ts`:
- Around line 226-242: The scale validation in calcByProfile repeats
Number(options.scale) three times; convert options.scale to a local numeric
variable once (e.g., let s = options.scale as number | undefined; or const
providedScale = options.scale) then coerce/validate that single value (Number or
Number.isFinite and > 0) and use it as currentScale, falling back to the
module-level scale; update calcByProfile to reference this single-local variable
instead of calling Number(options.scale) multiple times.
- Around line 178-188: The condition in refreshScaleF contains a redundant
defensive check "!scale" because scale is initialized to 1 and setScaleF already
ensures stored values are > 0; remove the "!scale" part and simplify the if to
only compare nextScale !== scale so the body calls setScaleF(nextScale) only
when the fetched value differs; keep the existing profile-switching logic
(setScaleProfile(nextProfile)) and the function return behavior unchanged.
🪄 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: 88d64b75-b933-4292-a7e0-05dcc2fd8fbc

📥 Commits

Reviewing files that changed from the base of the PR and between 11be1b3 and 4d19218.

📒 Files selected for processing (74)
  • .cursor/skills/nutui-proportional-scaling/SKILL.md
  • NutUI-React_组件标准白皮书.md
  • packages/nutui-taro-demo/src/app.ts
  • scripts/build-taro.mjs
  • scripts/build.mjs
  • scripts/generate-css-for-rtl-comparison.js
  • scripts/px-to-scale-px-in-component-scss.cjs
  • scripts/replace-css-var.js
  • src/packages/address/address.scss
  • src/packages/audio/audio.scss
  • src/packages/avatarcropper/avatarcropper.taro.tsx
  • src/packages/button/button.taro.tsx
  • src/packages/calendar/calendar.scss
  • src/packages/calendarcard/calendarcard.scss
  • src/packages/card/card.scss
  • src/packages/checkbox/checkbox.scss
  • src/packages/fixednav/fixednav.scss
  • src/packages/hoverbuttonitem/hoverbuttonitem.scss
  • src/packages/input/input.scss
  • src/packages/inputnumber/inputnumber.scss
  • src/packages/lottie/lottiemp.taro.tsx
  • src/packages/menu/menu.scss
  • src/packages/menu/menu.taro.tsx
  • src/packages/menu/menu.tsx
  • src/packages/menuitem/menuitem.scss
  • src/packages/navbar/navbar.scss
  • src/packages/numberkeyboard/numberkeyboard.scss
  • src/packages/numberkeyboard/numberkeyboard.taro.tsx
  • src/packages/numberkeyboard/numberkeyboard.tsx
  • src/packages/overlay/overlay.tsx
  • src/packages/popover/popover.scss
  • src/packages/popover/popover.tsx
  • src/packages/popup/popup.scss
  • src/packages/price/price.scss
  • src/packages/pulltorefresh/pulltorefresh.scss
  • src/packages/quickenter/quickenter.scss
  • src/packages/range/range.scss
  • src/packages/rate/rate.scss
  • src/packages/rate/rate.taro.tsx
  • src/packages/searchbar/demos/h5/demo6.tsx
  • src/packages/searchbar/searchbar.scss
  • src/packages/segmented/segmented.scss
  • src/packages/shortpassword/shortpassword.scss
  • src/packages/space/space.scss
  • src/packages/step/step.scss
  • src/packages/steps/steps.scss
  • src/packages/swipe/demos/h5/demo1.tsx
  • src/packages/swipe/demos/h5/demo3.tsx
  • src/packages/swipe/demos/h5/demo4.tsx
  • src/packages/swipe/demos/h5/demo5.tsx
  • src/packages/swipe/demos/h5/demo6.tsx
  • src/packages/swipe/demos/h5/demo7.tsx
  • src/packages/swipe/demos/h5/demo8.tsx
  • src/packages/swipe/demos/h5/demo9.tsx
  • src/packages/swipe/swipe.scss
  • src/packages/switch/switch.scss
  • src/packages/tabbar/tabbar.scss
  • src/packages/tabbaritem/tabbaritem.scss
  • src/packages/tabs/tabs.scss
  • src/packages/tag/tag.scss
  • src/packages/tag/tag.taro.tsx
  • src/packages/tag/tag.tsx
  • src/packages/timeselect/timeselect.scss
  • src/packages/tour/tour.scss
  • src/packages/uploader/uploader.scss
  • src/packages/virtuallist/virtuallist.scss
  • src/sites/assets/styles/highlight.scss
  • src/sites/mobile/main.tsx
  • src/styles/theme-dark.scss
  • src/styles/theme-default.scss
  • src/styles/variables.scss
  • src/utils/index.taro.ts
  • src/utils/index.ts
  • src/utils/scale-f.ts
💤 Files with no reviewable changes (3)
  • src/packages/overlay/overlay.tsx
  • src/packages/step/step.scss
  • NutUI-React_组件标准白皮书.md

Comment thread scripts/px-to-scale-px-in-component-scss.cjs
Comment on lines +26 to +27
width: 10px;
height: 10px;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 搜索 CSS 自定义属性的定义和使用
rg -n '\-\-nut-icon-(width|height)' --type=scss --type=css -C3

# 搜索可能依赖这些变量的组件
rg -n 'var\(\s*--nut-icon-(width|height)' -C2

Repository: jdf2e/nutui-react

Length of output: 90


🏁 Script executed:

#!/bin/bash
# Search for CSS custom properties without type restriction
rg '\-\-nut-icon-(width|height)' -C 3

# Also search for the SCSS file to understand its context
echo "=== Content of inputnumber.scss around lines 26-27 ==="
head -80 src/packages/inputnumber/inputnumber.scss | tail -60

# Search for any CSS variable definitions
echo "=== Searching for CSS variable definitions ==="
rg 'var\s*\(\s*--nut-icon' -C 2

Repository: jdf2e/nutui-react

Length of output: 8070


.nut-icon 改为硬编码尺寸值会破坏 CSS 自定义属性机制。

src/styles/variables.scss 中,--nut-icon-width--nut-icon-height 被定义为全局 CSS 变量,支持通过 --nut-scale-icon 进行动态缩放。此改动将这些值硬编码为 10px(第26-27行)和 16px(第69-75行),使得用户无法通过 CSS 变量统一控制该组件的图标尺寸,与 radio、checkbox 等其他组件的行为不一致。应改用 CSS 变量 var(--nut-icon-width)var(--nut-icon-height) 保持一致性。

🤖 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/inputnumber/inputnumber.scss` around lines 26 - 27, The
.nut-icon rules were changed to hardcoded sizes (10px / 16px) which breaks the
global CSS variable scaling; restore usage of the global CSS variables by
replacing the hardcoded width and height in the .nut-icon selector(s) with
var(--nut-icon-width) and var(--nut-icon-height) so the component respects
--nut-scale-icon and matches radio/checkbox behavior (update both small and
default/large .nut-icon occurrences to use the variables).

Comment on lines +24 to +29
style={{
fontSize: '12px',
width: '50px',
display: 'flex',
alignItems: 'center',
}}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 描述: 查找项目中关于尺寸适配、单位转换的相关实现

# 搜索可能的适配工具函数或配置
rg -n -C3 --type=ts --type=tsx '(px2|toPx|adaptSize|scaleSize|convertUnit)' -g '!node_modules' -g '!dist'

# 搜索 SCSS 转换相关配置
fd -e js -e ts -e json 'postcss|babel|webpack' --exec grep -l 'px' {} \;

# 查找其他 demo 文件的样式写法
rg -n --type=tsx 'fontSize.*style' src/packages/searchbar/demos/

Repository: jdf2e/nutui-react

Length of output: 117


🏁 Script executed:

#!/bin/bash
# Fix the initial search - use correct rg syntax and glob patterns

# Search for adaptation/sizing utilities
rg -n '(px2|toPx|adaptSize|scaleSize|convertUnit|adapt)' -g '*.ts' -g '*.tsx' -g '!node_modules' -g '!dist'

# Look at the specific file
echo "=== File content ==="
cat -n src/packages/searchbar/demos/h5/demo6.tsx | head -50

# Find other demo files to compare styling approaches
echo -e "\n=== Other demo files ==="
fd . src/packages/searchbar/demos/ -type f -name '*.tsx' | head -10

Repository: jdf2e/nutui-react

Length of output: 1590


🏁 Script executed:

#!/bin/bash
# Search for sizing/adaptation related code and SCSS utilities
rg -n 'fontSize|width.*px|adapt|scale' --glob='*.scss' --glob='*.css' src/packages/ | grep -i 'adapt\|scale\|font' | head -20

# Look for postcss/babel/webpack configuration that might transform px values
fd -type f \( -name 'postcss.config.*' -o -name '.babelrc*' -o -name 'webpack.config.*' \) | head -5

Repository: jdf2e/nutui-react

Length of output: 1809


🏁 Script executed:

#!/bin/bash
# Search for any adaptation system or utilities in the codebase
rg -n 'export.*function|export.*const' src/ --glob='*.ts' --glob='*.tsx' | grep -i 'adapt\|size\|scale\|px' | head -15

# Check if there are any HOCs or hooks for sizing
rg -n 'useSize|useAdapt|withSize|withAdapt' -g '*.ts' -g '*.tsx' | head -10

Repository: jdf2e/nutui-react

Length of output: 383


🏁 Script executed:

#!/bin/bash
# Look at the px-transform and scale-f utilities to understand how to use them
echo "=== px-transform.ts ==="
cat -n src/utils/taro/px-transform.ts

echo -e "\n=== scale-f.ts (key functions) ==="
sed -n '1,50p' src/utils/scale-f.ts
cat -n src/utils/scale-f.ts | sed -n '191,230p'

echo -e "\n=== px-check.ts ==="
cat -n src/utils/px-check.ts

Repository: jdf2e/nutui-react

Length of output: 3045


🏁 Script executed:

#!/bin/bash
# Search for how inline styles are used in other demo files
echo "=== Inline styles in demo files ==="
rg -n "style=\{\{" src/packages/searchbar/demos/ -A 5 | head -40

# Check if scale-f is imported anywhere in demos
echo -e "\n=== Import of scale utilities in demos ==="
rg -n "scale-f|pxTransform|scale-font|scale-icon" src/packages/searchbar/demos/

# Check how other components handle styling in their demos
echo -e "\n=== Other component demos with inline styles ==="
rg -n "style=\{\{" src/packages/*/demos/ -A 3 | grep -E "(fontSize|width).*px" | head -10

Repository: jdf2e/nutui-react

Length of output: 4205


🏁 Script executed:

#!/bin/bash
# Look at the components to see how they use these utilities
echo "=== Searchbar component implementation ==="
cat -n src/packages/searchbar/searchbar.tsx | head -100

# Check if there are any constants or configs for sizing
rg -n "export.*const.*=.*\{" src/packages/searchbar/ -A 10 | grep -i "size\|font\|width" | head -20

Repository: jdf2e/nutui-react

Length of output: 2967


🏁 Script executed:

#!/bin/bash
# Check if there are examples of using CSS variables in inline styles
echo "=== CSS variables usage in styles ==="
rg -n "var(--nut-scale" src/packages/ -A 2 -B 2 | head -30

# Check the CSS variable names in style-related files
rg -n "\-\-nut-scale" src/ --type=css --type=scss | head -20

# Look for any H5 utilities that might provide scaling
rg -n "export.*function|export.*const" src/utils/ --type=ts | grep -i "scale\|px" | head -15

Repository: jdf2e/nutui-react

Length of output: 538


🏁 Script executed:

#!/bin/bash
# Check CSS variables usage in inline styles - simpler search
echo "=== CSS variable usage examples ==="
rg -n "var\(--nut" src/packages/ -A 2 -B 2 | head -40

# Check scale-f.ts to see what CSS variable names are set
echo -e "\n=== CSS variables in scale-f.ts ==="
rg -n "setProperty\|--nut-scale" src/utils/scale-f.ts -A 2 -B 2

# Check if demos use any CSS class-based styling
echo -e "\n=== CSS classes in searchbar demos ==="
rg -n "className\|style" src/packages/searchbar/demos/h5/ -B 1 -A 1 | head -50

Repository: jdf2e/nutui-react

Length of output: 2516


🏁 Script executed:

#!/bin/bash
# Look at scale-f.ts more completely to understand how CSS variables are set
echo "=== Full scale-f.ts file (check for setProperty calls) ==="
cat -n src/utils/scale-f.ts | grep -E "setProperty|style\." -A 2 -B 2

# Check what the actual CSS variable names are
rg -n "nut-scale-f\|nut-scale-font\|nut-scale-icon" src/utils/ -A 1 -B 1

Repository: jdf2e/nutui-react

Length of output: 554


🏁 Script executed:

#!/bin/bash
# Check if there are any other examples in the codebase of using calcByProfile or scale-f in components
echo "=== Usage of calcByProfile in components ==="
rg -n "calcByProfile\|initScaleF" src/packages/ -A 3 -B 3 | head -40

# Check if demo files import or use scale utilities
echo -e "\n=== Scale utilities imports in demos ==="
rg -n "import.*scale\|import.*calcByProfile" src/packages/*/demos/

# Check how the CSS variables should be used in inline styles
echo -e "\n=== Check if inline styles can use CSS calc with scale variables ==="
rg -n "calc\(" src/packages/ --type=tsx -B 1 -A 1 | head -20

Repository: jdf2e/nutui-react

Length of output: 264


🏁 Script executed:

#!/bin/bash
# Look at the scale-f.ts file more completely to understand how it works with H5
echo "=== Check full scale-f.ts context ==="
head -100 src/utils/scale-f.ts

# Check if there's documentation on how to use the scaling system
echo -e "\n=== Check package.json or README ==="
head -50 README.md 2>/dev/null || echo "No README found"

# Look at how Taro demos handle scaling vs H5 demos
echo -e "\n=== Compare demo7 across platforms ==="
echo "=== H5 demo7 ==="
cat -n src/packages/searchbar/demos/h5/demo7.tsx | head -20
echo -e "\n=== Taro demo7 ==="
cat -n src/packages/searchbar/demos/taro/demo7.tsx | head -20

Repository: jdf2e/nutui-react

Length of output: 6400


将 demo 中的硬编码像素值改为支持多尺寸适配

此 demo 中的 fontSize: '12px'width: '50px' 硬编码值会绕过项目的 CSS 变量自适应系统(--nut-scale-font 等),无法在老年版/大字版等模式下正确缩放。

建议移除这些固定尺寸限制,或改用 calc() 结合 CSS 变量实现适配(如 calc(12px * var(--nut-scale-font)))。同样问题也存在于 src/packages/searchbar/demos/taro/demo6.tsx

🤖 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/searchbar/demos/h5/demo6.tsx` around lines 24 - 29, The inline
styles in the demo (the style object with fontSize and width in
src/packages/searchbar/demos/h5/demo6.tsx) use hard-coded '12px' and '50px'
which bypass the project's scaling CSS variables; update the style to remove
fixed px values or replace them with calc() using the scale variable (e.g.,
calc(12px * var(--nut-scale-font))) or reference the appropriate CSS variables
so fontSize and width respect --nut-scale-font and other sizing tokens; apply
the same change to the corresponding style block in
src/packages/searchbar/demos/taro/demo6.tsx.

Comment thread src/packages/shortpassword/shortpassword.scss Outdated

&-right {
display: flex;
//left: 100%;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

修复注释前缺少空行的 lint 违规

Line 35 的 //left: 100%; 前需要空行,否则会触发 scss/double-slash-comment-empty-line-before,可能导致 lint 失败。

建议修改
   &-right {
     display: flex;
+
     //left: 100%;
     height: 100%;
     right: 0px;
📝 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.

Suggested change
//left: 100%;
&-right {
display: flex;
//left: 100%;
height: 100%;
right: 0px;
🧰 Tools
🪛 Stylelint (17.11.0)

[error] 35-35: 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/packages/swipe/swipe.scss` at line 35, 在包含注释文本 `//left: 100%;`
的位置前插入一个空行以修复 scss/double-slash-comment-empty-line-before lint 违规;也就是在
swipe.scss 中找到该注释并在其上一行添加一个空行,提交后 lint 应通过。

Comment thread src/styles/variables.scss
Comment thread src/styles/variables.scss
Comment on lines +7 to +17
// ---- icon size ----
--nut-icon-height: calc(
16px * var(--nut-scale-icon, var(--nut-scale-f, 1))
) !important;
--nut-icon-width: calc(
16px * var(--nut-scale-icon, var(--nut-scale-f, 1))
) !important;
--nut-icon-line-height: calc(
16px * var(--nut-scale-icon, var(--nut-scale-f, 1))
) !important;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 验证 --nut-icon-* (without "ui") 与 --nutui-icon-* 在仓库内的实际消费者
echo "=== consumers of --nut-icon-height/width/line-height (no 'ui') ==="
rg -nP '\bvar\(\s*--nut-icon-(height|width|line-height)\b' -g '!**/dist/**'
echo
echo "=== consumers of --nutui-icon-height/width/line-height (with 'ui') ==="
rg -nP '\bvar\(\s*--nutui-icon-(height|width|line-height)\b' -g '!**/dist/**'

Repository: jdf2e/nutui-react

Length of output: 1351


:root--nut-icon-* 变量的定义是死代码,需要清理。

这段定义的 --nut-icon-height--nut-icon-width--nut-icon-line-height 在整个仓库内无任何消费者(检索结果为空)。而真正被使用的是下方第 555-557 行定义的 --nutui-icon-*--nutui- 前缀)及其他主题变量文件中的对应定义。

两套变量完全分离:

  • Lines 8-16 定义的 --nut-icon-* 及其 !important 从未被任何代码引用
  • Lines 555-557 等定义的 --nutui-icon-* 才是实际的 token 消费链

处理方案:

  1. 删除 Lines 8-16——这三个变量是冗余的,保留只会增加维护负担。
  2. 改名为 --nutui-icon-* 以统一命名空间,但需检查这样做是否会影响现有的 fallback 逻辑(Lines 555-557 的 fallback 是 scale-icon-px(20px),不会被 CSS 变量覆盖)。

建议直接删除 Lines 8-16,保持命名空间统一,由 SCSS 的 scale-icon-px() 函数负责生成可缩放的图标尺寸。

🧰 Tools
🪛 Stylelint (17.11.0)

[error] 7-7: 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/variables.scss` around lines 7 - 17, 移除未被使用的 CSS 变量
--nut-icon-height、--nut-icon-width、--nut-icon-line-height(当前在 :root 中带
!important 的三条定义),因为仓库实际使用的是 --nutui-icon-*
系列;在文件中删除这三条冗余变量定义以统一命名空间并避免维护负担;如果确实想保留兼容性可改名为 --nutui-icon-* 并验证与现有
scale-icon-px() 的回退逻辑(位于原文件的第 555–557 行)不会被破坏。

Comment thread src/styles/variables.scss

//swiper(✅)
$swiper-indicator-bottom: var(--nutui-swiper-indicator-bottom, 12px);
$swiper-indicator-bottom: var(--nutui-swiper-indicator-bottom, scale-px(12px));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

$swiper-indicator-bottom 缺少 !default

本文件中其余 token 几乎都带 !default,允许在引入前由使用方覆盖。此处的赋值会无条件覆盖外部预设值,破坏 token 链路。建议补齐:

建议补充 !default
-$swiper-indicator-bottom: var(--nutui-swiper-indicator-bottom, scale-px(12px));
+$swiper-indicator-bottom: var(
+  --nutui-swiper-indicator-bottom,
+  scale-px(12px)
+) !default;
📝 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.

Suggested change
$swiper-indicator-bottom: var(--nutui-swiper-indicator-bottom, scale-px(12px));
$swiper-indicator-bottom: var(
--nutui-swiper-indicator-bottom,
scale-px(12px)
) !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` at line 1353, The SCSS token
$swiper-indicator-bottom is being assigned unconditionally which overrides
external presets; update the declaration of $swiper-indicator-bottom to append
!default (i.e., change the assignment so it becomes a defaultable variable) so
it can be overridden by consumers and remain consistent with other tokens in the
file.

Comment thread src/utils/scale-f.ts
Comment on lines +190 to +205
/** 首次计算缩放并订阅 resize;返回卸载函数(SSR 下为空函数) */
export function initScaleF(nextProfile?: ScaleProfile) {
if (!canUseDom) return () => {}
setScaleProfile(nextProfile)

const handler = () => {
refreshScaleF()
}

handler()
window.addEventListener('resize', handler)

return () => {
window.removeEventListener('resize', handler)
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

resize 处理存在竞态与重复注册风险。

当前实现有两个问题:

  1. 没有节流/防抖:浏览器或软键盘弹起时 resize 会在很短时间内高频触发,每次都会触发一个 refreshScaleF()(其内部 await getScaleByNative() 通过原生桥),多个异步请求并发返回时,完成顺序无法保证——较早发起的请求可能在较晚发起的之后才 resolve,最终把"旧 scale" 覆盖回 :root,导致页面尺寸闪烁或回到错误值。
  2. initScaleF 没有幂等保护:被重复调用(HMR、Taro 页面多次 mount、demo 切换路由再回来等)时会反复 addEventListener('resize', handler),监听器会堆积,dispose 函数只能解掉最后一次返回的 handler。

建议:

  • requestAnimationFrame 合并多次 resize 或加一个简单防抖;
  • 用一个递增 token 标记每次刷新,回写 CSS 变量前比对 token,过期请求直接丢弃;
  • initScaleF 中维护一个 module-level disposer,重复调用时先调用旧 disposer 再重新订阅。
参考实现
-let scale = 1
+let scale = 1
+let activeDisposer: (() => void) | null = null
+let refreshToken = 0

@@
-/** 重新拉取缩放;可选同时切换 profile,避免与当前值相同时重复写 DOM */
-async function refreshScaleF(nextProfile?: ScaleProfile) {
-  if (nextProfile) {
-    setScaleProfile(nextProfile)
-  }
-  const nextScale = await getScaleF()
-  if (!scale || nextScale !== scale) {
-    setScaleF(nextScale)
-  }
-  return scale
-}
+async function refreshScaleF(nextProfile?: ScaleProfile) {
+  if (nextProfile) {
+    setScaleProfile(nextProfile)
+  }
+  const token = ++refreshToken
+  const nextScale = await getScaleF()
+  if (token !== refreshToken) return scale // 过期请求丢弃
+  if (nextScale !== scale) setScaleF(nextScale)
+  return scale
+}
@@
 export function initScaleF(nextProfile?: ScaleProfile) {
   if (!canUseDom) return () => {}
+  if (activeDisposer) activeDisposer()
   setScaleProfile(nextProfile)

-  const handler = () => {
-    refreshScaleF()
-  }
+  let rafId = 0
+  const handler = () => {
+    if (rafId) cancelAnimationFrame(rafId)
+    rafId = requestAnimationFrame(() => {
+      rafId = 0
+      refreshScaleF()
+    })
+  }

   handler()
   window.addEventListener('resize', handler)

-  return () => {
-    window.removeEventListener('resize', handler)
-  }
+  activeDisposer = () => {
+    if (rafId) cancelAnimationFrame(rafId)
+    window.removeEventListener('resize', handler)
+    activeDisposer = null
+  }
+  return activeDisposer
 }
🤖 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 190 - 205, The resize handler in
initScaleF can cause high-frequency concurrent refreshScaleF() calls (which
await getScaleByNative()) and also allows duplicate listeners; make initScaleF
idempotent by storing a module-level disposer and calling it at start to remove
any existing listener before registering a new one, debounce/coalesce resize
events using requestAnimationFrame (or a short timer) inside the handler to
avoid rapid concurrent calls, and implement a monotonically incremented
token/version in refreshScaleF/getScaleByNative flow so each async response
compares its token before writing CSS variables (drop outdated responses);
ensure the same handler reference is used for
addEventListener/removeEventListener so the disposer reliably removes the
listener.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 @.cursor/skills/nutui-proportional-scaling/SKILL.md:
- Line 56: The Markdown contains an escaped bold marker (\*\*) causing literal
asterisks to render; update the sentence that mentions scripts
(scripts/replace-css-var.js, scripts/build.mjs, scripts/build-taro.mjs,
scripts/px-to-scale-px-in-component-scss.cjs) and change the fragment
"不写回\*\*仓库里的组件 SCSS" to use a proper bold marker (e.g., "不写回**仓库里的组件 SCSS**" or
remove the asterisks entirely) so the bold formatting closes correctly and no
backslashes remain.
🪄 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: 9ea9008b-10c9-4686-8d09-34f3e9c6fa83

📥 Commits

Reviewing files that changed from the base of the PR and between 4d19218 and f3e2b10.

📒 Files selected for processing (6)
  • .cursor/skills/nutui-proportional-scaling/SKILL.md
  • src/packages/avatarcropper/avatarcropper.taro.tsx
  • src/packages/checkbox/checkbox.scss
  • src/packages/fixednav/fixednav.scss
  • src/packages/lottie/lottiemp.taro.tsx
  • src/packages/popover/popover.taro.tsx
✅ Files skipped from review due to trivial changes (1)
  • src/packages/avatarcropper/avatarcropper.taro.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/packages/checkbox/checkbox.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。
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

修复 Markdown 格式问题。

此行存在 Markdown 转义错误,不写回\*\*仓库里的组件 中的 \*\* 会显示为字面星号而非加粗结束标记,导致渲染异常。

📝 建议的修复
-在**内存**里把声明值中的裸 **`Npx`** 转为 **`scale-px(Npx)`**(规则见 §3),**不写回\*\*仓库里的组件 SCSS。
+在**内存**里把声明值中的裸 **`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.

Suggested change
-`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。
🤖 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, The Markdown
contains an escaped bold marker (\*\*) causing literal asterisks to render;
update the sentence that mentions scripts (scripts/replace-css-var.js,
scripts/build.mjs, scripts/build-taro.mjs,
scripts/px-to-scale-px-in-component-scss.cjs) and change the fragment
"不写回\*\*仓库里的组件 SCSS" to use a proper bold marker (e.g., "不写回**仓库里的组件 SCSS**" or
remove the asterisks entirely) so the bold formatting closes correctly and no
backslashes remain.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/styles/variables.scss (1)

2857-2864: ⚡ Quick win

TrendArrow token 被重复定义,建议去重。

Line 2857-2864 与 Line 2907-2914 的 $trendarrow-font-size$trendarrow-icon-margin 完全重复,后定义会静默覆盖前定义,后续维护容易漂移。建议仅保留一处。

建议修改
-// 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;

Also applies to: 2907-2914

🤖 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 2857 - 2864, The two SCSS tokens
$trendarrow-font-size and $trendarrow-icon-margin are defined twice (the blocks
at lines reported) causing silent overrides; remove the duplicate block so only
a single canonical definition remains (keep the desired instance with the
var(...) fallback and !default), verify the remaining definition uses the same
values (var(--nutui-trendarrow-font-size, $font-size-base) and
var(--nutui-trendarrow-icon-margin, scale-px(4px))) and ensure no other
duplicates exist so maintenance won’t silently override these tokens.
🤖 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`:
- Line 30: 在 src/packages/card/card.scss 中,声明 "line-height: $line-height-xl;"
前缺少按 stylelint
规则要求的空行(declaration-empty-line-before),请在该声明前插入一个空行以满足样式检查;确保仅对该声明添加空行而不改变其他缩进或语义。

In `@src/styles/theme-dark.scss`:
- Line 261: The SCSS file has single-line comments like "// 标准内容、名称类关键信息" that
violate the scss/double-slash-comment-empty-line-before rule; add a blank line
immediately before each offending double-slash comment (the occurrences
containing the text "标准内容、名称类关键信息" and the other comments at the same pattern on
the listed lines) so each // comment is preceded by an empty line to satisfy
stylelint.

In `@src/styles/theme-default.scss`:
- Line 260: The SCSS file contains single-line comments like "// 标准内容、名称类关键信息"
that are triggering the stylelint rule
scss/double-slash-comment-empty-line-before on several lines; fix by inserting
the required empty line(s) before each double-slash comment (e.g., the comment
text "// 标准内容、名称类关键信息") so the comment is preceded by a blank line as expected
by the linter across the affected occurrences.

In `@src/styles/variables.scss`:
- Around line 309-312: Fix the stylelint violations for
scss/dollar-variable-empty-line-before and
scss/double-slash-comment-empty-line-before by making spacing consistent around
SCSS variable declarations and single-line comments in variables.scss;
specifically adjust the blank line before the $button-xlarge-height declaration
and any other nearby $-variables or // comments so they either have the required
empty line or none (matching your project rule), and re-run stylelint to verify
and fix the remaining occurrences reported (e.g., around $button-xlarge-height
and other $variable and // comment blocks referenced in the review).

---

Nitpick comments:
In `@src/styles/variables.scss`:
- Around line 2857-2864: The two SCSS tokens $trendarrow-font-size and
$trendarrow-icon-margin are defined twice (the blocks at lines reported) causing
silent overrides; remove the duplicate block so only a single canonical
definition remains (keep the desired instance with the var(...) fallback and
!default), verify the remaining definition uses the same values
(var(--nutui-trendarrow-font-size, $font-size-base) and
var(--nutui-trendarrow-icon-margin, scale-px(4px))) and ensure no other
duplicates exist so maintenance won’t silently override these tokens.
🪄 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: 98e5583f-f4a3-4f83-84c8-fb52864a7c6e

📥 Commits

Reviewing files that changed from the base of the PR and between f3e2b10 and 0dcd2b4.

📒 Files selected for processing (18)
  • src/packages/calendarcard/calendarcard.scss
  • src/packages/card/card.scss
  • src/packages/checkbox/checkbox.scss
  • src/packages/hoverbuttonitem/hoverbuttonitem.scss
  • src/packages/menu/menu.scss
  • src/packages/navbar/navbar.scss
  • src/packages/numberkeyboard/numberkeyboard.scss
  • src/packages/price/price.scss
  • src/packages/quickenter/quickenter.scss
  • src/packages/rate/rate.scss
  • src/packages/searchbar/searchbar.scss
  • src/packages/steps/steps.scss
  • src/packages/tabs/tabs.scss
  • src/packages/tag/tag.scss
  • src/packages/virtuallist/virtuallist.scss
  • src/styles/theme-dark.scss
  • src/styles/theme-default.scss
  • src/styles/variables.scss
✅ Files skipped from review due to trivial changes (8)
  • src/packages/virtuallist/virtuallist.scss
  • src/packages/tabs/tabs.scss
  • src/packages/menu/menu.scss
  • src/packages/hoverbuttonitem/hoverbuttonitem.scss
  • src/packages/tag/tag.scss
  • src/packages/navbar/navbar.scss
  • src/packages/quickenter/quickenter.scss
  • src/packages/steps/steps.scss
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/packages/searchbar/searchbar.scss
  • src/packages/checkbox/checkbox.scss
  • src/packages/numberkeyboard/numberkeyboard.scss
  • src/packages/calendarcard/calendarcard.scss
  • src/packages/price/price.scss

Comment thread src/packages/card/card.scss Outdated
@include moreline-ellipsis();
line-height: 1.5;
font-size: 14px;
line-height: $line-height-xl;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Line 30 存在声明前空行的 stylelint 违规。

请在该声明前按规则补空行(declaration-empty-line-before),避免样式检查失败。

🧰 Tools
🪛 Stylelint (17.11.0)

[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` at line 30, 在 src/packages/card/card.scss 中,声明
"line-height: $line-height-xl;" 前缺少按 stylelint
规则要求的空行(declaration-empty-line-before),请在该声明前插入一个空行以满足样式检查;确保仅对该声明添加空行而不改变其他缩进或语义。

// 汉字:次要内容、辅助类信息 数字:羊角符号、小数点及角分
--nutui-font-size-s: var(--nutui-font-size-12);
--nutui-font-size-m: var(--nutui-font-size-13);
// 标准内容、名称类关键信息
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

请补齐注释前空行以通过 stylelint。

Line 261、263、265、268、270 触发 scss/double-slash-comment-empty-line-before,建议按规则补一个空行。

Also applies to: 263-263, 265-265, 268-268, 270-270

🧰 Tools
🪛 Stylelint (17.11.0)

[error] 261-261: 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` at line 261, The SCSS file has single-line
comments like "// 标准内容、名称类关键信息" that violate the
scss/double-slash-comment-empty-line-before rule; add a blank line immediately
before each offending double-slash comment (the occurrences containing the text
"标准内容、名称类关键信息" and the other comments at the same pattern on the listed lines)
so each // comment is preceded by an empty line to satisfy stylelint.

// 汉字:次要内容、辅助类信息 数字:羊角符号、小数点及角分
--nutui-font-size-s: var(--nutui-font-size-12);
--nutui-font-size-m: var(--nutui-font-size-13);
// 标准内容、名称类关键信息
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

这里有注释空行的 stylelint 错误。

Line 260、262、264、267、269 触发 scss/double-slash-comment-empty-line-before,建议补齐空行保持 CI 通过。

Also applies to: 262-262, 264-264, 267-267, 269-269

🧰 Tools
🪛 Stylelint (17.11.0)

[error] 260-260: 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` at line 260, The SCSS file contains
single-line comments like "// 标准内容、名称类关键信息" that are triggering the stylelint
rule scss/double-slash-comment-empty-line-before on several lines; fix by
inserting the required empty line(s) before each double-slash comment (e.g., the
comment text "// 标准内容、名称类关键信息") so the comment is preceded by a blank line as
expected by the linter across the affected occurrences.

Comment thread src/styles/variables.scss
Comment on lines +309 to +312
$button-xlarge-height: var(
--nutui-button-xlarge-height,
scale-px(48px)
) !default;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

请修复这些 stylelint 违规,避免样式检查阻塞。

Line 309、330、358、459、579、2231、2730 附近存在 scss/dollar-variable-empty-line-before / scss/double-slash-comment-empty-line-before 规则错误,建议统一补齐或移除空行后再提交。

Also applies to: 330-330, 358-361, 459-462, 579-579, 2231-2231, 2730-2731

🧰 Tools
🪛 Stylelint (17.11.0)

[error] 309-312: Unexpected empty line before $-variable (scss/dollar-variable-empty-line-before)

(scss/dollar-variable-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/variables.scss` around lines 309 - 312, Fix the stylelint
violations for scss/dollar-variable-empty-line-before and
scss/double-slash-comment-empty-line-before by making spacing consistent around
SCSS variable declarations and single-line comments in variables.scss;
specifically adjust the blank line before the $button-xlarge-height declaration
and any other nearby $-variables or // comments so they either have the required
empty line or none (matching your project rule), and re-run stylelint to verify
and fix the remaining occurrences reported (e.g., around $button-xlarge-height
and other $variable and // comment blocks referenced in the review).

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/packages/calendarcard/calendarcard.scss (1)

70-77: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

$font-size-s 与固定 12px 行盒组合有裁切风险。

Line 76 改为字体 token 后,Line 75Line 77 仍固定为 12px。在大字/老年倍率下,文本可能被压缩或截断。建议让行高(必要时高度)与字体缩放保持一致。

🛠 建议修改
     &-top,
     &-bottom {
       display: flex;
       align-items: center;
       justify-content: center;
       width: 100%;
-      height: 12px;
+      height: scale-font-px(12px);
       font-size: $font-size-s;
-      line-height: 12px;
+      line-height: scale-font-px(12px);
     }
🤖 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.scss` around lines 70 - 77, The
.calendarcard &-bottom rule uses $font-size-s with a fixed 12px line-height and
height, which can cause clipping at larger font scales; update the &-bottom
declaration so line-height and height are tied to the font token (or use a
scalable unit) — e.g. replace line-height: 12px and height: 12px with a
line-height that matches the font-size token (or a relative value like 1) and
set height to auto or min-height using the same token (reference: the &-bottom
selector and $font-size-s variable).
🤖 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/calendarcard/calendarcard.scss`:
- Around line 70-77: The .calendarcard &-bottom rule uses $font-size-s with a
fixed 12px line-height and height, which can cause clipping at larger font
scales; update the &-bottom declaration so line-height and height are tied to
the font token (or use a scalable unit) — e.g. replace line-height: 12px and
height: 12px with a line-height that matches the font-size token (or a relative
value like 1) and set height to auto or min-height using the same token
(reference: the &-bottom selector and $font-size-s variable).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e8f29c29-9af5-4979-8262-819c55efa713

📥 Commits

Reviewing files that changed from the base of the PR and between 0dcd2b4 and e606a0b.

📒 Files selected for processing (21)
  • .cursor/skills/nutui-proportional-scaling/SKILL.md
  • src/packages/calendarcard/calendarcard.scss
  • src/packages/card/card.scss
  • src/packages/inputnumber/inputnumber.taro.tsx
  • src/packages/menuitem/menuitem.taro.tsx
  • src/packages/noticebar/noticebar.scss
  • src/packages/noticebar/noticebar.taro.tsx
  • src/packages/noticebar/noticebar.tsx
  • src/packages/notify/notify.scss
  • src/packages/notify/notify.taro.tsx
  • src/packages/numberkeyboard/numberkeyboard.scss
  • src/packages/numberkeyboard/numberkeyboard.tsx
  • src/packages/rate/rate.scss
  • src/packages/segmented/segmented.scss
  • src/packages/shortpassword/shortpassword.scss
  • src/packages/shortpassword/shortpassword.taro.tsx
  • src/packages/shortpassword/shortpassword.tsx
  • src/packages/tabs/tabs.scss
  • src/packages/tabs/tabs.taro.tsx
  • src/packages/tabs/tabs.tsx
  • src/styles/variables.scss
💤 Files with no reviewable changes (2)
  • src/packages/menuitem/menuitem.taro.tsx
  • src/packages/inputnumber/inputnumber.taro.tsx
✅ Files skipped from review due to trivial changes (4)
  • src/packages/tabs/tabs.tsx
  • src/packages/numberkeyboard/numberkeyboard.scss
  • src/packages/segmented/segmented.scss
  • src/packages/rate/rate.scss
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/packages/tabs/tabs.scss

@irisSong irisSong changed the title chore:仅对比使用 feat: 等比多尺寸适配 May 12, 2026
@irisSong irisSong requested a review from xiaoyatong May 15, 2026 06:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action:review This PR needs more reviews (less than 2 approvals) size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants