Skip to content

Rate support precision #196

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

yellowryan
Copy link

@yellowryan yellowryan commented Mar 6, 2025

Rate组件支持更精细的控制

Related to antd#52986

  • 实现方式

    • 根据鼠标hover的移动,计算出百分比,和给定的precision进行一次rounded计算,最终赋值给相对应元素的宽度属性上。
  • 兼容处理

    • 原先有一个allowHalf(允许半星)的属性,既然有了precision的话,就没有必要继续用这个属性了,添加上了deprecated标记,内部做了一下兼容。

Summary by CodeRabbit

  • 新功能

    • 引入了更精细的评分功能,允许用户设置评分增量(如 0.1),以实现更精准的评分控制。
    • 示例中新增「Precision」展示区,直观展示全新评分效果。
  • 样式

    • 优化了评分组件的视觉外观,移除了部分过渡效果,并调整了星级显示样式。
  • 重构

    • 改进了评分计算逻辑和星级渲染,提升了评分显示的响应性和精确性。
  • 测试

    • 新增测试用例以验证精细评分功能的正确性。

Copy link

vercel bot commented Mar 6, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
rate ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 10, 2025 3:40am

Copy link

coderabbitai bot commented Mar 6, 2025

Walkthrough

此次变更涉及评分组件及其相关样式、逻辑和测试用例的更新。在 assets/index.less 中优化了评分星的样式,取消了一些转场效果并调整了宽度、透明度和颜色设定;在 docs/examples/simple.tsx 中新增了 "Precision" 示例;在 src/Rate.tsx 中引入了新的 precision 属性,优化了星级计算逻辑并废弃了 allowHalf;同时,src/Star.tsx 实现了 memoized 宽度计算,src/util.ts 添加了辅助工具函数,测试用例也随之更新。

Changes

文件 更改摘要
assets/index.less 移除转场效果,调整评分星样式:将 &-first 的宽度由 50% 改为 0%,透明度由 0 调整为 1,并添加了颜色属性;同时移除了部分悬停状态的样式。
docs/examples/simple.tsx, tests/simple.spec.js, src/Rate.tsx 实现并扩展了评分组件的 precision 特性:在组件中添加了 precision 属性,优化了事件处理和星级计算逻辑,同时在示例和测试用例中新增了相关验证。
src/Star.tsx 新增 memoized 计算逻辑,根据传入的 valueindex 动态计算星的宽度,修改了第一个星的渲染方式,添加内联样式以控制溢出。
src/util.ts 新增实用工具函数:导出 getBoundingClientRect ,以及 roundValueToPrecisionclamp 函数,同时添加了一个用于计算小数位数的内部辅助函数。

Sequence Diagram(s)

sequenceDiagram
    participant U as 用户
    participant R as Rate 组件
    participant S as Star 组件
    participant UTL as 工具函数

    U->>R: 触发鼠标事件 (click/move)
    R->>UTL: 获取元素边界 (getBoundingClientRect)
    UTL-->>R: 返回边界信息
    R->>UTL: 计算百分比 (calculatePercentage) 并执行四舍五入 (roundValueToPrecision)
    UTL-->>R: 返回计算结果
    R->>S: 更新星级显示 (通过 memoized 宽度)
    S-->>R: 完成渲染更新
Loading

Poem

嗨,我是一只跳跃的小兔子,
代码新意在风中轻舞,
样式清新如春日花开,
精度精准似晨光闪耀,
工具与测试齐奏欢歌,
我在代码森林中奔跑,快乐无限!
🐰🌸

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/Star.tsx

Oops! Something went wrong! :(

ESLint: 7.32.0

ESLint couldn't find the plugin "eslint-plugin-react".

(The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-react@latest --save-dev

The plugin "eslint-plugin-react" was referenced from the config file in ".eslintrc.js » /node_modules/.pnpm/@umijs[email protected]/node_modules/@umijs/fabric/dist/eslint.js".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6e30f9 and 8a88848.

📒 Files selected for processing (1)
  • src/Star.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Star.tsx

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 0

🧹 Nitpick comments (6)
docs/examples/simple.tsx (1)

3-3: 导入顺序变更

React 导入已移至 Rate 组件导入之后。虽然这不会影响功能,但最好保持一致的导入顺序,通常先导入核心库(如 React),然后是第三方库,最后是本地模块。

-import Rate from 'rc-rate';
-import React from 'react';
+import React from 'react';
+import Rate from 'rc-rate';
src/Star.tsx (2)

2-3: 导入顺序调整

导入顺序已调整,将React的导入移至KeyCode之后。为了保持一致性,建议将React作为首要导入。

-import KeyCode from 'rc-util/lib/KeyCode';
-import React from 'react';
+import React from 'react';
+import KeyCode from 'rc-util/lib/KeyCode';

93-101: 动态宽度样式应用

通过内联样式动态设置星星宽度的实现很好地支持了精确评分功能。建议考虑添加注释解释这种实现与allowHalf属性的关系。

建议在这个部分添加注释说明这个实现如何与精确度值一起工作:

 <div
   className={`${prefixCls}-first`}
   style={{
     width: `${memoWidth}%`,
     overflow: 'hidden',
   }}
+  // 基于精确值动态计算宽度百分比
 >
tests/simple.spec.js (1)

1-3: 导入顺序调整

导入顺序已调整,将React的导入移至enzyme之后。为了保持一致性,建议将React作为首要导入。

-import { mount, render } from 'enzyme';
-import KeyCode from 'rc-util/lib/KeyCode';
-import React from 'react';
+import React from 'react';
+import { mount, render } from 'enzyme';
+import KeyCode from 'rc-util/lib/KeyCode';
src/util.ts (1)

51-59: 在除以 precision 前最好校验 precision ≠ 0
当前实现若 precision === 0,会发生除零行为,也可能产生无穷大或 NaN 的结果,且后续 toFixed 可能报错。推荐加以保护或抛出异常以防止潜在错误。

src/Rate.tsx (1)

88-89: mergedPrecision 对非法精度回退处理合理,但可考虑给予用户提示。
precision <= 0 时自动回退为 1,目前逻辑能避免异常,但可能让部分使用者摸不着头脑。可在开发或调试阶段增加警告。

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1ec5a9d and c6e30f9.

⛔ Files ignored due to path filters (1)
  • tests/__snapshots__/simple.spec.js.snap is excluded by !**/*.snap
📒 Files selected for processing (6)
  • assets/index.less (1 hunks)
  • docs/examples/simple.tsx (2 hunks)
  • src/Rate.tsx (8 hunks)
  • src/Star.tsx (3 hunks)
  • src/util.ts (1 hunks)
  • tests/simple.spec.js (3 hunks)
🔇 Additional comments (18)
docs/examples/simple.tsx (1)

62-70: 精确评分功能展示良好

新增的"Precision"示例很好地展示了评分组件的精确度功能。这个例子使用0.1的精度和1.2的默认值,清晰地演示了该特性。

src/Star.tsx (1)

76-78: 精确宽度计算实现

使用useMemo缓存星星宽度计算结果是个好做法,可以避免不必要的重复计算。计算逻辑也很合理,确保了宽度百分比在0到100之间。

tests/simple.spec.js (1)

343-358: 精确度功能测试用例完善

新增的精确度测试用例很好地覆盖了核心功能点。测试验证了精确值如何影响星星的宽度显示,包括完整星星和部分填充星星的情况。特别是使用toBeCloseTo而不是精确比较是一个很好的做法,避免了因浮点数计算精度问题导致的测试不稳定。

assets/index.less (2)

56-56: 星星初始宽度调整

.@{rate-prefix-cls}-star-first的宽度从50%改为0%,配合Star组件中的动态宽度计算,更好地支持了精确评分功能。这样的改变使得星星的填充完全由JavaScript控制,而不是依赖CSS预设值。


59-60: 星星样式优化

将不透明度从0改为1并添加颜色属性是正确的改进。这确保了星星的前半部分可见并使用正确的颜色。这些变更与Star组件中的宽度计算配合,实现了更精确的星星评分显示。

src/util.ts (3)

41-44: 建议在使用此函数前做好空值检查。
如果元素尚未挂载到 DOM,调用 getBoundingClientRect 可能会导致错误,或返回不完整的坐标数据。可在上层逻辑中检查元素是否存在,确保安全调用。


46-49: 函数逻辑简洁,但需留意科学计数法的特殊情况。
value.toString() 遇到科学计数法(如 0.0001)时可能返回字符串形式并正常解析,但若出现非常小或非常大的数字,需确保业务场景能正确处理。若无此需求可忽略。


60-66: 实现逻辑清晰,通过数值夹取可以防止越界。
此函数在通用业务中足够灵活,可按需增加对 NaN 的防护。

src/Rate.tsx (10)

9-9: 新增导入的工具函数调用合理。
clamp, getBoundingClientRectroundValueToPrecision 结合使用,为星级计算提供了更精细的控制。


35-38: precision 属性应在类型定义中明确限定取值范围。
允许用户随意设置负数或零可能在计算时产生异常,建议增加对有效取值的说明或校验。


56-59: 已正确标注 allowHalf 废弃状态。
注释充分说明了此属性被替代的原因,便于后续维护和使用。


63-63: 默认精度为 1,需与其他逻辑保持一致。
若用户故意传入小于等于 0 时,后续逻辑会回退为默认值 1。此点建议在文档中写明,以免引起困惑。


113-115: 应注意 leftright 相等时会导致除零。
在极端场景下,如果星星宽度为 0 或未渲染完全,(right - left) 会变为 0,需确保业务层能捕获或避免此问题。


117-125: 检查 rateRef.current 是否存在,防止空引用。
rateRef.current 尚未赋值就调用,会引发错误,建议在调用前判断组件是否已渲染或在上层保证其一定存在。


127-142: 混合处理大于 1 的精度时要注意星值计算的一致性。
mergedPrecision > 1 时,函数内的逻辑需与普通精度场景保持步调一致。可考虑将分支逻辑合并或增强单测覆盖,避免未来维护出现遗漏。


169-169: 鼠标悬停改用 clientX,应确保对滚动容器下的定位仍然可靠。
若组件在可滚动容器中使用,clientX 与之前的滚动偏移逻辑存在差异,测试场景需留意此处。


190-190: 点击同样改用 clientX,建议整体验证新坐标系下的交互表现。
若页面存在横向滚动或其他位移,需确认计算出的星级不受影响。


202-202: 按键增减改用 mergedPrecision,功能更灵活。
此变更使得键盘交互可支持任意自定义精度,确保在高精度状态下仍有合适的递增步长。

@yellowryan
Copy link
Author

同时还有一个展示问题想请问下意见 ,例如设置的defaultValue是1.2,但是精度是1,那展示的时候是展示1颗星还是1.2颗星(目前的表现是会展示1.2颗星),但是hover、点击变化的时候会变成1、2、3这样。

import classNames from 'classnames';
import KeyCode from 'rc-util/lib/KeyCode';
Copy link
Member

Choose a reason for hiding this comment

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

既然都调整代码了,感觉可以直接把 hover 一些逻辑挪到 Star 里。以前放 Rate 计算其实不太内聚的

Copy link
Author

Choose a reason for hiding this comment

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

hover和click的一些逻辑存在耦合,不太好直接单拎出来

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants