-
Notifications
You must be signed in to change notification settings - Fork 292
Bugfix/v3.x #3408
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
base: feat_v3.x
Are you sure you want to change the base?
Bugfix/v3.x #3408
Conversation
Walkthrough本PR包含三项改动:表单项标签由 Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (4 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Repository UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (4)
🧰 Additional context used🧠 Learnings (1)📓 Common learnings⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
🔇 Additional comments (4)
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. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## feat_v3.x #3408 +/- ##
==========================================
Coverage 88.15% 88.16%
==========================================
Files 291 291
Lines 19212 19215 +3
Branches 2988 2990 +2
==========================================
+ Hits 16937 16940 +3
Misses 2269 2269
Partials 6 6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (2)
src/packages/formitem/formitem.scss (1)
136-136: 标签换行功能已正确实现将
white-space: nowrap替换为word-wrap: break-word可以让表单标签文本自动换行,改善了长标签的显示效果。不过需要注意,第 18 行的
.nut-form-item-label类已经设置了word-wrap: break-word。如果这些位置修饰符类(.nut-form-item-label-right、.nut-form-item-label-left)通常与父类一起使用,则可能存在属性重复。建议验证这些类的实际应用场景,确认是否需要显式声明以提高 CSS 优先级。#!/bin/bash # 描述:查找 formitem 相关组件中这些 CSS 类的使用方式 # 搜索 .nut-form-item-label-right 和 .nut-form-item-label-left 的使用 rg -n -A3 -B3 --type=tsx --type=ts --type=jsx --type=js 'nut-form-item-label-(right|left)'Also applies to: 142-142
src/packages/toast/toast.tsx (1)
66-68: 可选的代码简化建议当前的过滤和迭代模式功能正确,但可以简化以提高可读性:
🔎 建议的重构方案
- const checkParam = ['title', 'content'] - Object.entries(option) - .filter(([k, v]) => checkParam.includes(k)) - .forEach(([k, v]) => errorMsg(v)) + const checkParam = ['title', 'content'] as const + checkParam.forEach((key) => { + if (key in option) { + errorMsg(option[key]) + } + })
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/packages/formitem/formitem.scsssrc/packages/toast/toast.tsxsrc/types/spec/toast/base.ts
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: oasis-cloud
Repo: jdf2e/nutui-react PR: 2700
File: src/packages/animatingnumbers/animatingnumbers.harmony.css:25-32
Timestamp: 2024-11-06T05:56:06.800Z
Learning: 在优化 NutUI React 动画性能时,添加 `will-change` 属性可能会对布局产生影响,需要谨慎使用。
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: test
| const checkParam = ['title', 'content'] | ||
| Object.entries(option) | ||
| .filter(([k, v]) => checkParam.includes(k)) | ||
| .forEach(([k, v]) => errorMsg(v)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Verification inconclusive
React rendering 0 and false as child elements behavior
Short answer
- React treats false, true, null and undefined as “ignore me” when used as children — they produce no DOM output. It DOES render numbers and strings, so 0 is rendered as text. [1][2]
Why
- React’s renderer only skips booleans/null/undefined to support common conditional patterns (e.g. cond && ). Numbers (including 0) are valid renderable children, so 0 will be inserted as text. [1][2]
How to avoid accidentally showing 0
- Use an explicit boolean expression: {items.length > 0 && }. [2]
- Use a ternary: {count ? {count} : null} or {count > 0 ? {count} : null}. [3]
- Coerce to null when you want nothing: {condition ? : null} (preferred). [3]
Examples
- 0 && // renders "0"
- false && // renders nothing
- {count ? {count} : null} // only shows when count != 0. [1][3]
Sources
- React “False in JSX” tip. [1]
- Explanation of children and length-check pitfall. [2]
- Common fixes / patterns (ternary vs &&). [3]
Script executed:
# First, let's examine the toast.tsx file at the specified lines
fd "toast.tsx" -type f | head -20Repository: jdf2e/nutui-react
Repository: jdf2e/nutui-react
Script execution failed with unrecoverable error: [CAPABILITY:RUN_SHELL_SCRIPT] Failed to clone repository jdf2e/nutui-react: Clone operation failed
Script executed:
# Also search for base.ts to check the type changes mentioned
fd "base.ts" -type f | grep -i toastRepository: jdf2e/nutui-react
Repository: jdf2e/nutui-react
Exit code: 1
stderr:
error: 'ype' isn't a valid value for '--type <filetype>'
[possible values: file, directory, symlink, executable, empty, socket, pipe]
For more information try '--help'
Script executed:
# List all toast-related files
find . -name "*toast*" -type f 2>/dev/null | head -20Repository: jdf2e/nutui-react
Repository: jdf2e/nutui-react
Exit code: 0
stdout:
./src/packages/toast/__test__/toast.spec.tsx
./src/packages/toast/toast.scss
./src/packages/toast/toast.taro.tsx
./src/packages/toast/toast.tsx
Script executed:
# Search for errorMsg function definition
rg "errorMsg" -A 5 -B 2Repository: jdf2e/nutui-react
Repository: jdf2e/nutui-react
Exit code: 0
stdout:
src/sites/sites-react/doc/docs/react/migrate-from-v1.md-- `noButton` 重命名为 `hideFooter`
src/sites/sites-react/doc/docs/react/migrate-from-v1.md-- `onOk` 重命名为 `onConfirm`
src/sites/sites-react/doc/docs/react/migrate-from-v1.md:- `errorMsg` 重命名为 `error`
src/sites/sites-react/doc/docs/react/migrate-from-v1.md-- 移除 `closeOnClickOverlay`,默认支持透传 Popup 属性
src/sites/sites-react/doc/docs/react/migrate-from-v1.md-- `title`、`description`、`tips`、`error` 类型修改为 `ReactNode`
src/sites/sites-react/doc/docs/react/migrate-from-v1.md-- `modelValue` 重命名为 `value`,受控模式
src/sites/sites-react/doc/docs/react/migrate-from-v1.md-- 新增 `onFoucs` 事件
src/sites/sites-react/doc/docs/react/migrate-from-v1.md-
--
src/sites/sites-react/doc/docs/taro/migrate-from-v1.md-- `noButton` 重命名为 `hideFooter`
src/sites/sites-react/doc/docs/taro/migrate-from-v1.md-- `onOk` 重命名为 `onConfirm`
src/sites/sites-react/doc/docs/taro/migrate-from-v1.md:- `errorMsg` 重命名为 `error`
src/sites/sites-react/doc/docs/taro/migrate-from-v1.md-- 移除 `closeOnClickOverlay`,默认支持透传 Popup 属性
src/sites/sites-react/doc/docs/taro/migrate-from-v1.md-- `title`、`description`、`tips`、`error` 类型修改为 `ReactNode`
src/sites/sites-react/doc/docs/taro/migrate-from-v1.md-- `modelValue` 重命名为 `value`,受控模式
src/sites/sites-react/doc/docs/taro/migrate-from-v1.md-- 新增 `onFoucs` 事件
src/sites/sites-react/doc/docs/taro/migrate-from-v1.md-
--
src/packages/toast/toast.tsx-}
src/packages/toast/toast.tsx-
src/packages/toast/toast.tsx:const errorMsg = (msg: any) => {
src/packages/toast/toast.tsx- if (!msg) {
src/packages/toast/toast.tsx- console.warn('[NutUI Toast]: msg cannot be null')
src/packages/toast/toast.tsx- }
src/packages/toast/toast.tsx-}
src/packages/toast/toast.tsx-
src/packages/toast/toast.tsx-function show(option: ToastNativeProps | string) {
src/packages/toast/toast.tsx- if (typeof option === 'string') {
src/packages/toast/toast.tsx: errorMsg(option)
src/packages/toast/toast.tsx- return notice({ content: option })
src/packages/toast/toast.tsx- }
src/packages/toast/toast.tsx- const checkParam = ['title', 'content']
src/packages/toast/toast.tsx- Object.entries(option)
src/packages/toast/toast.tsx- .filter(([k, v]) => checkParam.includes(k))
src/packages/toast/toast.tsx: .forEach(([k, v]) => errorMsg(v))
src/packages/toast/toast.tsx- return notice({
src/packages/toast/toast.tsx- ...option,
src/packages/toast/toast.tsx- })
src/packages/toast/toast.tsx-}
src/packages/toast/toast.tsx-
--
src/packages/notify/notify.tsx-}
src/packages/notify/notify.tsx-
src/packages/notify/notify.tsx:const errorMsg = (message: any) => {
src/packages/notify/notify.tsx- if (!message) {
src/packages/notify/notify.tsx- console.warn('[NutUI Notify]: message不能为空')
src/packages/notify/notify.tsx- }
src/packages/notify/notify.tsx-}
src/packages/notify/notify.tsx-
src/packages/notify/notify.tsx-export default {
src/packages/notify/notify.tsx- text(message: string | React.ReactNode, option = {}) {
src/packages/notify/notify.tsx: errorMsg(message)
src/packages/notify/notify.tsx- return notice({ message, type: 'base', ...option })
src/packages/notify/notify.tsx- },
src/packages/notify/notify.tsx- hide() {
src/packages/notify/notify.tsx- if (messageInstance) {
src/packages/notify/notify.tsx- messageInstance.destroy()
--
packages/nutui-codemod/transforms/rules/props-rules.js- replacer: 'onConfirm',
packages/nutui-codemod/transforms/rules/props-rules.js- },
packages/nutui-codemod/transforms/rules/props-rules.js: errorMsg: {
packages/nutui-codemod/transforms/rules/props-rules.js- action: 'rename',
packages/nutui-codemod/transforms/rules/props-rules.js- replacer: 'error',
packages/nutui-codemod/transforms/rules/props-rules.js- },
packages/nutui-codemod/transforms/rules/props-rules.js- modelValue: {
packages/nutui-codemod/transforms/rules/props-rules.js- action: 'rename',
Script executed:
# Search for type definitions in base.ts
rg "title.*ReactNode\|content.*ReactNode" -A 2 -B 2Repository: jdf2e/nutui-react
Repository: jdf2e/nutui-react
Exit code: 1
Script executed:
# Get the specific lines from toast.tsx
rg "const checkParam = \['title'" -A 5 -B 5Repository: jdf2e/nutui-react
Repository: jdf2e/nutui-react
Exit code: 0
stdout:
src/packages/toast/toast.tsx-function show(option: ToastNativeProps | string) {
src/packages/toast/toast.tsx- if (typeof option === 'string') {
src/packages/toast/toast.tsx- errorMsg(option)
src/packages/toast/toast.tsx- return notice({ content: option })
src/packages/toast/toast.tsx- }
src/packages/toast/toast.tsx: const checkParam = ['title', 'content']
src/packages/toast/toast.tsx- Object.entries(option)
src/packages/toast/toast.tsx- .filter(([k, v]) => checkParam.includes(k))
src/packages/toast/toast.tsx- .forEach(([k, v]) => errorMsg(v))
src/packages/toast/toast.tsx- return notice({
src/packages/toast/toast.tsx- ...option,
参数验证逻辑存在缺陷:对 ReactNode 类型的检查过于严格
虽然扩展验证范围到 title 和 content 的思路正确,但 errorMsg 函数使用 !msg 检查存在问题。根据 React 规范,数字 0 是有效的 ReactNode 值(会被渲染为文本),而 false、null、undefined 才是被忽略的值。当前的检查逻辑会将 0 误判为无效。
同时,由于 title 和 content 现在是 ReactNode 类型,警告消息"msg cannot be null"不够准确。
建议改进验证逻辑,准确检查真正需要避免的空值:
const errorMsg = (msg: any) => {
- if (!msg) {
- console.warn('[NutUI Toast]: msg cannot be null')
+ if (msg == null || msg === '') {
+ console.warn('[NutUI Toast]: title and content cannot be empty')
}
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/packages/toast/toast.tsx around lines 65-68, the current validation uses
a falsy check (!msg) which incorrectly treats 0 as invalid; update the
validation to explicitly reject only React-ignored values (null, undefined, and
false) — e.g. check msg === null || msg === undefined || msg === false — and
update the warning text to something like "msg cannot be null, undefined, or
false" to reflect ReactNode types.
🤔 这个变动的性质是?
🔗 相关 Issue
💡 需求背景和解决方案
☑️ 请求合并前的自查清单
Summary by CodeRabbit
发行说明
样式改进
功能增强
✏️ Tip: You can customize this high-level summary in your review settings.