-
Notifications
You must be signed in to change notification settings - Fork 283
feat: datepickerview #3026
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
feat: datepickerview #3026
Conversation
Walkthrough此次 PR 对日期选择器相关功能进行了扩展和重构。配置文件中调整了“Col”组件的格式,并在“数据录入”部分新增了 DatePickerView 组件。多个日期选择器组件中引入了新的依赖(如 isEqual 和 classNames),重构了组件实现(从 FunctionComponent 转为 forwardRef 形式),并优化了状态管理与日期比较逻辑。同时,还增加了针对 DatePickerView 的测试用例、演示示例以及详细的文档说明。 Changes
Sequence Diagram(s)sequenceDiagram
participant U as 用户
participant DP as DatePickerView
participant HC as 日期比较逻辑
participant HO as onChange回调
U->>DP: 选择日期
DP->>HC: 执行 handleDateComparison/handleChange
HC-->>DP: 返回比较结果
DP->>HO: 触发 onChange 事件
HO-->>U: 更新页面显示
Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## feat_v3.x #3026 +/- ##
=============================================
+ Coverage 86.05% 86.12% +0.06%
=============================================
Files 281 283 +2
Lines 18255 18401 +146
Branches 2749 2768 +19
=============================================
+ Hits 15709 15847 +138
- Misses 2541 2549 +8
Partials 5 5 ☔ View full report in Codecov by Sentry. |
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: 3
🧹 Nitpick comments (26)
src/packages/picker/types.ts (1)
17-42
: PickerProps 接口定义完整定义了 Picker 组件的属性接口,包括必要的数据属性、交互行为和回调函数。特别是:
- 通过继承 BasicComponent 并排除 children 属性,然后在最后再添加 children 的方式,使类型定义更加灵活。
- 对于 popupProps 的处理,使用 Partial 和 Omit 组合排除了可能与父级属性冲突的字段。
- 回调函数类型定义清晰,参数类型明确。
建议:
- 考虑为
defaultValue
和value
添加更详细的类型注释,说明它们与 options 的对应关系children
类型使用any
不太严谨,建议使用React.ReactNode
或更具体的类型- children?: any + children?: React.ReactNodesrc/packages/datepickerview/types.ts (1)
8-31
: DatePickerViewProps 接口设计全面接口设计全面,包含了日期选择器视图组件所需的所有关键属性:
- 值控制(value/defaultValue)
- 日期类型配置(多种格式选项)
- 显示和步进控制
- 日期范围限制
- 格式化和过滤函数
- 事件回调
建议为必选和可选属性添加明确的注释,以提高代码的可维护性。
src/packages/form/demos/h5/demo7.tsx (1)
121-153
: 日期选择器实现合理,但可考虑提取公共样式日期选择器的实现逻辑清晰,功能完整。初始值设置、事件处理和显示格式都很合理。
不过,这里的Cell样式与第98-116行的Picker组件中的Cell样式完全相同。可以考虑将这些共同样式提取为一个常量或辅助函数,以减少代码重复。
- <Cell - style={{ - padding: 0, - '--nutui-cell-divider-border-bottom': '0', - }} - className="nutui-cell--clickable" - title={ - value - ? new Date(value).toLocaleDateString() - : 'Please select' - } - extra={<ArrowRight />} - align="center" - /> + <Cell + style={commonCellStyle} + className="nutui-cell--clickable" + title={ + value + ? new Date(value).toLocaleDateString() + : 'Please select' + } + extra={<ArrowRight />} + align="center" + />同时在文件顶部添加:
const commonCellStyle = { padding: 0, '--nutui-cell-divider-border-bottom': '0', }src/packages/datepickerview/demo.taro.tsx (1)
1-38
: 组件结构良好,但混合了View和h2标签这个新的DatePickerViewDemo组件结构清晰,国际化实现得当。支持中文简体、繁体和英文三种语言,满足多语言需求。
但在第29行使用了Taro的
<View className="h2">
,而第31行却直接使用了HTML的<h2>
标签。建议为了保持一致性,统一使用Taro的组件:- <View className="h2">{translated.basic}</View> + <View className="h2">{translated.basic}</View> <Demo1 /> - <h2>{translated.mmdd}</h2> + <View className="h2">{translated.mmdd}</View>这样可以确保在各平台(特别是小程序环境)下的兼容性和一致性。
src/packages/picker/__tests__/picker.spec.tsx (1)
177-199
: 测试中的异步处理可以优化根据之前的学习经验,在React组件测试中应避免使用带有固定延迟的setTimeout。建议使用act()包装异步状态更新,并使用waitFor()进行断言,这样可以使测试更稳定可靠。
虽然当前测试用例可以工作,但可以考虑采用更现代的异步测试方法。
const PenderContent = () => { const [asyncColumns, setasyncColumns] = useState([]) - setTimeout(() => { - setasyncColumns(simpleColumns) - }, 100) + React.useEffect(() => { + const timer = setTimeout(() => { + setasyncColumns(simpleColumns) + }, 100) + return () => clearTimeout(timer) + }, []) return ( <Picker visiblesrc/packages/datepickerview/demos/h5/demo2.tsx (2)
21-31
: 日期范围限制实现合理,但可优化描述一致性DatePickerView组件的配置合理,限制了开始和结束时间,并提供了适当的默认值。
不过,组件的标题"限制开始结束时间"与实际操作有关,但Cell的description使用的只是选中的日期值,可能会让用户困惑。建议将标题与描述信息更加一致,或者在描述中也反映出日期范围的信息。
9-17
: 日期格式化可以使用统一工具函数当前代码直接使用了Date原生方法来格式化月份和日期,但这种方式可能导致不同地区的显示差异。考虑使用专门的日期格式化工具或函数,确保一致的日期表示。
此外,月份需要+1处理(因为getMonth()返回0-11),这种逻辑在多处使用时容易出错。建议封装成工具函数。
- const [desc, setDesc] = useState( - `${defaultValue.getMonth() + 1}-${defaultValue.getDate()}` - ) + // 可以在项目中创建一个日期工具文件 + const formatMonthDay = (date) => { + return `${date.getMonth() + 1}-${date.getDate()}` + } + + const [desc, setDesc] = useState(formatMonthDay(defaultValue))src/packages/datepickerview/demo.tsx (1)
6-52
: 代码结构清晰,但可考虑增加更多演示案例组件演示代码结构清晰,很好地使用了国际化特性。不过,根据 demo.tsx 的内容,虽然有标题
{translated.showAll}
,但似乎没有对应的演示组件展示"选择年月日时分"功能,也缺少其他在翻译文本中定义的功能(如时间选择、格式化选项等)的演示。建议添加更多的演示案例来展示 DatePickerView 的所有功能,特别是已经在翻译文本中定义但尚未展示的功能。
src/packages/datepickerview/demos/taro/demo2.tsx (1)
9-33
: 代码实现合理,建议优化日期处理方式当前实现能够正确展示限制开始结束时间的功能,但日期处理方式可以进一步优化:
- 使用更安全的日期格式化方法,避免直接拼接字符串
- 考虑添加边界条件的处理,如无效日期的情况
建议考虑使用日期格式化库(如 date-fns)或自定义格式化函数来处理日期显示:
- const [desc, setDesc] = useState( - `${defaultValue.getMonth() + 1}-${defaultValue.getDate()}` - ) + const formatDate = (date: Date) => { + return `${date.getMonth() + 1}-${date.getDate()}` + } + const [desc, setDesc] = useState(formatDate(defaultValue))另外,建议为 Cell 组件的 title 添加国际化支持,使其与 demo.tsx 中的翻译保持一致。
src/packages/datepicker/demos/h5/demo1.tsx (1)
37-51
: 处理函数归一化优化
handleConfirm
函数很好地通过高阶函数实现了处理函数的归一化,但有一个问题:在第 41-43 行中硬编码了特定日期的比较逻辑
isEqual(values, ['2026', '02', '21'])
,这种方式不够灵活。建议:
- if (isEqual(values, ['2026', '02', '21'])) { - setValue('2026/03/22') - setDesc('2026年03月22日') - } else { + if (setValue) { setValue(values.join('/')) setDesc(options.map((option) => option.label).join('')) - }或者将这个特殊的日期处理逻辑抽离成配置项,增强代码的可维护性和灵活性。
src/packages/datepickerview/__test__/datepickerview.spec.tsx (1)
22-114
: 日期范围和格式化函数测试全面测试了
startDate
和endDate
属性,以及不同日期类型的渲染。格式化函数测试覆盖了所有日期类型。建议增加断言验证格式化后的文本内容是否符合预期,而不仅仅是执行重新渲染。
// 在 formatter 测试中添加以下断言 const yearItems = container.querySelectorAll('.nut-pickerview-list')[0].querySelectorAll('.nut-pickerview-roller-item'); expect(yearItems[0]).toHaveTextContent(/\d+/); // 验证年份格式src/packages/datepickerview/demos/h5/demo1.tsx (2)
11-21
: 自定义 Hook 返回默认日期和描述,功能简洁明了。
useDatePicker
能够将传入的初始日期转换为字符串并进行基础格式化,易于使用。若需国际化或更复杂的日期处理,可考虑参数化 formatter。
36-51
: onChange 回调中的特殊处理逻辑可进一步抽象。
判断['2026', '02', '26']
这种硬编码逻辑可以通过在 Hook 中或外部常量管理来提升可维护性,并避免散落在业务层的 magic numbers。src/packages/datepickerview/demos/taro/demo1.tsx (1)
36-51
: 使用相同的 onChange 回调逻辑,多端逻辑统一。
同样建议将硬编码的特殊日期逻辑抽离到常量或配置,防止未来业务扩展时出现维护问题。src/packages/datepicker/types.ts (1)
11-56
:DatePickerProps
定义全面,涵盖多种日期模式与回调函数。
- 支持
type
区分多种日期、时间格式为组件提供了灵活性。formatter
、filter
让开发者能在生成候选项时进行自定义处理,契合常见业务场景。- 建议在注释中注明各属性的默认值或适用范围,以方便团队后续维护。
src/packages/datepickerview/datepickerview.tsx (3)
73-77
: 借助usePropsValue
管理内部状态,减少受控与非受控两套逻辑的重复。
这种状态管理方式在复杂表单场景中易扩展,如需加强对同步/异步更新的控制,可在后续进一步优化。
79-99
:handleDateComparison
缺少测试覆盖,且逻辑存在潜在的时区问题。
- 静态分析提示此处未被测试,可补充单元测试以验证异常用例。
- 若部署地区存在时区差异,新旧日期的精细比较可受时区影响。
如需自动化脚本来查找测试文件并新增测试用例,可提出请求。
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 89-96: src/packages/datepickerview/datepickerview.tsx#L89-L96
Added lines #L89 - L96 were not covered by tests
169-181
: 仅在pickerOptions.length
大于 0 时渲染PickerView
。
此写法能够避免空数据导致渲染出错,但若pickerOptions
为空时,是否给予用户提示或 fallback 视图可酌情考虑。src/packages/datepickerview/datepickerview.taro.tsx (2)
154-155
: 移除或替换console.log
日志以避免生产环境中多余输出。
这里使用了console.log(new Date(selectedDate).toLocaleDateString())
,在生产环境中可能会造成无用的打印。若需保留调试信息,建议使用条件日志或调试工具。
117-152
: 建议将大型逻辑拆分以提升可维护性。
generatePickerColumns
函数体量较大,且包含多层级逻辑生成代码。可考虑将部分业务逻辑拆分到更小的函数中,从而提升可读性和后续维护性。src/packages/datepicker/datepicker.tsx (1)
129-176
: 与 Taro 同名文件的组件重复度较高,建议提取公共逻辑。
DatePicker
与 Taro 版本逻辑基本一致,包含许多相似处理函数及状态管理,后期维护会面临双处修改的风险。可将公共函数或 Hook 提取到独立模块中,减少重复代码并提升可维护性。🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 133-133: src/packages/datepicker/datepicker.tsx#L133
Added line #L133 was not covered by tests
[warning] 139-141: src/packages/datepicker/datepicker.tsx#L139-L141
Added lines #L139 - L141 were not covered by testssrc/packages/datepicker/datepicker.taro.tsx (2)
114-114
: 变量命名避免与判断逻辑重名。
行 114 与行 133-134 中将局部变量命名为isEqual
,易与其他相同命名逻辑混淆。建议更改为更具描述性的变量名,例如datesAreEqual
。Also applies to: 133-134
129-176
: 抽离公共逻辑,减少 Taro 与非 Taro 版本之间的重复。
InternalPicker
几乎与普通版相同,重复更新会提高出错概率。建议把重复部分封装到公共工具函数或 Hook 中,提高复用性。src/packages/datepicker/utils.ts (3)
66-67
: 考虑秒和分的关系在返回边界值对象时,
maxSeconds
和minSeconds
被设置为与分钟相同的值。这种实现可能是有意为之,但可能会导致用户混淆。建议考虑是否需要单独处理秒数,或者在注释中更清楚地说明这种关系。- [`${type}Seconds`]: minute, // 返回秒数(与分钟相同) + [`${type}Seconds`]: boundary.getSeconds(), // 返回实际的秒数或者保持现状但更新注释:
- [`${type}Seconds`]: minute, // 返回秒数(与分钟相同) + [`${type}Seconds`]: minute, // 目前秒数与分钟相同,简化处理
80-81
: 增强日期有效性检查当前的检查方式是
if (!selected) return []
,但这种检查可能不足以捕获所有无效日期情况,如Invalid Date
。建议使用更严格的日期验证。- const selected = new Date(selectedDate) - if (!selected) return [] + const selected = new Date(selectedDate) + if (!selected || isNaN(selected.getTime())) return []
131-132
: 增强日期有效性检查与前面的函数类似,这里只检查了
selectedDate
是否为假值,但没有检查日期是否有效。对于无效日期(例如NaN
),可能需要额外的验证。- if (!selectedDate) return 0 + if (!selectedDate || isNaN(date.getTime())) return 0
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
src/packages/datepickerview/__test__/__snapshots__/datepickerview.spec.tsx.snap
is excluded by!**/*.snap
📒 Files selected for processing (48)
src/config.json
(2 hunks)src/packages/calendar/demos/h5/demo6.tsx
(2 hunks)src/packages/calendar/demos/taro/demo6.tsx
(2 hunks)src/packages/datepicker/__test__/datepicker.spec.tsx
(1 hunks)src/packages/datepicker/datepicker.taro.tsx
(5 hunks)src/packages/datepicker/datepicker.tsx
(5 hunks)src/packages/datepicker/demos/h5/demo1.tsx
(3 hunks)src/packages/datepicker/demos/h5/demo2.tsx
(1 hunks)src/packages/datepicker/demos/h5/demo8.tsx
(4 hunks)src/packages/datepicker/demos/taro/demo1.tsx
(3 hunks)src/packages/datepicker/demos/taro/demo2.tsx
(1 hunks)src/packages/datepicker/demos/taro/demo8.tsx
(2 hunks)src/packages/datepicker/doc.en-US.md
(1 hunks)src/packages/datepicker/doc.md
(1 hunks)src/packages/datepicker/doc.taro.md
(1 hunks)src/packages/datepicker/doc.zh-TW.md
(1 hunks)src/packages/datepicker/index.taro.ts
(1 hunks)src/packages/datepicker/index.ts
(1 hunks)src/packages/datepicker/types.taro.ts
(1 hunks)src/packages/datepicker/types.ts
(1 hunks)src/packages/datepicker/utils.ts
(1 hunks)src/packages/datepickerview/__test__/datepickerview.spec.tsx
(1 hunks)src/packages/datepickerview/datepickerview.scss
(1 hunks)src/packages/datepickerview/datepickerview.taro.tsx
(1 hunks)src/packages/datepickerview/datepickerview.tsx
(1 hunks)src/packages/datepickerview/demo.taro.tsx
(1 hunks)src/packages/datepickerview/demo.tsx
(1 hunks)src/packages/datepickerview/demos/h5/demo1.tsx
(1 hunks)src/packages/datepickerview/demos/h5/demo2.tsx
(1 hunks)src/packages/datepickerview/demos/taro/demo1.tsx
(1 hunks)src/packages/datepickerview/demos/taro/demo2.tsx
(1 hunks)src/packages/datepickerview/doc.md
(1 hunks)src/packages/datepickerview/index.taro.ts
(1 hunks)src/packages/datepickerview/index.ts
(1 hunks)src/packages/datepickerview/types.ts
(1 hunks)src/packages/form/demos/h5/demo7.tsx
(2 hunks)src/packages/form/demos/taro/demo7.tsx
(2 hunks)src/packages/picker/__tests__/picker.spec.tsx
(2 hunks)src/packages/picker/index.taro.ts
(1 hunks)src/packages/picker/index.ts
(1 hunks)src/packages/picker/picker.taro.tsx
(3 hunks)src/packages/picker/picker.tsx
(1 hunks)src/packages/picker/types.taro.ts
(1 hunks)src/packages/picker/types.ts
(1 hunks)src/packages/popover/demos/h5/demo4-1.tsx
(2 hunks)src/packages/popover/demos/h5/demo4.tsx
(3 hunks)src/packages/popover/demos/taro/demo4-1.tsx
(3 hunks)src/packages/popover/demos/taro/demo4.tsx
(2 hunks)
✅ Files skipped from review due to trivial changes (4)
- src/packages/datepickerview/datepickerview.scss
- src/packages/datepickerview/index.taro.ts
- src/packages/datepickerview/index.ts
- src/packages/datepicker/index.taro.ts
🧰 Additional context used
🧠 Learnings (1)
src/packages/picker/__tests__/picker.spec.tsx (1)
Learnt from: xiaoyatong
PR: jdf2e/nutui-react#2990
File: src/packages/pickerview/__test__/pickerview.spec.tsx:0-0
Timestamp: 2025-02-25T02:21:32.906Z
Learning: In React component tests, avoid using setTimeout with fixed delays. Instead, use act() to wrap async state updates and waitFor() for assertions, which makes tests more stable and reliable.
🪛 GitHub Check: codecov/patch
src/packages/datepickerview/datepickerview.tsx
[warning] 89-96: src/packages/datepickerview/datepickerview.tsx#L89-L96
Added lines #L89 - L96 were not covered by tests
[warning] 161-162: src/packages/datepickerview/datepickerview.tsx#L161-L162
Added lines #L161 - L162 were not covered by tests
src/packages/datepicker/utils.ts
[warning] 115-115: src/packages/datepicker/utils.ts#L115
Added line #L115 was not covered by tests
[warning] 147-147: src/packages/datepicker/utils.ts#L147
Added line #L147 was not covered by tests
[warning] 243-244: src/packages/datepicker/utils.ts#L243-L244
Added lines #L243 - L244 were not covered by tests
[warning] 283-284: src/packages/datepicker/utils.ts#L283-L284
Added lines #L283 - L284 were not covered by tests
[warning] 287-288: src/packages/datepicker/utils.ts#L287-L288
Added lines #L287 - L288 were not covered by tests
src/packages/datepicker/datepicker.tsx
[warning] 98-99: src/packages/datepicker/datepicker.tsx#L98-L99
Added lines #L98 - L99 were not covered by tests
[warning] 101-102: src/packages/datepicker/datepicker.tsx#L101-L102
Added lines #L101 - L102 were not covered by tests
[warning] 133-133: src/packages/datepicker/datepicker.tsx#L133
Added line #L133 was not covered by tests
[warning] 139-141: src/packages/datepicker/datepicker.tsx#L139-L141
Added lines #L139 - L141 were not covered by tests
🪛 markdownlint-cli2 (0.17.2)
src/packages/datepickerview/doc.md
33-33: Link fragments should be valid
null
(MD051, link-fragments)
34-34: Tables should be surrounded by blank lines
null
(MD058, blanks-around-tables)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: test
🔇 Additional comments (89)
src/packages/calendar/demos/h5/demo6.tsx (4)
2-8
: 导入 PickerValue 类型用于类型安全
PickerValue
类型的导入增强了代码的类型安全性,这与 DatePicker 组件的重构保持一致。
41-41
: 更新函数参数类型以增强类型安全将
confirm
函数的参数类型从(string | number)[]
更新为PickerValue[]
,提高了类型安全性并与组件 API 的重构保持一致。
44-45
: 属性访问从 text 更新为 label将选项属性从
option.text
更新为option.label
,与 Picker 组件的 API 变更保持同步。
48-49
: 属性访问从 text 更新为 label将选项属性从
option.text
更新为option.label
,与 Picker 组件的 API 变更保持同步。src/packages/calendar/demos/taro/demo6.tsx (4)
7-7
: 导入 PickerValue 类型用于类型安全在 Taro 版本中导入
PickerValue
类型,确保与 H5 版本保持一致性,增强类型安全。
37-37
: 更新函数参数类型以增强类型安全将
confirm
函数的参数类型从(string | number)[]
更新为PickerValue[]
,与 H5 版本保持一致,提高了类型安全性。
40-41
: 属性访问从 text 更新为 label将选项属性从
option.text
更新为option.label
,确保与 Picker 组件的 API 变更和 H5 版本保持一致。
44-45
: 属性访问从 text 更新为 label将选项属性从
option.text
更新为option.label
,确保与 Picker 组件的 API 变更和 H5 版本保持一致。src/packages/popover/demos/taro/demo4.tsx (4)
3-8
: 更新导入引用和类型使用,确保类型安全将单独的导入语句合并成一个块导入,并添加了
PickerOnChangeCallbackParameter
类型导入,有助于提高代码的类型安全性和一致性。
16-30
: 列选项结构更新为使用label和value属性将选项结构从使用
text
属性更改为使用label
属性,保持了与其他Picker组件实现的一致性。这样的更改有助于统一API设计和提高代码可维护性。
60-60
: 更新onConfirm回调中的属性引用将
option.text
更改为option.label
,与列选项结构的更改保持一致。
64-67
: 改进onChange回调参数解构和类型安全使用
PickerOnChangeCallbackParameter
类型和解构selectedOptions
参数替代之前直接使用PickerOption[]
类型的方式,增强了类型安全性并使代码更加清晰。使用可选链操作符?.
和类型断言也提高了代码的健壮性。src/packages/popover/demos/h5/demo4.tsx (4)
2-7
: 组织导入并添加必要的类型将单独的导入语句合并成一个块导入,并添加了
PickerOnChangeCallbackParameter
类型,与其他文件保持一致。
15-29
: 统一Picker选项的数据结构将选项结构从使用
text
属性更改为使用label
属性,保持整个组件库中Picker组件API的一致性。
59-59
: 更新onConfirm回调中的属性引用从
option.text
更改为option.label
,与新的选项结构保持一致。
63-66
: 改进onChange处理函数的类型安全性使用
PickerOnChangeCallbackParameter
类型和解构语法,提高了代码的可读性和类型安全性。使用可选链操作符?.
和类型断言增强了代码的健壮性。src/packages/popover/demos/h5/demo4-1.tsx (4)
2-8
: 整合导入并添加必要的类型将导入语句合并为一个块导入,并添加了
PickerOnChangeCallbackParameter
类型导入,与其他组件保持一致的导入风格。
17-25
: 统一Picker选项的数据结构格式将选项结构从使用
text
属性更改为使用label
属性,保持了与库中其他Picker实现的一致性。这种统一的API设计有助于提高开发体验和代码可维护性。
63-63
: 更新onConfirm回调中的属性访问从
option.text
更改为option.label
,与新的选项结构保持一致。
67-70
: 增强onChange处理函数的类型安全性和可读性使用
PickerOnChangeCallbackParameter
类型和解构selectedOptions
参数,使代码更加类型安全和易于理解。使用可选链操作符和类型断言增强了代码的健壮性。src/packages/popover/demos/taro/demo4-1.tsx (4)
3-9
: 优化导入结构并引入类型声明将导入语句组织为一个块导入,并添加了
PickerOnChangeCallbackParameter
类型导入,提高了代码的一致性和类型安全性。
19-29
: 统一Picker选项的数据结构将选项结构从使用
text
属性更改为使用label
属性,与其他Picker组件保持一致。这种统一的API设计有助于降低学习成本并提高代码可维护性。
67-67
: 更新onConfirm回调中的属性引用将
option.text
更改为option.label
,与新的选项结构保持一致。
71-74
: 提高onChange处理函数的类型安全性和可读性使用
PickerOnChangeCallbackParameter
类型和解构语法替代之前直接使用数组类型的方式,提高了代码的类型安全性和可读性。使用可选链操作符和类型断言增强了代码的健壮性。src/packages/picker/index.ts (1)
3-3
: 类型导入路径更新将
PickerProps
类型的导入路径从 './picker' 改为 './types',提高了代码组织性,使类型定义更加集中和规范。src/packages/picker/index.taro.ts (1)
3-3
: 类型导入路径更新将
PickerProps
类型的导入路径从 './picker.taro' 改为 './types.taro',与非 Taro 版本保持一致的类型管理方式,增强了代码结构的一致性。src/packages/picker/types.taro.ts (1)
1-8
: Taro 平台的 PickerProps 类型定义新增的 Taro 平台特定类型定义文件,通过继承 Web 版本的 PickerProps 并重新定义 popupProps,解决了平台特定属性的差异。使用 TypeScript 的 Omit 和 Partial 类型工具有效地定制了组件属性。
特别注意:确保
popupProps
的类型定义与 Taro 平台的 Popup 组件行为保持一致,避免在运行时出现属性类型不匹配的问题。src/packages/picker/types.ts (1)
1-9
: 类型导入和依赖导入了必要的类型定义,包括 PopupProps、BasicComponent 以及 PickerView 相关类型。组件类型拆分和重用的方式符合最佳实践。
src/packages/picker/picker.taro.tsx (5)
17-17
: 在 Taro 环境下引入 Popup 组件的优化做法
此处导入Popup
的写法看上去与其他 Taro 组件一致,不存在功能或兼容性问题。
22-22
: 使用 ComponentDefaults 统一管理默认属性
导入ComponentDefaults
有助于在此组件内复用全局默认属性,避免重复定义。
24-24
: 从单独文件引入 PickerProps 更具可维护性
将PickerProps
独立到./types.taro
文件,有利于解耦与统一管理属性类型。
143-147
: TS 类型注释能提高点击事件的可读性和安全性
通过声明(e: { stopPropagation: () => void })
明确事件对象结构,能减少潜在的类型错误并提升开发体验。
153-157
: 同理为确认按钮添加类型注释
与取消按钮的做法一致,这里的类型注释可确保事件处理逻辑更安全、易读。src/packages/picker/picker.tsx (3)
16-16
: 引入 Popup 以提供基础弹窗功能
此处使用@/packages/popup/index
保持了与非 Taro 版本组件的结构一致性,便于在 Web 环境中统一管理弹窗交互。
21-21
: 在组件中应用全局默认属性
从@/utils/typings
中导入的ComponentDefaults
同样适用于此文件,强化了全局一致性。
22-22
: 扩展自定义类型并导出至其他组件
{ PickerActions, PickerProps, PickerRef }
的集中导入,为组件之间的类型共享提供了便利,有助于可维护性。src/packages/datepicker/types.taro.ts (1)
1-18
: 类型定义看起来很清晰这个新的
DatePickerProps
类型定义通过 Omit 和 Partial 的组合使用,有效地控制了可以通过pickerProps
传递的属性。这种方法可以确保某些特定的属性(如defaultValue
、value
等)不会被意外覆盖,同时保持类型安全。这种类型定义的设计模式使得组件间的属性传递更加安全和可控。
src/packages/datepicker/demos/taro/demo8.tsx (4)
16-16
: 时间格式更新默认描述字符串现在包含了固定的时间 "06:00",与下面状态变量的更新保持一致。
18-22
: 状态描述格式优化desc 状态变量的初始化已更改为使用中文字符(年、月、日、时)作为格式,使显示更加本地化和用户友好。
33-51
: 函数重命名保持一致性
formatter
函数(之前可能命名为formatter1
)保持了相同的逻辑,但名称更具描述性,与组件 API 保持一致。
55-55
: 标题更新符合功能变化Cell 组件的标题从"选择时分秒"更新为"选择年月日时",更准确地反映了当前 demo 的功能,与
type="datehour"
保持一致。src/packages/datepicker/__test__/datepicker.spec.tsx (1)
4-4
:✅ Verification successful
导入方式变更
DatePicker 的导入方式从命名导入更改为默认导入,这表明 DatePicker 组件的导出方式在其源文件中已更改。请确保此更改与
datepicker.ts
文件中的导出方式一致。如果
datepicker.ts
文件中的导出语法已相应更新为默认导出,那么这个更改是正确的。
🏁 Script executed:
#!/bin/bash # 检查 DatePicker 组件的导出方式 echo "检查 DatePicker 的导出方式:" grep -A 5 "export " src/packages/datepicker/datepicker.tsxLength of output: 137
结果确认:DatePicker 导出方式正确
经过验证,
src/packages/datepicker/datepicker.tsx
中确实使用了export default DatePicker
进行导出,因此在src/packages/datepicker/__test__/datepicker.spec.tsx
中使用默认导入方式(即import DatePicker from '../datepicker'
)是正确的。不需要做任何修改。src/packages/datepicker/doc.taro.md (1)
102-102
:✅ Verification successful
API 文档更新
filter 属性的类型签名已更新,从处理单个选项 (option: PickerOption) 改为处理选项数组 (options: PickerOptions)。这一变化使 API 更加一致,并且与 demo8.tsx 中的实际用法相匹配。
请确保所有相关的文档文件(如 doc.md、doc.en-US.md 等)也进行了相应的更新,以保持文档的一致性。
🏁 Script executed:
#!/bin/bash # 检查其他文档文件中 filter 属性的描述是否一致 echo "检查其他文档文件中的 filter 属性描述:" grep -A 1 "filter" src/packages/datepicker/doc.*.mdLength of output: 1078
已验证:API 文档更新一致,无需额外修改
- 已确认
src/packages/datepicker/doc.en-US.md
、src/packages/datepicker/doc.taro.md
以及src/packages/datepicker/doc.zh-TW.md
中关于filter
属性的签名均更新为(type: string, options: PickerOptions) => PickerOptions
,同时描述均表明通过该函数对选项数组进行过滤,与 demo8.tsx 中的实际使用一致。- 请检查其他相关文档(例如
doc.md
,若存在此文件)是否也保持相同步骤更新以确保全站统一。src/packages/datepicker/demos/taro/demo2.tsx (1)
27-30
: 改进日期选择器的动态范围设置将固定日期改为动态日期是一个很好的改进,这样使得示例代码更实用且与当前日期相关。使用
defaultValue
的年份来设置endDate
保证了开始和结束日期之间有合理的关系。以下几点值得注意:
- 使用当前日期作为
startDate
可以确保用户只能选择今天及以后的日期- 将
endDate
设置为当年的 7 月 1 日提供了一个合理的日期范围- 使用已定义的
defaultValue
变量保持了代码的一致性src/packages/datepicker/doc.zh-TW.md (1)
102-102
: 更新了过滤函数的类型签名,提高了一致性
filter
属性的类型签名从处理单个选项(type: string, option: PickerOption) => PickerOption[]
更改为处理选项集合(type: string, options: PickerOptions) => PickerOptions
,这是一个重要的 API 变更。此更改表明
filter
函数现在可以一次性处理和返回整个选项集合,而不是单个选项,这提高了组件的灵活性和功能性。确保在使用此组件时更新相应的回调函数实现。请检查文档中的所有示例代码是否已更新以匹配此 API 变更,特别是
demo8.tsx
中的过滤选项示例。src/packages/datepicker/demos/h5/demo2.tsx (1)
29-31
: 改进日期选择器的动态范围设置与 Taro 版本一致,H5 版本的示例也采用了动态日期设置,这是一个良好的实践。此更改使得示例更加实用,并确保在任何时间查看时都具有相关性。
代码中值得注意的几点:
- 动态设置
startDate
为当前日期,确保选择范围始终是最新的- 将
endDate
限制为当年的 7 月 1 日,提供了更实际的日期范围展示- 使用预先定义的
defaultValue
变量增强了代码的可读性和一致性src/packages/datepicker/doc.md (1)
102-102
:✅ Verification successful
更新了过滤函数的类型签名,增强了处理能力
filter
属性的类型签名从(type: string, option: PickerOption) => PickerOption[]
更改为(type: string, options: PickerOptions) => PickerOptions
,这是一个重要的 API 变更。这一变更提高了
filter
函数的能力,现在它可以批量处理选项集合,而不是单独处理每个选项,可能会带来更高的性能和更灵活的过滤逻辑实现。请确保更新所有使用此组件的代码,特别是自定义过滤函数的实现。需要确认这一变更是否与其他相关文档(如 API 参考、示例代码等)保持一致,特别是 demo8.tsx 中的过滤选项示例是否已适配新的 API。
🏁 Script executed:
#!/bin/bash # 检查相关示例代码中的 filter 函数实现 grep -r "filter" --include="*.tsx" src/packages/datepicker/demosLength of output: 642
确认 API 签名更新 – 示例代码验证通过
经过验证,
src/packages/datepicker/demos/taro/demo8.tsx
和src/packages/datepicker/demos/h5/demo8.tsx
中的filter
函数均已更新为新签名(type: string, options: PickerOptions) => PickerOptions
,此变更已正确反映在示例代码中。请确保所有其他使用该组件的代码同步更新此 API 变更。src/packages/datepicker/doc.en-US.md (1)
92-92
: 类型签名更改更加符合实际用例
filter
属性类型已从处理单个选项更新为处理选项集合,这种变更更加符合实际使用场景。在日期选择器中,过滤通常应用于一组选项而非单个选项。- | filter | Option filter | `(type: string, option: PickerOption) => PickerOption[]` | `-` | + | filter | Option filter | `(type: string, options: PickerOptions) => PickerOptions` | `-` |src/packages/form/demos/taro/demo7.tsx (2)
15-15
: 引入新组件正确导入了 DatePicker 组件,与其他表单组件导入保持一致。
121-153
: DatePicker 表单项实现良好Form.Item 结合 DatePicker 组件的实现遵循了与现有 Picker 相同的模式,保持了 API 设计的一致性。getValueFromEvent 函数正确处理了日期转换,而 onClick 处理程序恰当地打开了日期选择器。Cell 组件的渲染也处理了有值和无值的两种情况。
src/packages/datepickerview/types.ts (2)
1-7
: 导入依赖项定义清晰从 utils/typings 和 pickerview/types 正确导入了所需的类型定义,为新组件提供了必要的基础类型支持。
24-25
: 确保格式化和过滤函数的一致性注意到
formatter
函数接收单个option
参数,而filter
函数接收options
集合参数。确保这种设计是有意的,并与 DatePicker 组件中相应的参数类型保持一致。src/packages/datepicker/index.ts (1)
1-3
:❓ Verification inconclusive
重构模块导入导出方式
DatePicker 组件的导入方式从命名导入更改为默认导入,同时 DatePickerProps 类型的导出源从 './datepicker' 更改为 './types'。这种重构改进了代码组织,将类型定义分离到专门的类型文件中。
确保这一变更已在所有引用 DatePicker 和 DatePickerProps 的地方进行了同步更新,以避免潜在的导入错误。
🏁 Script executed:
#!/bin/bash # 检查是否有任何地方仍在使用旧的导入方式 rg "import.*DatePicker.*from.*'@nutui/nutui.*datepicker'" --type tsx --type tsLength of output: 114
请注意更新所有引用 DatePicker 和 DatePickerProps 的地方
文件
src/packages/datepicker/index.ts
的修改内容:
- 将 DatePicker 组件的导入方式从命名导入更改为默认导入
- 将 DatePickerProps 类型的导出源从
'./datepicker'
更改为'./types'
请确保整个代码库中所有引用 DatePicker 及 DatePickerProps 的地方也同步做了相应调整,以免因导入方式不一致而导致运行错误。
附加说明:原有的 ripgrep 命令在检查
.tsx
文件中旧的导入方式时出现了 “unrecognized file type: tsx” 错误。建议使用下面的新命令进行验证:rg "import.*DatePicker.*from.*'@nutui/nutui.*datepicker'" -g "*.ts" -g "*.tsx"src/packages/form/demos/h5/demo7.tsx (1)
15-15
: 导入新组件以增强表单功能导入DatePicker组件以扩展表单的日期选择能力,与现有表单组件保持一致。
src/packages/picker/__tests__/picker.spec.tsx (2)
5-5
: 引入PickerOptions类型增强类型系统引入PickerOptions类型是一个好的改进,这为组件间共享类型定义提供了基础。
17-17
: 类型更新提高了灵活性将PickerOption接口中的children类型从
PickerOption[]
更新为PickerOptions
增加了类型系统的灵活性和一致性。这种变更有助于统一多级选择器的类型定义。src/packages/datepicker/demos/taro/demo1.tsx (2)
10-21
: 良好的代码重构,提取了日期处理逻辑将日期处理逻辑提取到
useDatePicker
自定义钩子中是一个很好的做法,增强了代码的可重用性和可维护性。
37-52
: 硬编码的特定日期条件需要重新考虑
handleConfirm
函数中包含了一个特定日期条件检查:isEqual(values, ['2026', '02', '21'])
,这看起来像是硬编码的测试条件。在生产代码中应避免此类硬编码条件,除非有明确的业务需求。这个特定日期条件是否有特殊的业务意义?如果是为了测试或示例目的,建议添加注释说明,或者考虑使用更通用的逻辑。
if (setValue) { - if (isEqual(values, ['2026', '02', '21'])) { - setValue('2026/03/22') - setDesc('2026年03月22日') - } else { setValue(values.join('/')) setDesc(options.map((option) => option.label).join('')) - } } else {src/packages/datepicker/demos/h5/demo1.tsx (3)
10-21
: 自定义 Hook 提高了代码复用性创建了
useDatePicker
自定义 Hook 来抽象日期对象处理逻辑,这是一个很好的实践,能够简化组件代码并提高复用性。
24-36
: 默认日期初始化逻辑优化使用自定义 Hook 替代内联的日期处理逻辑,代码结构更加清晰。
66-70
: 使用新的处理函数简化了组件配置使用
handleConfirm
函数替代原来的回调处理,简化了组件配置并保持了一致性。src/packages/datepickerview/__test__/datepickerview.spec.tsx (3)
7-20
: 中文显示测试用例正确测试了
showChinese
属性是否正常工作,确保年份标签显示正确。
116-130
: 时间步进设置测试验证了
minuteStep
属性正确限制了分钟选项的数量,测试逻辑清晰。
132-153
: 时间过滤功能测试测试验证了过滤功能能够正确过滤小时选项。使用了模拟函数来实现过滤逻辑,测试方法得当。
src/config.json (2)
226-236
: 代码格式优化Col 组件的配置格式已优化,提高了代码的一致性和可读性。
644-656
: 新增 DatePickerView 组件配置新增了 DatePickerView 组件的配置,完善了数据录入类组件体系。配置项定义清晰,包含了版本、名称、类型、中文名等必要信息。
src/packages/datepicker/demos/h5/demo8.tsx (5)
16-16
: 默认时间调整将默认时间从 "00:00" 修改为 "06:00",更符合实际使用场景。
18-22
: 改进了日期描述格式使用中文年月日时格式,增强了本地化显示效果,提高了用户体验。
33-33
: 函数命名优化将
formatter1
重命名为formatter
,使函数名更具描述性和一致性。
55-55
: 更新了单元格标题将标题从"选择时分秒"更新为"选择年月日时",更准确地反映了日期选择器的实际功能。
66-66
: 更新格式化函数引用更新了 DatePicker 组件的 formatter 属性以使用重命名后的函数,保持了代码一致性。
src/packages/datepickerview/demos/h5/demo1.tsx (4)
1-10
: 导入依赖合理,使用方式规范。
引入了DatePickerView
、CellGroup
等组件以及react-fast-compare
库,整体符合 React 及 NutUI 的使用规范。
55-63
: 非受控用法示例清晰,适合快速上手。
使用defaultValue
与onChange
搭配展示,示例简单易懂,无明显问题。
65-74
: 受控用法演示得当,且使用useState
来同步更新。
当开发者需要手动控制值的改变和展示时,这种用法是非常直观的示例。
79-79
: 默认导出组件符合通用的组件导出惯例。
若项目无特殊要求,此方式可无缝地被其他模块或路由引入。src/packages/datepickerview/demos/taro/demo1.tsx (5)
1-10
: 与 H5 版本保持一致的导入和依赖结构。
强调了 Taro 版组件的差异性通过包名区分,结构清晰。
11-21
: 自定义 Hook 提供相同的默认日期与格式化逻辑。
解决多端复用层面的日期初始化需求,避免重复代码。若后续需要更多功能,可考虑封装进一步的配置选项。
55-63
: 非受控示例与 H5 版本示例一致,无明显问题。
代码结构统一、便于跨端理解和对比。
65-74
: 受控示例同样设计合理,调用方式简明。
兼容 Taro 环境的使用场景,示例易读无不当之处。
79-79
: 默认导出符合多端组件常用模式。
能直接被其他页面或组件引用,降低二次封装的难度。src/packages/datepicker/types.ts (2)
1-3
: 类型导入结构良好。
对BasicComponent
、PickerProps
、PickerOptions
、PickerValue
等类型的引用清晰可控,避免了冗余。
5-9
: 定义DatePickerRef
及其对应功能方法,接口设计简洁易用。
open
、close
方法命名直观,可与外层业务流程自然衔接。src/packages/datepickerview/datepickerview.tsx (2)
5-8
: 基于PickerView
进行二次封装,合理利用其导出的类型与基础功能。
对上层进行日期特化,满足多种日期场景需求,无不当之处。
153-163
: 检测 selectedDate 改变时的 useEffect 未在测试中覆盖。
可在测试用例中模拟 selectedDate 发生变化并断言相关行为,确保组件在日期变化时能正确触发副作用。🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 161-162: src/packages/datepickerview/datepickerview.tsx#L161-L162
Added lines #L161 - L162 were not covered by testssrc/packages/datepicker/datepicker.tsx (1)
98-102
: 为以下行添加单元测试以提升覆盖率。
静态分析工具指出第 98-99 行、101-102 行、133 行以及 139-141 行缺少测试覆盖。建议编写相应用例,以确保对开启、关闭、确认逻辑以及isEqual
比较逻辑的正确性进行验证。Also applies to: 133-133, 139-141
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 98-99: src/packages/datepicker/datepicker.tsx#L98-L99
Added lines #L98 - L99 were not covered by tests
[warning] 101-102: src/packages/datepicker/datepicker.tsx#L101-L102
Added lines #L101 - L102 were not covered by testssrc/packages/datepicker/datepicker.taro.tsx (1)
98-105
: 为 Taro 版本的打开/关闭逻辑和取消操作添加测试。
在actions
中的open
与close
方法(行 99-104)以及handleCancel
(行 140-143)尚未看到相应的测试验证。可考虑补充测试用例,确保 Taro 环境下的显示与隐藏逻辑正确无误。Also applies to: 140-144
src/packages/datepicker/utils.ts (3)
243-244
: 考虑为未覆盖的代码路径添加测试静态分析显示这部分代码没有被测试覆盖。当
value
为null
或不是有效日期时,代码将使用startDate
作为默认值。建议添加测试用例来覆盖这种情况。可以添加如下测试用例:
test('formatValue应当在值为null或无效时使用startDate', () => { const startDate = new Date(2023, 0, 1); const endDate = new Date(2023, 11, 31); // 测试null值 expect(formatValue(null, startDate, endDate)).toBe(startDate.getTime()); // 测试无效日期 const invalidDate = new Date('invalid'); expect(formatValue(invalidDate, startDate, endDate)).toBe(startDate.getTime()); });🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 243-244: src/packages/datepicker/utils.ts#L243-L244
Added lines #L243 - L244 were not covered by tests
283-288
: 特殊日期格式处理的测试覆盖静态分析表明,处理"month-day"和"year-month"格式的代码分支未被测试覆盖。这些分支处理日期格式的特殊情况,确保正确的日期构造。建议添加相应的测试用例。
可以为这些特殊格式添加测试:
test('handlePickerValueChange应正确处理month-day格式', () => { // 模拟month-day格式的选择 const selectedOptions = [...]; const selectedValue = ['05', '15']; // 5月15日 const defaultDate = new Date(2023, 0, 1); let resultDate = null; const handleDateComparison = (date) => { resultDate = date; }; handlePickerValueChange( selectedOptions, selectedValue, 0, 'month-day', defaultDate, handleDateComparison ); // 验证年份是否正确使用了defaultDate的年份 expect(resultDate.getFullYear()).toBe(2023); expect(resultDate.getMonth()).toBe(4); // 5月 expect(resultDate.getDate()).toBe(15); }); // 同样可以添加year-month格式的测试🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 283-284: src/packages/datepicker/utils.ts#L283-L284
Added lines #L283 - L284 were not covered by tests
[warning] 287-288: src/packages/datepicker/utils.ts#L287-L288
Added lines #L287 - L288 were not covered by tests
1-337
: 总体代码质量评价代码整体结构清晰,函数命名规范,注释详尽,职责划分明确。大多数函数都有完整的JSDoc注释,这对于维护和使用非常有帮助。这些实用函数很好地封装了日期选择和处理的复杂逻辑,提高了组件的可复用性和可维护性。
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 115-115: src/packages/datepicker/utils.ts#L115
Added line #L115 was not covered by tests
[warning] 147-147: src/packages/datepicker/utils.ts#L147
Added line #L147 was not covered by tests
[warning] 243-244: src/packages/datepicker/utils.ts#L243-L244
Added lines #L243 - L244 were not covered by tests
[warning] 283-284: src/packages/datepicker/utils.ts#L283-L284
Added lines #L283 - L284 were not covered by tests
[warning] 287-288: src/packages/datepicker/utils.ts#L287-L288
Added lines #L287 - L288 were not covered by tests
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: 0
🧹 Nitpick comments (1)
src/packages/datepickerview/doc.md (1)
31-48
: 标题命名建议调整
Props 部分当前标题为“## DatePicker”,建议修改为“## DatePickerView”以确保文档中组件名称的一致性,避免造成混淆。以下是建议的 diff 修正:
-## DatePicker +## DatePickerView此外,Props 表格整体说明详尽,每个属性的描述、类型以及默认值均已明确,文档格式符合 Markdown 规范。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/config.json
(2 hunks)src/packages/datepickerview/doc.en-US.md
(1 hunks)src/packages/datepickerview/doc.md
(1 hunks)src/packages/datepickerview/doc.taro.md
(1 hunks)src/packages/datepickerview/doc.zh-TW.md
(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- src/packages/datepickerview/doc.taro.md
- src/packages/datepickerview/doc.zh-TW.md
- src/packages/datepickerview/doc.en-US.md
🚧 Files skipped from review as they are similar to previous changes (1)
- src/config.json
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: test
🔇 Additional comments (4)
src/packages/datepickerview/doc.md (4)
1-4
: 整体介绍清晰
文件开头的标题“DatePickerView 日期选择器视图”以及简短描述“时间选择器,支持日期、年月、时分等维度。”较好地传达了组件的基本功能。建议若后续有更多细节(例如支持的特定用例或限制)可在后续版本中补充说明。
5-10
: 引入部分语法正确
“引入”部分使用了 TypeScript 代码块展示了如何导入组件,写法简洁清晰,路径正确且易于理解。
11-20
: 示例代码部分——选择日期
示例代码通过 demo 块展示了如何使用组件,能够快速帮助用户理解基本用法。代码块及 demo 语法正确,建议保留现有结构。
21-29
: 示例代码部分——选择月日
说明文字详细解释了如何通过 type 属性控制日期类型的选择,demo 块使用得当。可以考虑在后续版本中增加其它类型的示例以覆盖更多场景,但当前版本已具备基本说明。
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 (4)
src/packages/datepickerview/datepickerview.tsx (1)
168-180
: 条件渲染合理,但可补充空数组或空值时的兜底逻辑。使用
pickerOptions.length && <PickerView ...>
可以避免空数据时渲染 PickerView。但若初始化或异常情况下数据为空时,是否需要展示占位或提示用户?可根据业务需求添加相应的处理。src/packages/datepickerview/datepickerview.taro.tsx (1)
169-180
: 有条件地渲染 PickerView,需考虑空数据场景。当
pickerOptions.length
不为 0 时才渲染PickerView
,能有效避免空数组渲染。但若默认选项为空或异步获取导致为空——此时是否需要给用户提示,或展示空态占位?可视业务需求酌情优化。src/packages/datepicker/datepicker.tsx (1)
179-214
: 生成选择器列优化
generatePickerColumns
函数使用工具函数生成日期选择器的列数据,代码结构清晰。但有一点需要注意:在回调函数中直接修改并设置
pickerValue
数组,可能会导致状态更新不可预测。建议使用函数式更新或者创建新数组后再设置状态。建议优化状态更新方式:
- pickerValue[columnIndex] = options[selectedIndex]?.value - setPickerValue([...pickerValue]) + setPickerValue(prevValue => { + const newValue = [...prevValue] + newValue[columnIndex] = options[selectedIndex]?.value + return newValue + })src/packages/datepicker/datepicker.taro.tsx (1)
227-247
: Taro 特定的渲染实现使用 Taro 的
View
组件替代标准 HTML 的div
,并使用字符串连接方式添加类名,而不是使用cls
变量。建议统一使用前面定义的cls
变量来保持代码一致性。为了保持代码风格一致性,建议使用前面定义的
cls
变量:- <View className={`nut-datepicker ${className}`} style={style} {...rest}> + <View className={cls} style={style} {...rest}>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
src/packages/calendar/demos/h5/demo6.tsx
(2 hunks)src/packages/calendar/demos/taro/demo6.tsx
(2 hunks)src/packages/datepicker/datepicker.taro.tsx
(5 hunks)src/packages/datepicker/datepicker.tsx
(5 hunks)src/packages/datepicker/index.taro.ts
(1 hunks)src/packages/datepickerview/datepickerview.taro.tsx
(1 hunks)src/packages/datepickerview/datepickerview.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/packages/datepicker/index.taro.ts
🔇 Additional comments (33)
src/packages/calendar/demos/h5/demo6.tsx (2)
2-9
: 已引入更明确的类型定义,增强类型安全。引入
PickerValue
与PickerOptions
后,可以更好地约束时间/日期选择的参数类型。当前改动符合类型安全需求,并与后续逻辑搭配合理。
42-47
: 确认函数入参类型更新,注意与组件调用保持一致。
confirm
函数的参数从原本的(string | number)[]
、any[]
更改为PickerValue[]
、PickerOptions
,对齐了新类型定义,逻辑更加清晰。但是建议在调用端也检查一下,以确保调用方传入的类型与这里定义的参数保持一致,避免后期出现类型不匹配问题。src/packages/calendar/demos/taro/demo6.tsx (2)
7-8
: 类型引入与 H5 版本对齐,增加一致性。
PickerValue
和PickerOptions
的导入与 H5 版本保持一致,利于跨端维护和代码阅读性。
38-50
: 更新 confirm 函数参数类型,确保跨端一致性。对
confirm
函数的参数类型做了与 H5 端一致的更新,并将选项处理切换至option.label
,能够更直观地处理选择结果。建议在实际使用中验证是否存在对旧类型的依赖,以及在业务逻辑中是否有相应的兼容处理。src/packages/datepickerview/datepickerview.tsx (2)
24-32
: 默认属性范围合理,但需注意日期区间有效性。使用当前年份前后 10 年设置
startDate
和endDate
通常足够通用,但实际业务场景中需确保日期区间能满足需求,同时避免过大区间产生性能开销。
79-98
: 对比日期并触发 onChange 回调的实现合理。
handleDateComparison
核心逻辑是判断日期是否变化,不再重复调用 setState,同时适时调用onChange
。实现思路清晰。但要注意:在高频率场景(如快速滑动)下,尽量避免多次重复渲染,可在调优时关注性能瓶颈。src/packages/datepickerview/datepickerview.taro.tsx (2)
25-33
: 默认属性可满足通用需求,建议结合业务场景调整。与 Web 版本相同的默认属性设置(前后 10 年区间)非常通用,但仍需根据具体项目需求评估是否需要减少或扩大区间,避免用户滚动过量日期选项。
80-99
: 比较并触发 onChange 的逻辑实现清晰。方法
handleDateComparison
先判断日期合法性并使用isDate
校验,再比较新旧值并调用onChange
传出。用途明确,可读性高。src/packages/datepicker/datepicker.tsx (16)
1-6
: 导入依赖项更新组件从普通函数组件变更为使用
ForwardRefRenderFunction
和useImperativeHandle
,这是一个很好的改进,现在组件可以通过 ref 暴露方法,增强了与父组件的交互能力。
20-23
: 导入工具函数和类型优化从
./utils
导入的工具函数使代码更加模块化,提高了可维护性。将类型定义分离到./types
文件中也是一个良好的实践,这样便于类型的复用和管理。
38-41
: 组件定义方式优化使用
ForwardRefRenderFunction
类型定义内部组件,并指定DatePickerRef
作为 ref 类型,Partial<DatePickerProps>
作为 props 类型,使得类型更加明确和安全。
61-62
: 添加 children 属性支持新增了对 children 属性的支持,使组件更加灵活,可以通过函数子组件方式传递和使用选中的日期。
80-82
: 类名定义和样式优化将类名前缀定义为常量并使用
classNames
工具函数来处理类名,这样使得类名管理更加清晰和灵活。
86-91
: 状态管理优化使用
usePropsValue
钩子管理受控组件的值,并在格式化值时传入startDate
和endDate
参数。这种方式更加符合 React 的数据流模式,使组件既可以作为受控组件也可以作为非受控组件使用。
93-94
: 内部日期状态管理新增
innerDate
状态用于内部处理,与selectedDate
分离,使状态管理更加清晰。当用户在选择过程中,修改的是innerDate
,只有确认后才会更新selectedDate
。
95-99
: 可见性状态管理优化使用
usePropsValue
钩子管理组件的可见性状态,使组件可以受控也可以非受控。
101-110
: 暴露命令式方法通过
actions
对象和useImperativeHandle
钩子,暴露了open
和close
方法给父组件使用,使组件更加灵活,能够通过 ref 直接控制。
112-131
: 日期比较处理逻辑优化
handleDateComparison
函数现在正确地比较新日期与当前选择的日期,并只在必要时更新innerDate
,避免不必要的重渲染。需要确保时间戳比较是准确的,考虑到不同时区可能存在的影响。确保在不同时区下日期比较的准确性,特别是当应用部署在国际环境中时。
133-139
: 确认日期比较逻辑
handleConfirmDateComparison
函数只在确认操作时更新selectedDate
,这符合典型的日期选择器交互模式,用户可以在最终确认前预览选择。
141-149
: 取消和关闭操作处理取消操作时将
innerDate
重置为selectedDate
,关闭时设置innerVisible
为 false,这些处理都符合日期选择器的预期行为。
151-177
: 确认和变更事件处理通过
handleConfirm
和handleChange
函数处理确认和变更事件,使用条件判断innerVisible &&
确保只在选择器可见时处理变更事件,这是一个很好的优化。但是,当
innerVisible
为 false 时,handleChange
函数不会执行,这可能会导致在某些特殊情况下(如通过程序设置值)无法正确触发变更事件,请确认这是否符合预期。确认在选择器不可见时是否需要处理变更事件的情况。
216-224
: Effect 钩子依赖优化Effect 钩子的依赖数组包含了所有必要的依赖项,确保状态更新和副作用执行的一致性。
225-246
: 渲染逻辑优化渲染逻辑增加了对函数子组件的支持,并且条件渲染 Picker 组件,确保只有当
pickerOptions
有长度时才渲染,这是一个很好的优化。使用 Fragment (<>
) 包裹多个元素也是符合 React 的最佳实践。
249-252
: 组件导出方式更新使用
React.forwardRef
包装InternalPicker
并默认导出,符合 React 的最佳实践,使组件能够接收和处理 ref。src/packages/datepicker/datepicker.taro.tsx (9)
1-6
: 导入依赖项更新与标准版本相同,Taro 版本的组件也从普通函数组件变更为使用
ForwardRefRenderFunction
和useImperativeHandle
,提高了组件的灵活性和交互能力。
22-24
: 类型导入优化从 Taro 特定的类型文件导入
DatePickerProps
,同时从通用类型文件导入DatePickerActions
和DatePickerRef
,这种区分方式有助于管理平台特定的差异。
40-43
: 组件定义方式统一Taro 版本的组件定义方式与标准版本保持一致,使用
ForwardRefRenderFunction
类型定义内部组件,保证了代码风格和接口的一致性。
63-64
: 添加 children 属性支持与标准版本一致,Taro 版本也添加了对 children 属性的支持,保持了两个平台实现的一致性。
82-84
: 类名定义和样式优化与标准版本相同的类名处理方式,使用
classNames
工具函数处理类名,保持了一致的风格。
88-93
: 状态管理优化使用
usePropsValue
钩子管理受控组件的值,与标准版本保持一致,确保了跨平台的行为一致性。
97-101
: 可见性状态管理一致性与标准版本一致的可见性状态管理,确保 Taro 版本的行为与标准版本相同。
103-112
: 暴露命令式方法通过相同的机制暴露
open
和close
方法,保持了 API 的一致性。
251-254
: 组件导出方式统一与标准版本一致的导出方式,使用
React.forwardRef
包装InternalPicker
并默认导出。
if ( | ||
!isEqual( | ||
new Date(selectedDate)?.getTime(), | ||
new Date(selectedDate)?.getTime() | ||
) | ||
) { | ||
setSelectedDate(selectedDate) | ||
} | ||
}, [selectedDate]) | ||
|
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.
逻辑判断恒为 false,可能导致状态无法更新。
在此处使用 !isEqual(new Date(selectedDate)?.getTime(), new Date(selectedDate)?.getTime())
比较的是同一个表达式,结果一定是 false
。若本意是对比新旧日期,请确保传入两个不同的值,例如保存旧值或传入下一次更新的时间,以正确触发后续流程。
- if (!isEqual(new Date(selectedDate)?.getTime(), new Date(selectedDate)?.getTime())) {
+ // 示例:假设需要对比 prevSelectedDate 和当前 selectedDate
+ if (!isEqual(prevSelectedDate?.getTime(), new Date(selectedDate)?.getTime())) {
Committable suggestion skipped: line range outside the PR's diff.
useEffect(() => { | ||
if ( | ||
!isEqual( | ||
new Date(selectedDate)?.getTime(), | ||
new Date(selectedDate)?.getTime() | ||
) | ||
) { | ||
setSelectedDate(selectedDate) | ||
} | ||
}, [selectedDate]) |
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.
比较同一表达式将导致判断永远为 false。
!isEqual(new Date(selectedDate)?.getTime(), new Date(selectedDate)?.getTime())
比较了相同的时间值。若期望对比更新前与更新后的值,需保持两个不同的引用或记录上一次的数值,否则无法触发更新逻辑。
- if (!isEqual(new Date(selectedDate)?.getTime(), new Date(selectedDate)?.getTime())) {
+ // 请确保此处对比新旧值一致
+ if (!isEqual(prevSelectedDate?.getTime(), new Date(selectedDate)?.getTime())) {
Committable suggestion skipped: line range outside the PR's diff.
src/config.json
Outdated
"name": "数据录入", | ||
"enName": "dataentry", | ||
"packages": [ | ||
{ |
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.
可以放在 datepicker 后边~ 如果分包超过大小时,可以把上边的最后一个移到这里-dateentry 下~
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.
可以放在 datepicker 后边~ 如果分包超过大小时,可以把上边的最后一个移到这里-dateentry 下~
已修改
} | ||
|
||
const classPrefix = 'nut-datepicker' | ||
const cls = classNames(classPrefix, className) |
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.
cls 没有用到~
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.
cls 没有用到~
已修改
src/packages/datepickerview/demo.tsx
Outdated
basic: '选择日期', | ||
mmdd: '选择月日', | ||
showAll: '选择年月日时分', | ||
time: '选择时分秒', |
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.
后边用不到的可以删掉~
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.
后边用不到的可以删掉~
已修改
src/packages/datepickerview/demo.tsx
Outdated
<Demo1 /> | ||
<h2>{translated.mmdd}</h2> | ||
<Demo2 /> | ||
<h2>{translated.showAll}</h2> |
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.
这里没有demo,可以删掉~
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.
这里没有demo,可以删掉~
已修改
<Cell title="显示中文-非受控" description={desc1} /> | ||
<Cell> | ||
<DatePickerView | ||
defaultValue={new Date(defaultValue1)} |
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.
demo的数据类型有不一致的情况~
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.
demo的数据类型有不一致的情况~
已修改
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
♻️ Duplicate comments (1)
src/packages/datepickerview/datepickerview.tsx (1)
153-162
:⚠️ Potential issue修复无效的日期比较逻辑
这段代码存在逻辑问题,当前的条件
!isEqual(new Date(selectedDate)?.getTime(), new Date(selectedDate)?.getTime())
比较的是同一个表达式,结果总是false
,导致setSelectedDate(selectedDate)
永远不会执行。useEffect(() => { - if ( - !isEqual( - new Date(selectedDate)?.getTime(), - new Date(selectedDate)?.getTime() - ) - ) { - setSelectedDate(selectedDate) - } + // 如果需要在 selectedDate 变化时执行某些操作,可以直接在此处理 + // 例如:可以在此同步更新其他状态或执行副作用 }, [selectedDate])如果需要保留对 selectedDate 的检查和处理,建议使用 useRef 跟踪先前的值并进行比较:
+ const prevSelectedDateRef = useRef<number>(0); + useEffect(() => { + // 只有当日期实际发生变化时才更新 + if (prevSelectedDateRef.current !== selectedDate) { + // 执行必要的更新操作 + prevSelectedDateRef.current = selectedDate; + } - if ( - !isEqual( - new Date(selectedDate)?.getTime(), - new Date(selectedDate)?.getTime() - ) - ) { - setSelectedDate(selectedDate) - } }, [selectedDate])🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 159-160: src/packages/datepickerview/datepickerview.tsx#L159-L160
Added lines #L159 - L160 were not covered by tests
🧹 Nitpick comments (4)
src/packages/datepickerview/demos/h5/demo1.tsx (2)
36-50
: 改进 handleChange 函数的类型安全和可读性handleChange 函数的实现比较复杂,建议进行重构以提高可读性和类型安全性。当前实现中存在以下几个问题:
- 针对特定日期的硬编码处理(
isEqual(value, ['2026', '02', '26'])
)缺乏注释说明其用途- 函数嵌套和条件分支较多,可读性不高
建议进行以下优化:
- const handleChange = - (setDesc: (desc: string) => void, setValue?: (value: string) => void) => - (selectedOptions: PickerOptions, value: PickerValue[]) => { - if (setValue) { - if (isEqual(value, ['2026', '02', '26'])) { - setValue('2026/03/22') - setDesc('2026年03月22日') - } else { - setValue(value.join('/')) - setDesc(selectedOptions.map((option) => option.label).join('')) - } - } else { - setDesc(selectedOptions.map((option) => option.label).join('')) - } - } + // 创建一个处理日期选择变化的高阶函数 + const handleChange = + (setDesc: (desc: string) => void, setValue?: (value: string) => void) => + (selectedOptions: PickerOptions, value: PickerValue[]) => { + // 根据选项生成描述文本 + const newDesc = selectedOptions.map((option) => option.label).join('') + + // 非受控模式下只更新描述 + if (!setValue) { + setDesc(newDesc) + return + } + + // 受控模式下处理特殊情况(演示用例) + if (isEqual(value, ['2026', '02', '26'])) { + // 特殊日期处理:当用户选择2026年2月26日时,自动调整到3月22日 + setValue('2026/03/22') + setDesc('2026年03月22日') + } else { + // 正常情况:更新值和描述 + setValue(value.join('/')) + setDesc(newDesc) + } + }
68-68
: 确保日期格式转换的一致性value 变量是通过
value.join('/')
形成的字符串,传入new Date()
构造函数可能导致不同浏览器或平台有不同的解析结果。建议使用更可靠的日期解析方法:
- value={new Date(value)} + value={new Date(value.split('/')[0], parseInt(value.split('/')[1]) - 1, value.split('/')[2])}或者更好的方式是保持状态为日期对象而非字符串:
- const [value, setValue] = useState(defaultValue2) + const [value, setValue] = useState(new Date(defaultValue2)) - const handleChange = - (setDesc: (desc: string) => void, setValue?: (value: string) => void) => + const handleChange = + (setDesc: (desc: string) => void, setValue?: (value: Date) => void) => (selectedOptions: PickerOptions, value: PickerValue[]) => { if (setValue) { if (isEqual(value, ['2026', '02', '26'])) { - setValue('2026/03/22') + setValue(new Date(2026, 2, 22)) // 注意月份从0开始,3月是2 setDesc('2026年03月22日') } else { - setValue(value.join('/')) + setValue(new Date(parseInt(value[0]), parseInt(value[1]) - 1, parseInt(value[2]))) setDesc(selectedOptions.map((option) => option.label).join('')) } } else { setDesc(selectedOptions.map((option) => option.label).join('')) } }src/packages/datepickerview/datepickerview.tsx (2)
34-36
: 考虑使用 forwardRef 代替 FunctionComponent当前组件使用 FunctionComponent 类型,但考虑到组件库的一致性和复杂表单组件的需求,建议使用 React.forwardRef 转发引用,这样可以使外部组件访问这个组件内部的 DOM 元素。
-export const DatePickerView: FunctionComponent<Partial<DatePickerViewProps>> = ( - props -) => { +export const DatePickerView = React.forwardRef< + HTMLDivElement, + Partial<DatePickerViewProps> & React.HTMLAttributes<HTMLDivElement> +>((props, ref) => {同时更新组件的返回语句:
return ( - <div className={cls} style={style}> + <div className={cls} style={style} ref={ref}> {pickerOptions.length && ( <PickerView
169-178
: 添加空数据处理和加载状态当
pickerOptions.length
为 0 时,组件不渲染任何内容,这可能导致用户体验问题,特别是在数据加载过程中。return ( <div className={cls} style={style}> - {pickerOptions.length && ( + {pickerOptions.length ? ( <PickerView value={pickerValue} options={pickerOptions} onChange={({ selectedOptions, value, index }) => { handleChange(selectedOptions, value, index) }} threeDimensional={threeDimensional} /> + ) : ( + <div className={`${classPrefix}-empty`}> + {/* 可以添加加载指示器或空状态提示 */} + <span>{locale.common?.loading || '加载中...'}</span> + </div> )} </div> )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/packages/datepickerview/datepickerview.taro.tsx
(1 hunks)src/packages/datepickerview/datepickerview.tsx
(1 hunks)src/packages/datepickerview/demos/h5/demo1.tsx
(1 hunks)src/packages/datepickerview/demos/h5/demo2.tsx
(1 hunks)src/packages/datepickerview/demos/taro/demo1.tsx
(1 hunks)src/packages/datepickerview/demos/taro/demo2.tsx
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/packages/datepickerview/demos/h5/demo2.tsx
- src/packages/datepickerview/demos/taro/demo2.tsx
🧰 Additional context used
🪛 GitHub Check: codecov/patch
src/packages/datepickerview/datepickerview.tsx
[warning] 88-95: src/packages/datepickerview/datepickerview.tsx#L88-L95
Added lines #L88 - L95 were not covered by tests
[warning] 159-160: src/packages/datepickerview/datepickerview.tsx#L159-L160
Added lines #L159 - L160 were not covered by tests
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: test
🔇 Additional comments (7)
src/packages/datepickerview/demos/h5/demo1.tsx (1)
58-58
: 修复 defaultValue 数据类型不一致问题传给 DatePickerView 的 defaultValue 属性需要是 Date 类型,但直接使用
new Date(defaultValue1)
将字符串转换为日期对象可能导致浏览器兼容性问题或不一致的解析结果。src/packages/datepickerview/demos/taro/demo1.tsx (3)
36-50
: 改进 handleChange 函数的类型安全和可读性handleChange 函数的实现比较复杂,建议进行重构以提高可读性和类型安全性。当前实现中存在以下几个问题:
- 针对特定日期的硬编码处理(
isEqual(value, ['2026', '02', '26'])
)缺乏注释说明其用途- 函数嵌套和条件分支较多,可读性不高
58-58
: 修复 defaultValue 数据类型不一致问题传给 DatePickerView 的 defaultValue 属性需要是 Date 类型,但直接使用
new Date(defaultValue1)
将字符串转换为日期对象可能导致浏览器兼容性问题或不一致的解析结果。
68-68
: 确保日期格式转换的一致性value 变量是通过
value.join('/')
形成的字符串,传入new Date()
构造函数可能导致不同浏览器或平台有不同的解析结果。src/packages/datepickerview/datepickerview.taro.tsx (3)
35-37
: 考虑使用 forwardRef 代替 FunctionComponent当前组件使用 FunctionComponent 类型,但考虑到组件库的一致性和复杂表单组件的需求,建议使用 React.forwardRef 转发引用。
74-78
: 完善日期格式化逻辑和错误处理当前的日期格式化缺少错误处理,如果
props.value
或defaultValue
是无效日期,可能会导致运行时错误。
153-162
: 修复无效的日期比较逻辑这段代码存在逻辑问题,当前的条件
!isEqual(new Date(selectedDate)?.getTime(), new Date(selectedDate)?.getTime())
比较的是同一个表达式,结果总是false
,导致setSelectedDate(selectedDate)
永远不会执行。
const [selectedDate, setSelectedDate] = usePropsValue<number>({ | ||
value: props.value && formatValue(props.value, startDate, endDate), | ||
defaultValue: defaultValue && formatValue(defaultValue, startDate, endDate), | ||
finalValue: 0, | ||
}) | ||
|
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.
🛠️ Refactor suggestion
完善日期格式化逻辑和错误处理
当前的日期格式化缺少错误处理,如果 props.value
或 defaultValue
是无效日期,可能会导致运行时错误。
const [selectedDate, setSelectedDate] = usePropsValue<number>({
- value: props.value && formatValue(props.value, startDate, endDate),
- defaultValue: defaultValue && formatValue(defaultValue, startDate, endDate),
+ value: props.value && isDate(props.value) ? formatValue(props.value, startDate, endDate) : undefined,
+ defaultValue: defaultValue && isDate(defaultValue) ? formatValue(defaultValue, startDate, endDate) : formatValue(new Date(), startDate, endDate),
finalValue: 0,
})
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const [selectedDate, setSelectedDate] = usePropsValue<number>({ | |
value: props.value && formatValue(props.value, startDate, endDate), | |
defaultValue: defaultValue && formatValue(defaultValue, startDate, endDate), | |
finalValue: 0, | |
}) | |
const [selectedDate, setSelectedDate] = usePropsValue<number>({ | |
value: props.value && isDate(props.value) ? formatValue(props.value, startDate, endDate) : undefined, | |
defaultValue: defaultValue && isDate(defaultValue) ? formatValue(defaultValue, startDate, endDate) : formatValue(new Date(), startDate, endDate), | |
finalValue: 0, | |
}) |
const handleDateComparison = ( | ||
newDate: Date | null, | ||
selectedOptions: PickerOptions, | ||
index: number | ||
) => { | ||
if (newDate && isDate(newDate)) { | ||
if (!isEqual(new Date(selectedDate)?.getTime(), newDate?.getTime())) { | ||
setSelectedDate(formatValue(newDate, startDate, endDate)) | ||
onChange?.( | ||
selectedOptions, | ||
[ | ||
String(newDate.getFullYear()), | ||
padZero(newDate.getMonth() + 1), | ||
padZero(newDate.getDate()), | ||
], | ||
index | ||
) | ||
} | ||
} | ||
} |
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 agent
🧩 Analysis chain
改进 handleDateComparison 函数并添加测试覆盖
该函数是组件的关键部分,但缺少测试覆盖。同时,可以优化日期比较逻辑,使其更清晰。
const handleDateComparison = (
newDate: Date | null,
selectedOptions: PickerOptions,
index: number
) => {
if (newDate && isDate(newDate)) {
- if (!isEqual(new Date(selectedDate)?.getTime(), newDate?.getTime())) {
+ const currentDate = new Date(selectedDate);
+ const isNewDateDifferent =
+ !currentDate ||
+ currentDate.getFullYear() !== newDate.getFullYear() ||
+ currentDate.getMonth() !== newDate.getMonth() ||
+ currentDate.getDate() !== newDate.getDate();
+
+ if (isNewDateDifferent) {
setSelectedDate(formatValue(newDate, startDate, endDate))
onChange?.(
selectedOptions,
[
String(newDate.getFullYear()),
padZero(newDate.getMonth() + 1),
padZero(newDate.getDate()),
],
index
)
}
}
}
建议添加测试用例覆盖此函数的不同场景:
🏁 Script executed:
#!/bin/bash
# 检查 DatePickerView 组件的测试覆盖率
fd "datepickerview.spec" -e tsx --exec cat {}
Length of output: 3720
主题:改进 handleDateComparison 函数及增加单独测试覆盖
- 已更新日期比较逻辑,将原有
isEqual
调用替换为基于年、月、日的明确比较,使得逻辑更清晰易懂。 - 当前测试主要覆盖了整个 DatePickerView 组件的行为,但未单独对
handleDateComparison
函数进行充分测试。建议新增针对该函数的单元测试,覆盖以下场景:selectedDate
为null
或格式无效时的处理;- 比较新日期与当前日期相同时不触发更新;
- 新日期与当前日期不同时正确调用
setSelectedDate
及onChange
。
const handleDateComparison = (
newDate: Date | null,
selectedOptions: PickerOptions,
index: number
) => {
if (newDate && isDate(newDate)) {
- if (!isEqual(new Date(selectedDate)?.getTime(), newDate?.getTime())) {
+ const currentDate = new Date(selectedDate);
+ const isNewDateDifferent =
+ !currentDate ||
+ currentDate.getFullYear() !== newDate.getFullYear() ||
+ currentDate.getMonth() !== newDate.getMonth() ||
+ currentDate.getDate() !== newDate.getDate();
+
+ if (isNewDateDifferent) {
setSelectedDate(formatValue(newDate, startDate, endDate))
onChange?.(
selectedOptions,
[
String(newDate.getFullYear()),
padZero(newDate.getMonth() + 1),
padZero(newDate.getDate()),
],
index
)
}
}
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const handleDateComparison = ( | |
newDate: Date | null, | |
selectedOptions: PickerOptions, | |
index: number | |
) => { | |
if (newDate && isDate(newDate)) { | |
if (!isEqual(new Date(selectedDate)?.getTime(), newDate?.getTime())) { | |
setSelectedDate(formatValue(newDate, startDate, endDate)) | |
onChange?.( | |
selectedOptions, | |
[ | |
String(newDate.getFullYear()), | |
padZero(newDate.getMonth() + 1), | |
padZero(newDate.getDate()), | |
], | |
index | |
) | |
} | |
} | |
} | |
const handleDateComparison = ( | |
newDate: Date | null, | |
selectedOptions: PickerOptions, | |
index: number | |
) => { | |
if (newDate && isDate(newDate)) { | |
const currentDate = new Date(selectedDate); | |
const isNewDateDifferent = | |
!currentDate || | |
currentDate.getFullYear() !== newDate.getFullYear() || | |
currentDate.getMonth() !== newDate.getMonth() || | |
currentDate.getDate() !== newDate.getDate(); | |
if (isNewDateDifferent) { | |
setSelectedDate(formatValue(newDate, startDate, endDate)) | |
onChange?.( | |
selectedOptions, | |
[ | |
String(newDate.getFullYear()), | |
padZero(newDate.getMonth() + 1), | |
padZero(newDate.getDate()), | |
], | |
index | |
) | |
} | |
} | |
} |
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 88-95: src/packages/datepickerview/datepickerview.tsx#L88-L95
Added lines #L88 - L95 were not covered by tests
先review datepicker重构在review这个
Summary by CodeRabbit
New Features
Refactor
Documentation
Tests