-
Notifications
You must be signed in to change notification settings - Fork 2.5k
feat: date-picker 组件优化日期选择器,支持自定义日期字段顺序 #6940
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: master
Are you sure you want to change the base?
feat: date-picker 组件优化日期选择器,支持自定义日期字段顺序 #6940
Conversation
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthrough为 DatePicker 引入可配置列顺序与子集选择:新增 Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor 用户
participant DatePicker
participant Picker
participant Utils as date-picker-utils
participant DUtils as date-picker-date-utils
用户->>DatePicker: 打开/确认 (precision, columns?, tillNow?)
DatePicker->>Picker: 请求 columns 回调(selected, min, max, ..., columns)
Picker->>Utils: generateDatePickerColumns(..., columns)
Utils->>DUtils: 传入 columns -> 按列序/默认序生成候选列
DUtils-->>Utils: 返回列数据(首列可能含 "now")
Utils-->>Picker: 返回列数据
用户->>Picker: 选择值 selected[]
Picker->>Utils: convertStringArrayToDate(selected[], precision, columns)
Utils->>DUtils: 按 columns 构造 Date(缺失列使用当前时间;首列 TILL_NOW 特殊处理)
DUtils-->>Utils: 返回 Date
Utils-->>Picker: 返回 Date
Picker-->>DatePicker: 返回 Date
DatePicker-->>用户: onConfirm(Date)
rect rgba(200,230,201,0.12)
note right of DUtils: 关键变化:支持自定义列序/子集;tillNow 在首列追加“现在”并能清空后续列
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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). (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 |
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.
Summary of Changes
Hello @Passing-of-A-Dream, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
此拉取请求为日期选择器组件引入了一项新功能,允许用户自定义年、月、日字段的显示顺序。这增强了组件的灵活性,使其能够适应不同的日期格式需求,从而提升了用户体验。
Highlights
- 新功能: 为DatePicker和DatePickerView组件新增了fields属性。
- 灵活性: 支持多种fields属性格式,包括数组形式(例如['month', 'day', 'year'])和字符串别名(如'YMD'、'MDY'、'DMY')。
- 核心逻辑: 在date-picker-date-utils.ts中实现了重新排序日期列的核心逻辑。
- 数据处理: 更新了日期转换工具函数(convertDateToStringArray和convertStringArrayToDate),以在自定义字段顺序下仍能正确解析和格式化日期。
- 测试与示例: 新增了演示示例和单元测试,以验证此功能的正确性。
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command>
or @gemini-code-assist <command>
. Below is a summary of the supported commands.
Feature | Command | Description |
---|---|---|
Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/
folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
commit: |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6940 +/- ##
==========================================
+ Coverage 92.90% 92.98% +0.07%
==========================================
Files 336 336
Lines 7334 7357 +23
Branches 1847 1830 -17
==========================================
+ Hits 6814 6841 +27
- Misses 484 508 +24
+ Partials 36 8 -28 ☔ 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.
Code Review
本次 PR 优化了日期选择器,增加了对年、月、日列顺序的自定义支持,这是一个很棒的功能。代码整体实现得不错,并且补充了相应的演示和测试用例。
我发现了一些可以改进的地方,主要集中在 date-picker-date-utils.ts
和 date-picker-utils.ts
文件中。存在一些重复代码和一处潜在的逻辑缺陷。具体的建议请看我的评论。
const safe = (i: number) => (Number.isFinite(i) && i >= 0 ? i : 0) | ||
const yStr = selected[safe(idx.year)] ?? selected[0] | ||
const mStr = selected[safe(idx.month)] ?? selected[1] | ||
const dStr = selected[safe(idx.day)] ?? selected[2] |
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.
这里的 safe
函数和后续的备用逻辑存在缺陷。当 fields
属性不包含某个日期单位时(例如 precision
为 'month'
且 fields
为 ['year']
),idx.month
会是 -1
,safe(-1)
返回 0
。这会导致 mStr
错误地取值为 selected[0]
,也就是年份的值。
为了更正这个逻辑并提高代码的清晰度,建议直接检查索引是否存在,并为 undefined
或未找到的情况提供明确的备用值。同时可以移除不再需要的 safe
函数。
const safe = (i: number) => (Number.isFinite(i) && i >= 0 ? i : 0) | |
const yStr = selected[safe(idx.year)] ?? selected[0] | |
const mStr = selected[safe(idx.month)] ?? selected[1] | |
const dStr = selected[safe(idx.day)] ?? selected[2] | |
const yStr = (idx.year > -1 ? selected[idx.year] : undefined) ?? min.getFullYear().toString() | |
const mStr = (idx.month > -1 ? selected[idx.month] : undefined) ?? '1' | |
const dStr = (idx.day > -1 ? selected[idx.day] : undefined) ?? '1' |
const order: ('year' | 'month' | 'day')[] = (() => { | ||
if (!fields) return ['year', 'month', 'day'] | ||
if (Array.isArray(fields)) return fields | ||
if (fields === 'MDY') return ['month', 'day', 'year'] | ||
if (fields === 'DMY') return ['day', 'month', 'year'] | ||
return ['year', 'month', 'day'] | ||
})() |
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.
const fieldsOrder: ('year' | 'month' | 'day')[] = (() => { | ||
if (!fields) return ['year', 'month', 'day'] | ||
if (Array.isArray(fields)) return fields | ||
if (fields === 'MDY') return ['month', 'day', 'year'] | ||
if (fields === 'DMY') return ['day', 'month', 'year'] | ||
return ['year', 'month', 'day'] | ||
})() |
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.
// Support reordering for Y/M/D only; time units (hour/minute/second) keep original order after day | ||
const order = normalizeDateFieldsOrder(fields) | ||
if (length <= 3) { | ||
const y = base[0] | ||
const m = base[1] | ||
const d = base[2] | ||
const map: Record<'year' | 'month' | 'day', string> = { | ||
year: y, | ||
month: m, | ||
day: d, | ||
} | ||
const reordered = order.map(k => map[k]) | ||
return reordered.slice(0, length) | ||
} | ||
// length > 3 | ||
const ymdReordered = (() => { | ||
const y = base[0] | ||
const m = base[1] | ||
const d = base[2] | ||
const map: Record<'year' | 'month' | 'day', string> = { | ||
year: y, | ||
month: m, | ||
day: d, | ||
} | ||
return order.map(k => map[k]) | ||
})() | ||
const rest = base.slice(3, length) | ||
return [...ymdReordered, ...rest] |
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.
这部分代码在 length <= 3
和 length > 3
的分支中存在重复逻辑,即从 base
数组中提取年、月、日并根据 order
重排序的部分。
为了使代码更简洁、易于维护,可以提取这部分公共逻辑。
// Support reordering for Y/M/D only; time units (hour/minute/second) keep original order after day
const order = normalizeDateFieldsOrder(fields)
const y = base[0]
const m = base[1]
const d = base[2]
const map: Record<'year' | 'month' | 'day', string> = {
year: y,
month: m,
day: d,
}
const ymdReordered = order.map(k => map[k])
if (length <= 3) {
return ymdReordered.slice(0, length)
} else {
const rest = base.slice(3, length)
return [...ymdReordered, ...rest]
}
const indexInPresent = (key: 'year' | 'month' | 'day') => | ||
presentOrder.indexOf(key) | ||
const yIdx = indexInPresent('year') | ||
const mIdx = indexInPresent('month') | ||
const dIdx = indexInPresent('day') |
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.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/components/date-picker/date-picker-date-utils.ts (1)
170-188
: 字段顺序处理逻辑存在重复Lines 60-66 和 Lines 170-176 中存在几乎相同的字段顺序标准化逻辑。建议提取为一个共用的辅助函数以减少代码重复。
可以考虑提取如下的辅助函数:
+const normalizeFieldsOrder = (fields?: DateFieldsOrder): ('year' | 'month' | 'day')[] => { + if (!fields) return ['year', 'month', 'day'] + if (Array.isArray(fields)) return fields + if (fields === 'MDY') return ['month', 'day', 'year'] + if (fields === 'DMY') return ['day', 'month', 'year'] + return ['year', 'month', 'day'] +} - const order: ('year' | 'month' | 'day')[] = (() => { - if (!fields) return ['year', 'month', 'day'] - if (Array.isArray(fields)) return fields - if (fields === 'MDY') return ['month', 'day', 'year'] - if (fields === 'DMY') return ['day', 'month', 'year'] - return ['year', 'month', 'day'] - })() + const order = normalizeFieldsOrder(fields) - const fieldsOrder: ('year' | 'month' | 'day')[] = (() => { - if (!fields) return ['year', 'month', 'day'] - if (Array.isArray(fields)) return fields - if (fields === 'MDY') return ['month', 'day', 'year'] - if (fields === 'DMY') return ['day', 'month', 'year'] - return ['year', 'month', 'day'] - })() + const fieldsOrder = normalizeFieldsOrder(fields)src/components/date-picker/date-picker-utils.ts (1)
67-97
: 日期转字符串数组的字段重排逻辑需要优化实现中存在重复的代码块用于处理 Y/M/D 重排。可以提取公共逻辑以提高代码可维护性。
应用以下重构来消除重复代码:
export const convertDateToStringArray = ( date: Date | undefined | null, precision: Precision, fields?: DateFieldsOrder ) => { if (precision.includes('week')) { return weekUtils.convertDateToStringArray(date) } else if (precision.includes('quarter')) { return quarterUtils.convertDateToStringArray(date) } else { const datePrecision = precision as DatePrecision const base = dateUtils.convertDateToStringArray(date) const length = precisionLengthRecord[datePrecision] // Support reordering for Y/M/D only; time units (hour/minute/second) keep original order after day const order = normalizeDateFieldsOrder(fields) + // Extract reordering logic + const reorderYMD = (base: string[], order: ('year' | 'month' | 'day')[]) => { + const y = base[0] + const m = base[1] + const d = base[2] + const map: Record<'year' | 'month' | 'day', string> = { + year: y, + month: m, + day: d, + } + return order.map(k => map[k]) + } if (length <= 3) { - const y = base[0] - const m = base[1] - const d = base[2] - const map: Record<'year' | 'month' | 'day', string> = { - year: y, - month: m, - day: d, - } - const reordered = order.map(k => map[k]) + const reordered = reorderYMD(base, order) return reordered.slice(0, length) } // length > 3 - const ymdReordered = (() => { - const y = base[0] - const m = base[1] - const d = base[2] - const map: Record<'year' | 'month' | 'day', string> = { - year: y, - month: m, - day: d, - } - return order.map(k => map[k]) - })() + const ymdReordered = reorderYMD(base, order) const rest = base.slice(3, length) return [...ymdReordered, ...rest] } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
src/components/date-picker-view/date-picker-view.tsx
(4 hunks)src/components/date-picker/date-picker-date-utils.ts
(5 hunks)src/components/date-picker/date-picker-utils.ts
(5 hunks)src/components/date-picker/date-picker.tsx
(5 hunks)src/components/date-picker/demos/demo1.tsx
(3 hunks)src/components/date-picker/tests/date-picker.test.tsx
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (6)
src/components/date-picker/tests/date-picker.test.tsx (2)
src/components/picker-view/columns-extend.tsx (1)
columns
(34-36)src/components/date-picker/date-picker.tsx (1)
DatePicker
(78-178)
src/components/date-picker/demos/demo1.tsx (3)
src/components/space/space.tsx (1)
Space
(30-55)src/components/button/button.tsx (1)
Button
(64-132)src/components/date-picker/date-picker.tsx (1)
DatePicker
(78-178)
src/components/date-picker/date-picker-date-utils.ts (2)
src/components/date-picker/date-picker-utils.ts (2)
DateFieldsOrder
(25-29)convertStringArrayToDate
(100-143)src/components/picker-view/picker-view.tsx (1)
PickerColumn
(27-27)
src/components/date-picker/date-picker-utils.ts (1)
src/components/date-picker/date-picker-date-utils.ts (2)
DatePrecision
(14-20)convertStringArrayToDate
(254-271)
src/components/date-picker-view/date-picker-view.tsx (5)
src/components/date-picker/date-picker-utils.ts (3)
DateFieldsOrder
(25-29)convertDateToStringArray
(56-98)convertStringArrayToDate
(100-143)src/components/date-picker/date-picker-date-utils.ts (2)
convertDateToStringArray
(240-252)convertStringArrayToDate
(254-271)src/components/date-picker/date-picker-week-utils.ts (2)
convertDateToStringArray
(120-130)convertStringArrayToDate
(132-146)src/components/date-picker/date-picker-quarter-utils.ts (2)
convertDateToStringArray
(98-104)convertStringArrayToDate
(106-118)src/components/picker-view/picker-view.tsx (1)
PickerValue
(14-14)
src/components/date-picker/date-picker.tsx (3)
src/components/date-picker/date-picker-utils.ts (3)
DateFieldsOrder
(25-29)convertDateToStringArray
(56-98)convertStringArrayToDate
(100-143)src/components/date-picker/date-picker-date-utils.ts (2)
convertDateToStringArray
(240-252)convertStringArrayToDate
(254-271)src/components/date-picker/date-picker-week-utils.ts (2)
convertDateToStringArray
(120-130)convertStringArrayToDate
(132-146)
⏰ 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). (4)
- GitHub Check: size
- GitHub Check: build preview
- GitHub Check: check
- GitHub Check: compressed-size
🔇 Additional comments (28)
src/components/date-picker/demos/demo1.tsx (3)
3-3
: 导入顺序调整符合代码规范调整了 React hooks 的导入顺序(从
useState, useCallback
到useCallback, useState
),虽然这不影响功能,但保持了一致的代码风格。
273-313
: 新增字段顺序演示功能实现良好FieldsDemo 组件很好地展示了新的
fields
属性功能:
- 使用数组格式
['month', 'day', 'year']
展示月-日-年顺序- 使用字符串格式
'DMY'
展示日-月-年顺序- 两个选择器都正确设置了最大值和确认回调
实现符合 PR 目标,为用户提供了直观的字段顺序自定义功能演示。
346-348
: 演示模块集成正确新的"自定义列顺序"演示块已正确集成到主演示页面中,为用户提供了清晰的功能展示入口。
src/components/date-picker/tests/date-picker.test.tsx (3)
267-282
: 测试工具函数实现合理
getColumnValues
辅助函数能够正确提取指定列的文本内容,为验证字段顺序提供了可靠的测试基础。defaultDate
常量选择了具体的测试日期,有助于验证预期结果。
284-310
: 数组格式字段顺序测试覆盖完整测试正确验证了使用数组格式
['month', 'day', 'year']
时:
- 各列内容顺序符合预期(月-日-年)
- 确认后返回的日期对象正确
测试逻辑清晰,覆盖了核心功能点。
312-338
: 字符串格式字段顺序测试实现正确测试有效验证了使用字符串格式
'DMY'
时:
- 各列内容按日-月-年顺序正确显示
- 用户选择后的日期转换准确
与数组格式测试形成良好互补,确保了两种配置方式都能正常工作。
src/components/date-picker-view/date-picker-view.tsx (5)
7-7
: 正确导入新类型定义添加了
DateFieldsOrder
类型导入,为组件支持字段顺序配置提供了类型基础。
43-43
: Props 接口扩展合理为
DatePickerViewProps
添加了可选的fields?: DateFieldsOrder
属性,保持了向后兼容性的同时扩展了功能。
70-71
: 日期转换函数参数传递正确在
convertDateToStringArray
调用中正确传递了props.fields
参数,确保了日期到字符串数组的转换能够遵循指定的字段顺序。同时更新了依赖数组以包含props.fields
,保证了字段顺序变化时组件能够正确重新计算。
75-82
: onChange 回调处理完整
convertStringArrayToDate
调用中正确传递了props.fields
参数,确保字符串数组到日期的转换能够正确解析按自定义顺序排列的值。依赖数组也相应更新,保证了响应性。
95-96
: 列生成函数参数传递完整
generateDatePickerColumns
函数调用中正确添加了props.fields
参数,确保生成的选择器列能够按照指定的字段顺序排列。src/components/date-picker/date-picker.tsx (7)
19-22
: 类型导入新增合理正确导入了
DateFieldsOrder
类型,为组件提供字段顺序配置的类型支持。
65-65
: Props 接口扩展符合设计为
DatePickerProps
添加了可选的fields?: DateFieldsOrder
属性,保持了 API 的一致性和向后兼容性。
75-75
: 默认值设置合理将
fields
的默认值设置为'YMD'
,保持了原有的年-月-日显示顺序,确保了向后兼容性。
106-106
: 日期转换参数传递正确在
pickerValue
的计算中,convertDateToStringArray
正确传递了props.fields
参数,确保了选择器值的生成能够遵循指定的字段顺序。
111-118
: 确认回调处理完整
onConfirm
回调中的convertStringArrayToDate
调用正确传递了props.fields
参数,确保了用户选择的值能够被正确解析为日期对象。依赖数组也相应更新以包含props.fields
。
122-122
: 选择回调处理正确
onSelect
回调中的日期转换同样传递了正确的props.fields
参数,保证了选择过程中的数据一致性。
135-145
: 列生成依赖更新完整
generateDatePickerColumns
调用中正确添加了props.fields
参数,同时在依赖数组中也包含了该字段,确保字段顺序变化时能够重新生成列配置。src/components/date-picker/date-picker-date-utils.ts (5)
7-7
: 类型导入添加正确正确导入了
DateFieldsOrder
类型,为函数签名提供了必要的类型支持。
38-40
: 函数签名扩展合理
generateDatePickerColumns
函数添加了可选的fields?: DateFieldsOrder
参数,保持了向后兼容性的同时扩展了功能。参数顺序安排合理。
59-76
: 字段顺序映射逻辑实现正确通过计算字段顺序并创建索引映射,然后安全地提取年、月、日字符串,这种实现方式:
- 正确处理了不同的字段顺序格式(数组、字符串)
- 通过
safe
函数提供了边界保护- 为后续的日期计算提供了正确的基础数据
逻辑清晰且健壮。
107-123
: buildStringArrayFor 辅助函数设计良好该函数根据不同的精度级别构建正确的字符串数组,使用了重新映射的年、月、日字符串,确保了过滤器能够基于正确的字段顺序进行工作。实现简洁且逻辑清晰。
138-188
: 列生成和排序逻辑实现优雅代码采用了先生成各个日期列(年、月、日),然后根据字段顺序重新排列的方式:
- 避免了重复的顺序判断逻辑
- 保持了原有的列生成逻辑完整性
- 通过
available
数组和循环实现了灵活的列排序这种设计既保持了代码的可维护性,又实现了功能需求。
src/components/date-picker/date-picker-utils.ts (5)
25-29
: 类型定义设计良好,支持灵活配置
DateFieldsOrder
类型设计合理,同时支持数组形式和字符串缩写形式,为用户提供了灵活的配置选项。这种设计既满足了编程式配置的需求,也提供了便捷的预设选项。
31-45
: 规范化函数实现正确
normalizeDateFieldsOrder
函数正确处理了各种输入格式,包括 undefined、数组和字符串格式。实现逻辑清晰,默认值处理合理。
119-142
: 字符串数组转日期的逆向重排逻辑实现正确逆向重排逻辑正确实现了从自定义顺序的字符串数组还原为标准的 Y/M/D 顺序,然后传递给底层的
dateUtils.convertStringArrayToDate
函数。索引映射逻辑清晰,时间单位的处理也很合理。
152-184
: 参数传递和函数签名更新正确
generateDatePickerColumns
函数正确添加了fields
参数并将其传递给底层的日期工具函数。参数顺序合理,保持了向后兼容性。
58-59
: 验证完成:所有调用点已包含 fields 参数已确认:
- 在
src/components/date-picker/date-picker.tsx
中,convertDateToStringArray(date, props.precision, props.fields)
与convertStringArrayToDate(val, props.precision, props.fields)
均已传入props.fields
。- 在
src/components/date-picker-view/date-picker-view.tsx
中,convertDateToStringArray(value, props.precision, props.fields)
和convertStringArrayToDate(val, props.precision, props.fields)
均已传入props.fields
。generateDatePickerColumns
的调用:
- 在
date-picker-view.tsx
中以完整参数(selected, min, max, precision, renderLabel, filter, tillNow, fields)调用。- 在
date-picker.tsx
中以必选前五个参数调用(其余为可选,未传时使用默认值)。无需进一步修改。
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
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/date-picker/date-picker.tsx (1)
96-107
: useMemo 依赖缺失 columns,切换列顺序不会触发 pickerValue 重算当外部动态变更
props.columns
时,pickerValue
不会更新,导致 UI 未按新顺序重排/同步选中值。需将props.columns
加入依赖数组。建议改动:
- }, [value, props.precision, props.min, props.max]) + }, [value, props.precision, props.min, props.max, props.columns])
🧹 Nitpick comments (8)
src/components/date-picker/index.ts (1)
7-8
: 建议同时对外导出类型 DateColumnsOrder,方便 TS 场景复用目前仅导出 DatePickerProps / DatePickerRef / DatePickerFilter。考虑把 DateColumnsOrder 也从 index.ts re-export,便于用户在类型层面声明列顺序变量(而不仅仅是通过常量)。
可以在本文件中追加如下导出:
export type { DatePickerProps, DatePickerRef } from './date-picker' -export type { DatePickerFilter } from './date-picker-utils' +export type { DatePickerFilter, DateColumnsOrder } from './date-picker-utils'src/components/date-picker/tests/date-picker.test.tsx (4)
267-267
: 测试用例描述建议与新 API 名称保持一致块描述为“DatePicker fields prop”,而实际属性名为 columns。建议统一为 columns,避免混淆。
- describe('DatePicker fields prop', () => { + describe('DatePicker columns prop', () => {
268-269
: 避免使用字符串日期构造,降低时区导致的用例不稳定风险
new Date('2025-8-20')
依赖实现细节/时区解析,极端情况下可能在不同环境变成前一天或后一天。建议改用数值构造。- const defaultDate = new Date('2025-8-20') + // 月份从 0 开始,这里 7 代表 8 月 + const defaultDate = new Date(2025, 7, 20)
295-301
: 断言更精确:校验“已选中”的列项而不是“包含某值”当前
toContain('8') / toContain('20')
仅验证列内是否存在该数字,无法确保是当前选中项。建议断言选中项(如使用.adm-picker-view-column-item-selected
)的文本,更能确保列顺序与选中值正确。例如:
- expect(getColumnValues(baseElement, 0)).toContain('8') - expect(getColumnValues(baseElement, 1)).toContain('20') + const selectedOf = (col: number) => + baseElement + .querySelectorAll('.adm-picker-view-column') + [col]?.querySelector('.adm-picker-view-column-item-selected') + ?.textContent + expect(selectedOf(0)).toBe('8') + expect(selectedOf(1)).toBe('20')若实际选中类名不同,请替换为项目内真实类名。
284-311
: 补充一条关于“部分列(如仅 day+month)”的行为用例本 PR 支持自定义列顺序,同时允许 columns 只给出部分 Y/M/D。建议新增一例:columns 仅包含两列(例如 ['day', 'month'])时,确认:
- 生成列顺序符合预期(是否会自动补齐 year,或使用当前 year 回填)。
- 转换回 Date 时的年份默认策略(当前年)正确。
我可以补一条用例,您需要的话我来起草。
src/components/date-picker/demos/demo1.tsx (1)
275-316
: “日-月”示例的列数与按钮文案可能不一致,请确认行为并保持一致
columns={[DAY_COLUMN, MONTH_COLUMN]}
若内部会通过 normalize 补齐year
(常见设计是补齐为 3 列以满足 day 精度计算),则实际显示可能为“日-月-年”。建议:
- 若实际是 3 列:更新按钮文案为“日-月-年”,或显式传入
columns={[DAY_COLUMN, MONTH_COLUMN, YEAR_COLUMN]}
以避免误导。- 若实际就是 2 列:建议在文档/示例中说明“缺失的年份回退为当前年”的行为,并补充一条测试覆盖(参考上文测试建议)。
我可以根据确认结果提交相应的示例/测试修正。
src/components/date-picker/date-picker-date-utils.ts (1)
80-86
: 仅在需要日列时再计算当月天数,避免无谓计算
firstDayInSelectedMonth
仅在rank >= day
时参与日列上限计算。可推迟到该分支内生成,减少不必要的计算与依赖。- const firstDayInSelectedMonth = dayjs( - convertStringArrayToDate([yStr, mStr, '1']) - ) + // 下方 day 分支内按需计算: + // const firstDayInSelectedMonth = dayjs(convertStringArrayToDate([yStr, mStr, '1']))并在 day 分支内部按需计算:
const firstDayInSelectedMonth = dayjs( convertStringArrayToDate([yStr, mStr, '1']) ) const upper = isInMaxMonth ? maxDay : firstDayInSelectedMonth.daysInMonth()src/components/date-picker/date-picker-utils.ts (1)
85-131
: 反序列化映射逻辑合理;可小幅收紧类型以避免断言使用
Map
计算索引、对缺失字段用“当前日期”兜底,能在不同顺序下稳定还原。当前将mapped
断言为string[]
传入底层转换函数,虽运行时安全,但类型不够严谨。可在赋值时统一转为字符串,消除断言。- mapped[0] = yIdx !== -1 ? value[yIdx] : currentYear - mapped[1] = mIdx !== -1 ? value[mIdx] : currentMonth - mapped[2] = dIdx !== -1 ? value[dIdx] : currentDay + mapped[0] = (yIdx !== -1 ? value[yIdx] : currentYear).toString() + mapped[1] = (mIdx !== -1 ? value[mIdx] : currentMonth).toString() + mapped[2] = (dIdx !== -1 ? value[dIdx] : currentDay).toString() for (let i = presentOrder.length; i < value.length; i += 1) { - mapped[3 + (i - presentOrder.length)] = value[i] + mapped[3 + (i - presentOrder.length)] = String(value[i] ?? '') } - return dateUtils.convertStringArrayToDate(mapped as string[]) + return dateUtils.convertStringArrayToDate(mapped as string[])
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (9)
src/components/date-picker-view/date-picker-view.tsx
(4 hunks)src/components/date-picker-view/demos/demo1.tsx
(1 hunks)src/components/date-picker/date-picker-date-utils.ts
(5 hunks)src/components/date-picker/date-picker-utils.ts
(6 hunks)src/components/date-picker/date-picker.tsx
(5 hunks)src/components/date-picker/demos/demo1.tsx
(3 hunks)src/components/date-picker/index.ts
(1 hunks)src/components/date-picker/tests/date-picker.test.tsx
(1 hunks)src/components/date-picker/util.ts
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/components/date-picker-view/demos/demo1.tsx
🧰 Additional context used
🧬 Code Graph Analysis (7)
src/components/date-picker/index.ts (2)
src/components/date-picker/date-picker.tsx (1)
DatePicker
(78-178)src/components/date-picker/util.ts (1)
TILL_NOW
(1-1)
src/components/date-picker/date-picker.tsx (1)
src/components/date-picker/date-picker-utils.ts (3)
DateColumnsOrder
(25-25)convertDateToStringArray
(51-83)convertStringArrayToDate
(85-132)
src/components/date-picker-view/date-picker-view.tsx (2)
src/components/date-picker/date-picker-utils.ts (3)
DateColumnsOrder
(25-25)convertDateToStringArray
(51-83)convertStringArrayToDate
(85-132)src/components/picker-view/picker-view.tsx (1)
PickerValue
(14-14)
src/components/date-picker/date-picker-date-utils.ts (3)
src/components/date-picker/date-picker-utils.ts (3)
DateColumnsOrder
(25-25)normalizeDateColumnsOrder
(27-40)convertStringArrayToDate
(85-132)src/components/date-picker/util.ts (3)
YEAR_COLUMN
(7-7)MONTH_COLUMN
(9-9)DAY_COLUMN
(11-11)src/components/picker-view/picker-view.tsx (1)
PickerColumn
(27-27)
src/components/date-picker/date-picker-utils.ts (4)
src/components/date-picker/util.ts (3)
YEAR_COLUMN
(7-7)MONTH_COLUMN
(9-9)DAY_COLUMN
(11-11)src/components/date-picker/date-picker-date-utils.ts (2)
DatePrecision
(18-24)convertStringArrayToDate
(251-268)src/components/date-picker/date-picker-week-utils.ts (1)
convertStringArrayToDate
(132-146)src/components/date-picker/date-picker-quarter-utils.ts (1)
convertStringArrayToDate
(106-118)
src/components/date-picker/demos/demo1.tsx (2)
src/components/date-picker/date-picker.tsx (1)
DatePicker
(78-178)src/components/date-picker/util.ts (3)
MONTH_COLUMN
(9-9)DAY_COLUMN
(11-11)YEAR_COLUMN
(7-7)
src/components/date-picker/tests/date-picker.test.tsx (1)
src/components/date-picker/date-picker.tsx (1)
DatePicker
(78-178)
⏰ 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). (3)
- GitHub Check: compressed-size
- GitHub Check: size
- GitHub Check: build preview
🔇 Additional comments (18)
src/components/date-picker/util.ts (1)
7-11
: 新增列常量命名清晰、类型安全,LGTM以 string literal + as const 的方式导出 YEAR/MONTH/DAY 三个列键,非常适合在外部作为 columns 配置使用。
src/components/date-picker/index.ts (1)
10-16
: 将列键常量挂到组件静态属性,易用性提升,LGTM通过 attachPropertiesToComponent 暴露 YEAR_COLUMN/MONTH_COLUMN/DAY_COLUMN,便于示例和用户直接从 DatePicker 解构使用,符合现有 API 风格。
src/components/date-picker/tests/date-picker.test.tsx (1)
267-311
: 测试块未重复定义,无需修改经检索,
describe('DatePicker fields prop', …)
在date-picker.test.tsx
文件中仅出现一次,未发现重复定义的测试块,请忽略此建议。Likely an incorrect or invalid review comment.
src/components/date-picker/demos/demo1.tsx (1)
8-9
: 从 DatePicker 解构列键常量用于示例,LGTM提升了示例的可读性与可发现性,且与 index.ts 的静态导出设计一致。
src/components/date-picker-view/date-picker-view.tsx (4)
7-8
: 为 DatePickerView 新增 columns?: DateColumnsOrder,类型与 DatePicker 对齐,LGTM类型对齐且向下贯穿至转换与列生成,便于 DatePickerView 独立使用时也能自定义列顺序。
70-72
: pickerValue 计算引入 columns 参与重排,依赖项同步更新,LGTM已将
props.columns
纳入 useMemo 依赖,避免列序改变时视图不同步。
73-82
: onChange 转换逻辑引入 columns,避免错位解析,LGTM依赖项补充
props.columns
,保证闭包内拿到最新的列顺序。
95-97
: 列生成传递 columns,保持转换与渲染一致性,LGTMgenerateDatePickerColumns 的入参与 DatePicker 对齐,减少双组件行为差异。
src/components/date-picker/date-picker.tsx (4)
65-76
: 新增 columns Prop 与默认值设置合理公开
columns?: DateColumnsOrder
并在defaultProps
中默认['year','month','day']
,与此次能力目标一致,类型与默认值选择均恰当。
111-119
: onConfirm 回调透传 columns 正确;依赖项已包含 columns
convertStringArrayToDate(val, props.precision, props.columns)
的调用与依赖项维护一致,能正确按自定义顺序还原日期。
121-124
: onSelect 动态使用最新 columns 与 precision 的实现可接受这里用
useMemoizedFn
获取最新的props
,无需在依赖数组中声明,能保持引用稳定且拿到最新precision/columns
,实现合理。
126-146
: 列生成逻辑已正确串联 tillNow 与 columns
generateDatePickerColumns(..., props.tillNow, props.columns)
的透传与依赖项维护完整,符合新增能力设计。src/components/date-picker/date-picker-date-utils.ts (4)
110-126
: 过滤器上下文构造正确,能与 columns 顺序解耦通过
buildStringArrayFor
始终以标准 Y/M/D 顺序构造日期字符串数组供convertStringArrayToDate
使用,确保filter
逻辑不受列顺序影响,设计合理。
141-171
: 年/月/日列生成逻辑与选中态计算合理针对边界条件的上下限(min/max)与选中态
selectedXxx === v
的计算正确;结合上方越界修复后,可以避免 NaN 造成的选中态异常。
173-185
: 按自定义顺序组装 Y/M/D 列的实现清晰通过
normalizeDateColumnsOrder
与available
列表拼装输出顺序,语义明确,易维护。
220-232
: “至今”选项固定追加到第一列,请确认与交互预期一致当前将
TILL_NOW
追加到ret[0]
,且convertStringArrayToDate
仅在value[0] === TILL_NOW
情况下处理“至今”。这意味着当自定义顺序为 MDY/DMY 时,“至今”会出现在“第一列”(可能是月/日列)。如产品期望“至今”始终显示在年份列,请确认是否需要在组装顺序前将“年份列”强制置于索引 0 的特殊位(或调整判定逻辑为“只要某列为 TILL_NOW 即视为至今”)。src/components/date-picker/date-picker-utils.ts (2)
51-82
: 按自定义顺序重排 Y/M/D 的实现正确且简洁将 Y/M/D 重排后再拼接后续时间单位,满足不同精度下的列顺序配置需求,逻辑清晰。
134-175
: 路由到不同精度的列生成函数并透传 columns 的更改正确对 week/quarter/date 三种路径的签名统一、行为一致,透传
columns
(以及tillNow
)保证渲染与反序列化一致。
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
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/components/date-picker/date-picker.tsx (2)
91-103
: useMemo 依赖缺少 props.columns,切换列顺序时 pickerValue 不会更新当外部变更
columns
时,pickerValue
仍基于旧顺序,导致初始选中错位。建议补全依赖:
- }, [value, props.precision, props.min, props.max]) + }, [value, props.precision, props.min, props.max, props.columns])
121-141
: columns 回调缺少 props.filter 依赖,动态过滤规则变更不生效
generateDatePickerColumns
使用了props.filter
,但未列入依赖,可能导致列候选集与 UI 不一致。- [ + [ props.min, props.max, props.precision, mergedRenderLabel, props.tillNow, props.columns, + props.filter, ]src/components/date-picker/date-picker-date-utils.ts (1)
115-137
: 过滤回调中构造 date 未传入 columns,且 prefix 位置计算与自定义顺序不符当前用
precisionRankRecord[precision]
截取prefix
,在自定义列顺序下位置不对;且未把列顺序传给convertStringArrayToDate
,导致filter
判断基于错误日期。- const prefix = selected.slice(0, precisionRankRecord[precision]) + // 以渲染列顺序定位当前列在 selected 中的位置 + const insertIndex = Math.max( + 0, + renderedColumns.findIndex(ct => columnToPrecisionMap[ct] === precision) + ) + const prefix = selected.slice(0, insertIndex) @@ - const stringArray = [...prefix, i.toString()] - return convertStringArrayToDate(stringArray) + const stringArray = [...prefix, i.toString()] + return convertStringArrayToDate(stringArray, renderedColumns)
♻️ Duplicate comments (1)
src/components/date-picker/date-picker-date-utils.ts (1)
146-218
: switch case 内声明变量触发 Biome noSwitchDeclarations 错误需为每个 case 加块级作用域,避免跨 case 变量泄露。
- case YEAR_COLUMN: - const lower = minYear - const upper = maxYear - const years = generateColumn(lower, upper, 'year') + case YEAR_COLUMN: { + const lower = minYear + const upper = maxYear + const years = generateColumn(lower, upper, 'year') ret.push( years.map(v => ({ label: renderLabel('year', v, { selected: selectedYear === v }), value: v.toString(), })) ) - break + break + } @@ - case MONTH_COLUMN: + case MONTH_COLUMN: { const lowerMonth = isInMinYear ? minMonth : 1 const upperMonth = isInMaxYear ? maxMonth : 12 const months = generateColumn(lowerMonth, upperMonth, 'month') ret.push( months.map(v => ({ label: renderLabel('month', v, { selected: selectedMonth === v }), value: v.toString(), })) ) - break + break + } @@ - case DAY_COLUMN: + case DAY_COLUMN: { const lowerDay = isInMinMonth ? minDay : 1 const upperDay = isInMaxMonth ? maxDay : firstDayInSelectedMonth.daysInMonth() const days = generateColumn(lowerDay, upperDay, 'day') ret.push( days.map(v => ({ label: renderLabel('day', v, { selected: selectedDay === v }), value: v.toString(), })) ) - break + break + } @@ - case HOUR_COLUMN: + case HOUR_COLUMN: { const lowerHour = isInMinDay ? minHour : 0 const upperHour = isInMaxDay ? maxHour : 23 const hours = generateColumn(lowerHour, upperHour, 'hour') ret.push( hours.map(v => ({ label: renderLabel('hour', v, { selected: selectedHour === v }), value: v.toString(), })) ) - break + break + } @@ - case MINUTE_COLUMN: + case MINUTE_COLUMN: { const lowerMinute = isInMinHour ? minMinute : 0 const upperMinute = isInMaxHour ? maxMinute : 59 const minutes = generateColumn(lowerMinute, upperMinute, 'minute') ret.push( minutes.map(v => ({ label: renderLabel('minute', v, { selected: selectedMinute === v }), value: v.toString(), })) ) - break + break + } @@ - case SECOND_COLUMN: + case SECOND_COLUMN: { const lowerSecond = isInMinMinute ? minSecond : 0 const upperSecond = isInMaxMinute ? maxSecond : 59 const seconds = generateColumn(lowerSecond, upperSecond, 'second') ret.push( seconds.map(v => ({ label: renderLabel('second', v, { selected: selectedSecond === v }), value: v.toString(), })) ) - break + break + }
🧹 Nitpick comments (1)
src/components/date-picker/date-picker-date-utils.ts (1)
94-100
: 可选:对选中年份做二次夹取,增强稳健性上游异常映射时可出现越界年份,建议再次 clamp 到
[minYear, maxYear]
。- const selectedYear = getValue(YEAR_COLUMN) ?? min.getFullYear() + let selectedYear = getValue(YEAR_COLUMN) ?? min.getFullYear() + selectedYear = Math.min(Math.max(selectedYear, minYear), maxYear)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
src/components/date-picker/date-picker-date-utils.ts
(5 hunks)src/components/date-picker/date-picker-utils.ts
(5 hunks)src/components/date-picker/date-picker.tsx
(4 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/components/date-picker/date-picker-date-utils.ts (3)
src/components/date-picker/util.ts (8)
DateColumnType
(14-20)YEAR_COLUMN
(7-7)MONTH_COLUMN
(8-8)DAY_COLUMN
(9-9)HOUR_COLUMN
(10-10)MINUTE_COLUMN
(11-11)SECOND_COLUMN
(12-12)TILL_NOW
(1-1)src/components/date-picker/date-picker-utils.ts (3)
generateDatePickerColumns
(93-133)DatePickerFilter
(21-31)convertStringArrayToDate
(70-91)src/components/date-picker-view/date-picker-view.tsx (1)
RenderLabel
(21-27)
src/components/date-picker/date-picker-utils.ts (4)
src/components/date-picker/util.ts (7)
DateColumnType
(14-20)YEAR_COLUMN
(7-7)MONTH_COLUMN
(8-8)DAY_COLUMN
(9-9)HOUR_COLUMN
(10-10)MINUTE_COLUMN
(11-11)SECOND_COLUMN
(12-12)src/components/date-picker/date-picker-date-utils.ts (2)
DatePrecision
(23-29)convertStringArrayToDate
(253-319)src/components/date-picker/date-picker-week-utils.ts (1)
convertStringArrayToDate
(132-146)src/components/date-picker/date-picker-quarter-utils.ts (1)
convertStringArrayToDate
(106-118)
src/components/date-picker/date-picker.tsx (2)
src/components/date-picker/util.ts (1)
DateColumnType
(14-20)src/components/date-picker/date-picker-utils.ts (2)
convertDateToStringArray
(42-68)convertStringArrayToDate
(70-91)
🪛 Biome (2.1.2)
src/components/date-picker/date-picker-date-utils.ts
[error] 147-147: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 148-148: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 149-149: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 159-159: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 160-160: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 161-161: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 171-171: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 172-174: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 175-175: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 185-185: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 186-186: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 187-187: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 197-197: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 198-198: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 199-199: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 209-209: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 210-210: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 211-211: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Safe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
⏰ 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). (4)
- GitHub Check: compressed-size
- GitHub Check: build preview
- GitHub Check: size
- GitHub Check: check
🔇 Additional comments (1)
src/components/date-picker/date-picker-date-utils.ts (1)
253-309
: convertStringArrayToDate 对 '0' 误判为 falsy,导致 0 时/分/秒回退默认值应使用空值判断而非真值判断;并统一十进制解析。
- columns.forEach((columnType, index) => { - const val = value[index]?.toString() ?? null + columns.forEach((columnType, index) => { + const raw = value[index] + const val = raw == null ? null : String(raw) @@ - case YEAR_COLUMN: - if (val) yearString = val + case YEAR_COLUMN: + if (val != null) yearString = val break @@ - case MONTH_COLUMN: - if (val) monthString = val + case MONTH_COLUMN: + if (val != null) monthString = val break @@ - case DAY_COLUMN: - if (val) dateString = val + case DAY_COLUMN: + if (val != null) dateString = val break @@ - case HOUR_COLUMN: - if (val) hourString = val + case HOUR_COLUMN: + if (val != null) hourString = val break @@ - case MINUTE_COLUMN: - if (val) minuteString = val + case MINUTE_COLUMN: + if (val != null) minuteString = val break @@ - case SECOND_COLUMN: - if (val) secondString = val + case SECOND_COLUMN: + if (val != null) secondString = val breakLikely an incorrect or invalid review comment.
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
♻️ Duplicate comments (2)
src/components/date-picker/date-picker-utils.ts (1)
81-101
: TILL_NOW 仅检查首列,和 UI 行为一致与“将 Now 选项放在第一列”的实现对齐,判断逻辑合理。
src/components/date-picker/date-picker-date-utils.ts (1)
119-141
: 过滤回调中日期反序列化未携带列顺序,重排/子集时会算错 date(需修复)当前
convertStringArrayToDate(stringArray)
以默认 Y-M-D 顺序解析;当 columns 重排为如 [MONTH, DAY, YEAR] 或仅为子集时,prefix
的顺序与默认不一致,过滤得到的date
错误,直接影响候选项。同时,
prefix
含 TILL_NOW 时会把 'TILL_NOW' 传给解析函数导致 NaN,应在此短路为 now。建议:给
generateColumn
增加columnType
参数,构造与stringArray
一致的usedColumns
顺序传入解析;并对 TILL_NOW 前缀短路。- const generateColumn = ( - from: number, - to: number, - precision: DatePrecision - ) => { + const generateColumn = ( + from: number, + to: number, + precision: DatePrecision, + columnType: DateColumnType + ) => { let column: number[] = [] for (let i = from; i <= to; i++) { column.push(i) } const prefix = selected.slice(0, precisionRankRecord[precision]) const currentFilter = filter?.[precision] if (currentFilter && typeof currentFilter === 'function') { column = column.filter(i => currentFilter(i, { get date() { - const stringArray = [...prefix, i.toString()] - return convertStringArrayToDate(stringArray) + const stringArray = [...prefix, i.toString()] + // 与 stringArray 对齐的列顺序:先取已渲染的前缀列,再拼接当前列 + const usedColumns = renderedColumns + .slice(0, precisionRankRecord[precision]) + .concat(columnType) + // 若选择了“至今”,直接按当前时间短路 + if (prefix.includes(TILL_NOW)) return new Date() + return convertStringArrayToDate(stringArray, usedColumns) }, }) ) } return column }并在下方 switch 分支调用处补上
columnType
:- const years = generateColumn(lower, upper, 'year') + const years = generateColumn(lower, upper, 'year', YEAR_COLUMN) @@ - const months = generateColumn(lowerMonth, upperMonth, 'month') + const months = generateColumn(lowerMonth, upperMonth, 'month', MONTH_COLUMN) @@ - const days = generateColumn(lowerDay, upperDay, 'day') + const days = generateColumn(lowerDay, upperDay, 'day', DAY_COLUMN) @@ - const hours = generateColumn(lowerHour, upperHour, 'hour') + const hours = generateColumn(lowerHour, upperHour, 'hour', HOUR_COLUMN) @@ - const minutes = generateColumn(lowerMinute, upperMinute, 'minute') + const minutes = generateColumn(lowerMinute, upperMinute, 'minute', MINUTE_COLUMN) @@ - const seconds = generateColumn(lowerSecond, upperSecond, 'second') + const seconds = generateColumn(lowerSecond, upperSecond, 'second', SECOND_COLUMN)
🧹 Nitpick comments (5)
src/components/date-picker/date-picker-utils.ts (1)
42-79
: columns 未做去重/校验,可能导致重复列与值错位当传入 columns 含重复项或非法项时,这里会按重复顺序返回值,易与渲染列数不一致。建议先去重并过滤仅允许的列,再按精度裁剪。
可在本函数内做轻量归一化,避免额外依赖:
const map: Record<DateColumnType, string> = { @@ } - const order: DateColumnType[] = [ + const order: DateColumnType[] = [ YEAR_COLUMN, MONTH_COLUMN, DAY_COLUMN, HOUR_COLUMN, MINUTE_COLUMN, SECOND_COLUMN, ] const max = precisionLengthRecord[datePrecision] - return columns - .filter(col => order.indexOf(col) > -1 && order.indexOf(col) < max) - .map(col => map[col]) + const allowed = new Set(order) + // 去重且仅保留允许列 + const normalized = Array.from(new Set(columns)).filter(c => allowed.has(c)) + return normalized + .filter(col => order.indexOf(col) < max) + .map(col => map[col])src/components/date-picker/date-picker-date-utils.ts (4)
75-88
: finalColumns 建议先去重,避免重复列渲染与 selected 映射错位当外部传入包含重复列时,renderedColumns 会重复生成列,selected 顺序也会变得不稳定。建议在应用精度过滤前去重。
- const finalColumns = columns?.length ? columns : defaultColumns - const renderedColumns = finalColumns.filter(columnType => { + const finalColumns = columns?.length ? columns : defaultColumns + const dedupedFinal = Array.from(new Set(finalColumns)) + const renderedColumns = dedupedFinal.filter(columnType => { const columnPrecision = columnToPrecisionMap[columnType] return rank >= precisionRankRecord[columnPrecision] })
98-103
: year 建议再次夹取到 [minYear, maxYear],防御异常输入可避免异常 selected 导致边界判定错乱(如 isInMinYear/MaxYear)。
- const selectedYear = getValue(YEAR_COLUMN) ?? min.getFullYear() + const selectedYearRaw = getValue(YEAR_COLUMN) ?? min.getFullYear() + const selectedYear = Math.min(Math.max(selectedYearRaw, minYear), maxYear)
223-234
: Till Now 清空下游列的方式可提前短路以省开销(可选)若首列已选 TILL_NOW,可在生成列前直接返回仅含首列的结果,减少无效计算。
253-319
: 列映射反序列化对“包含但未给值”的列未做兜底,默认 1900/1/1/0:0:0 不理想当 columns 包含某列但对应值缺失(例如过滤阶段或受限于精度),当前实现会保留初始的 1900/1/1/0:0:0。建议对“包含但未赋值”的列回退到 now(或约定默认),避免生成过早/异常日期。
- columns.forEach((columnType, index) => { - const val = value[index]?.toString() ?? null + columns.forEach((columnType, index) => { + const val = value[index]?.toString() ?? null switch (columnType) { case YEAR_COLUMN: - if (val) yearString = val + yearString = val ?? now.getFullYear().toString() break case MONTH_COLUMN: - if (val) monthString = val + monthString = val ?? (now.getMonth() + 1).toString() break case DAY_COLUMN: - if (val) dateString = val + dateString = val ?? now.getDate().toString() break case HOUR_COLUMN: - if (val) hourString = val + hourString = val ?? now.getHours().toString() break case MINUTE_COLUMN: - if (val) minuteString = val + minuteString = val ?? now.getMinutes().toString() break case SECOND_COLUMN: - if (val) secondString = val + secondString = val ?? now.getSeconds().toString() break } }) - - if (!columns.includes(YEAR_COLUMN)) + if (!columns.includes(YEAR_COLUMN)) yearString = now.getFullYear().toString() @@ - if (!columns.includes(SECOND_COLUMN)) + if (!columns.includes(SECOND_COLUMN)) secondString = now.getSeconds().toString()说明:保持“未包含的列回退 now”的现有语义,同时让“包含但未给值”的场景也安全回退。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
src/components/date-picker/date-picker-date-utils.ts
(5 hunks)src/components/date-picker/date-picker-utils.ts
(5 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/components/date-picker/date-picker-date-utils.ts (3)
src/components/date-picker/util.ts (8)
DateColumnType
(14-20)YEAR_COLUMN
(7-7)MONTH_COLUMN
(8-8)DAY_COLUMN
(9-9)HOUR_COLUMN
(10-10)MINUTE_COLUMN
(11-11)SECOND_COLUMN
(12-12)TILL_NOW
(1-1)src/components/date-picker/date-picker-utils.ts (3)
generateDatePickerColumns
(104-144)DatePickerFilter
(21-31)convertStringArrayToDate
(81-102)src/components/date-picker-view/date-picker-view.tsx (1)
RenderLabel
(21-27)
src/components/date-picker/date-picker-utils.ts (2)
src/components/date-picker/util.ts (7)
DateColumnType
(14-20)YEAR_COLUMN
(7-7)MONTH_COLUMN
(8-8)DAY_COLUMN
(9-9)HOUR_COLUMN
(10-10)MINUTE_COLUMN
(11-11)SECOND_COLUMN
(12-12)src/components/date-picker/date-picker-date-utils.ts (1)
convertStringArrayToDate
(253-319)
⏰ 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). (4)
- GitHub Check: build preview
- GitHub Check: compressed-size
- GitHub Check: check
- GitHub Check: size
🔇 Additional comments (4)
src/components/date-picker/date-picker-utils.ts (2)
8-17
: 导入常量与类型整合良好与 util 解耦后更清晰,可读性 OK。
111-143
: 透传 tillNow 与 columns 至底层实现签名扩展与透传无副作用,保持向后兼容。
src/components/date-picker/date-picker-date-utils.ts (2)
8-17
: 常量与类型来源统一到 util消除了运行时循环依赖风险,方向正确。
40-47
: 列到精度映射定义清晰后续过滤/裁剪逻辑可直接复用该映射。
@gemini-code-assist, review again. To check carefully do it has a break change. |
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.
Code Review
这个 PR 引入了一个很棒的功能,允许自定义 DatePicker
的列顺序。代码实现总体上是好的,并且包含了相应的文档和测试。
我发现了一个关于日期解析逻辑的潜在问题,当 columns
属性未提供时,代码实现比较脆弱。我提出了两个相关的修复建议,一个在 date-picker-utils.ts
,另一个在 date-picker-date-utils.ts
。这些修改将通过确保在解析日期字符串时始终使用正确的列顺序来增强代码的健壮性。
除此之外,代码看起来不错。
return quarterUtils.convertStringArrayToDate(value) | ||
} else { | ||
return dateUtils.convertStringArrayToDate(value) | ||
return dateUtils.convertStringArrayToDate(value, columns) |
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.
为了使日期解析更健壮,请将 precision
参数传递给 dateUtils.convertStringArrayToDate
。当 columns
属性为空时,dateUtils.convertStringArrayToDate
需要 precision
来确定正确的默认列顺序。这将修复一个在默认列顺序改变时可能发生的潜在错误。
return dateUtils.convertStringArrayToDate(value, columns) | |
return dateUtils.convertStringArrayToDate(value, columns, precision as DatePrecision) |
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
♻️ Duplicate comments (2)
src/components/date-picker/date-picker-date-utils.ts (2)
123-145
: 过滤用的日期构造未按自定义列顺序映射,列重排/子集时会计算错误
generateColumn
用selected.slice(0, precisionRankRecord[precision])
推断前缀,并在convertStringArrayToDate
中不传columns
。当列被重排或为子集时,前缀与默认 Y→S 顺序不一致,extend.date
会被错误解析,进而导致filter
结果不正确。应基于“实际渲染列顺序 renderedColumns”构造前缀与columns
再传入转换函数。下面补丁同时将columnType
传入,彻底消除错位问题。- const generateColumn = ( - from: number, - to: number, - precision: DatePrecision - ) => { + const generateColumn = ( + from: number, + to: number, + p: DatePrecision, + columnType: DateColumnType + ) => { let column: number[] = [] for (let i = from; i <= to; i++) { column.push(i) } - const prefix = selected.slice(0, precisionRankRecord[precision]) - const currentFilter = filter?.[precision] + // 以“实际渲染列顺序”定位前缀,避免列重排导致取值错位 + const pos = Math.max(0, renderedColumns.indexOf(columnType)) + const prefix = selected.slice(0, pos) + const partialColumns = renderedColumns.slice(0, pos).concat(columnType) + const currentFilter = filter?.[p] if (currentFilter && typeof currentFilter === 'function') { column = column.filter(i => currentFilter(i, { get date() { const stringArray = [...prefix, i.toString()] - return convertStringArrayToDate(stringArray, undefined, precision) + return convertStringArrayToDate(stringArray, partialColumns, p) }, }) ) } return column } @@ - const years = generateColumn(lower, upper, 'year') + const years = generateColumn(lower, upper, 'year', YEAR_COLUMN) @@ - const months = generateColumn(lowerMonth, upperMonth, 'month') + const months = generateColumn(lowerMonth, upperMonth, 'month', MONTH_COLUMN) @@ - const days = generateColumn(lowerDay, upperDay, 'day') + const days = generateColumn(lowerDay, upperDay, 'day', DAY_COLUMN) @@ - const hours = generateColumn(lowerHour, upperHour, 'hour') + const hours = generateColumn(lowerHour, upperHour, 'hour', HOUR_COLUMN) @@ - const minutes = generateColumn(lowerMinute, upperMinute, 'minute') + const minutes = generateColumn(lowerMinute, upperMinute, 'minute', MINUTE_COLUMN) @@ - const seconds = generateColumn(lowerSecond, upperSecond, 'second') + const seconds = generateColumn(lowerSecond, upperSecond, 'second', SECOND_COLUMN)Also applies to: 149-222
139-141
: 在 filter 的日期构造中缺少 columns(与上条合并修复)这里未传入
columns
导致自定义顺序下解析错误,见上方补丁已一并修复为传partialColumns
。
🧹 Nitpick comments (3)
src/components/date-picker/date-picker-date-utils.ts (2)
98-104
: 对选中年份做一次夹取,防御异常输入
selectedYear
可能来自异常值(如解析错位或越界)。建议在使用前按[minYear, maxYear]
再次夹取,避免后续边界判断漂移。- const selectedYear = getValue(YEAR_COLUMN) ?? min.getFullYear() + let selectedYear = getValue(YEAR_COLUMN) ?? min.getFullYear() const selectedMonth = getValue(MONTH_COLUMN) ?? 1 const selectedDay = getValue(DAY_COLUMN) ?? 1 const selectedHour = getValue(HOUR_COLUMN) ?? 0 const selectedMinute = getValue(MINUTE_COLUMN) ?? 0 const selectedSecond = getValue(SECOND_COLUMN) ?? 0 + // 防御性夹取 + selectedYear = Math.max(minYear, Math.min(maxYear, selectedYear))
293-299
: parseInt 明确指定进制,保持一致性为避免隐式进制和风格不一致,建议统一使用
parseInt(x, 10)
。- parseInt(dateParts[YEAR_COLUMN]), - parseInt(dateParts[MONTH_COLUMN]) - 1, - parseInt(dateParts[DAY_COLUMN]), - parseInt(dateParts[HOUR_COLUMN]), - parseInt(dateParts[MINUTE_COLUMN]), - parseInt(dateParts[SECOND_COLUMN]) + parseInt(dateParts[YEAR_COLUMN], 10), + parseInt(dateParts[MONTH_COLUMN], 10) - 1, + parseInt(dateParts[DAY_COLUMN], 10), + parseInt(dateParts[HOUR_COLUMN], 10), + parseInt(dateParts[MINUTE_COLUMN], 10), + parseInt(dateParts[SECOND_COLUMN], 10)src/components/date-picker/date-picker-utils.ts (1)
48-56
: 判定分支建议统一startsWith
语义,保持一致同文件其它位置使用了
startsWith('week'/'quarter')
;这里用includes
含义更宽(潜在误判)。建议统一为startsWith
。- if (precision.includes('week')) { + if (precision.startsWith('week')) { @@ - } else if (precision.includes('quarter')) { + } else if (precision.startsWith('quarter')) {Also applies to: 95-99
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/components/date-picker/date-picker-date-utils.ts
(5 hunks)src/components/date-picker/date-picker-utils.ts
(5 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/components/date-picker/date-picker-date-utils.ts (3)
src/components/date-picker/util.ts (8)
DateColumnType
(14-20)YEAR_COLUMN
(7-7)MONTH_COLUMN
(8-8)DAY_COLUMN
(9-9)HOUR_COLUMN
(10-10)MINUTE_COLUMN
(11-11)SECOND_COLUMN
(12-12)TILL_NOW
(1-1)src/components/date-picker/date-picker-utils.ts (3)
generateDatePickerColumns
(108-148)DatePickerFilter
(21-31)convertStringArrayToDate
(81-106)src/components/date-picker-view/date-picker-view.tsx (1)
RenderLabel
(21-27)
src/components/date-picker/date-picker-utils.ts (5)
src/components/picker-view/columns-extend.tsx (1)
columns
(34-36)src/components/date-picker/util.ts (7)
DateColumnType
(14-20)YEAR_COLUMN
(7-7)MONTH_COLUMN
(8-8)DAY_COLUMN
(9-9)HOUR_COLUMN
(10-10)MINUTE_COLUMN
(11-11)SECOND_COLUMN
(12-12)src/components/date-picker/date-picker-date-utils.ts (2)
DatePrecision
(23-29)convertStringArrayToDate
(257-300)src/components/date-picker/date-picker-week-utils.ts (1)
convertStringArrayToDate
(132-146)src/components/date-picker/date-picker-quarter-utils.ts (1)
convertStringArrayToDate
(106-118)
⏰ 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). (4)
- GitHub Check: build preview
- GitHub Check: compressed-size
- GitHub Check: check
- GitHub Check: size
🔇 Additional comments (4)
src/components/date-picker/date-picker-date-utils.ts (1)
226-238
: “至今”选项插入到首列且联动清空后续列的实现清晰可控,LGTM交互符合预期:首列追加
TILL_NOW
,命中后清空后续列。src/components/date-picker/date-picker-utils.ts (3)
56-79
: 按精度过滤后再按自定义列顺序映射初值,逻辑正确当提供
columns
时先依据精度裁剪,再按自定义顺序映射,避免值长度与可见列不一致问题。
81-106
: 将precision
与columns
透传给底层解析,修正默认顺序依赖问题这里把两个参数一并传递到
dateUtils.convertStringArrayToDate
,可确保解析在列重排/子集时仍正确。
42-79
: 确认:无需修改调用点已核验仓内调用:convertDateToStringArray 在 src/components/date-picker-view/date-picker-view.tsx 与 src/components/date-picker/date-picker.tsx;generateDatePickerColumns 在 src/components/date-picker/date-picker.tsx 与 src/components/date-picker-view/date-picker-view.tsx。底层 date/quarter/week 模块保留单参实现并由顶层委托;columns 为可选参数,现有调用可通过编译,无需改动。
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/components/date-picker/date-picker-date-utils.ts (1)
154-246
: 使用 forEach 和 switch 的实现可以简化虽然当前实现功能正确,但可以考虑使用数组映射来减少重复代码。
可以创建一个配置对象来简化这些重复的 case 分支:
const columnConfigs = { [YEAR_COLUMN]: { lower: minYear, upper: maxYear, selected: selectedYear, precision: 'year' as DatePrecision }, [MONTH_COLUMN]: { lower: isInMinYear ? minMonth : 1, upper: isInMaxYear ? maxMonth : 12, selected: selectedMonth, precision: 'month' as DatePrecision }, // ... 其他配置 } renderedColumns.forEach(columnType => { const config = columnConfigs[columnType] if (!config) return const column = generateColumn(config.lower, config.upper, config.precision, columnType) ret.push( column.map(v => ({ label: renderLabel(config.precision, v, { selected: config.selected === v }), value: v.toString(), })) ) })
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/components/date-picker/date-picker-date-utils.ts
(5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/components/date-picker/date-picker-date-utils.ts (3)
src/components/date-picker/util.ts (8)
DateColumnType
(14-20)YEAR_COLUMN
(7-7)MONTH_COLUMN
(8-8)DAY_COLUMN
(9-9)HOUR_COLUMN
(10-10)MINUTE_COLUMN
(11-11)SECOND_COLUMN
(12-12)TILL_NOW
(1-1)src/components/date-picker/date-picker-utils.ts (3)
generateDatePickerColumns
(108-148)DatePickerFilter
(21-31)convertStringArrayToDate
(81-106)src/components/date-picker-view/date-picker-view.tsx (1)
RenderLabel
(21-27)
⏰ 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). (4)
- GitHub Check: size
- GitHub Check: build preview
- GitHub Check: compressed-size
- GitHub Check: check
🔇 Additional comments (4)
src/components/date-picker/date-picker-date-utils.ts (4)
105-109
: firstDayInSelectedMonth 计算逻辑正确使用
convertStringArrayToDate
传递了正确的参数,包括columns
和precision
,确保了与新 API 的兼容性。
123-152
: generateColumn 函数的 filter 回调需要完善在 Line 142-146 中,
convertStringArrayToDate
的调用看起来是正确的,传递了partialColumns
和precision
参数。
249-260
: tillNow 逻辑实现正确正确检查了
ret.length > 0
并且只在第一列添加 "now" 选项,当选择了 TILL_NOW 时清空后续列的逻辑也是合理的。
279-322
: convertStringArrayToDate 函数重构合理新的实现正确支持了
columns
和precision
参数,使用dateParts
映射的方式也很清晰,能够处理不同的列顺序组合。
@gemini-code-assist pls help to review again |
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.
Code Review
本次 PR 为 DatePicker
组件增加了 columns
属性,支持自定义日期列的顺序和仅选择部分字段,是一个很棒的功能增强。代码实现上做了比较大的重构,特别是 generateDatePickerColumns
函数,使其更加模块化和可读。同时,也为新功能添加了相应的单元测试,值得称赞。
我发现了一个在自定义列顺序时可能导致日期计算错误的 bug,以及一处代码重复的问题。修复这些问题会让这个新功能更加健壮。
convertStringArrayToDate( | ||
[selectedYear, selectedMonth, '1'], | ||
columns ?? defaultColumns, | ||
precision | ||
) |
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.
此处 convertStringArrayToDate
的使用方式存在问题。该函数期望的第一个参数 value
数组中的元素顺序与第二个参数 columns
数组的顺序严格对应。然而,这里硬编码了 [selectedYear, selectedMonth, '1']
,它假定了列的顺序是年、月、日,当 columns
prop 自定义顺序时(例如 ['month', 'day', 'year']
),这会导致错误的日期计算,进而影响天数滚轮的范围。
由于 selectedYear
和 selectedMonth
已经包含了正确的回退值,可以直接使用它们来构造日期,这样更清晰且能避免上述 bug。
new Date(selectedYear, selectedMonth - 1, 1)
const defaultColumns: DateColumnType[] = [] | ||
Object.keys(columnToPrecisionMap).forEach(columnType => { | ||
const precision = columnToPrecisionMap[columnType as DateColumnType] | ||
if (rank >= precisionRankRecord[precision]) { | ||
defaultColumns.push(columnType as DateColumnType) | ||
} | ||
}) |
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.
fix: #6856 支持自定义日期选择器中年、月、日列的显示顺序
Summary by CodeRabbit
新功能
文档
测试
注意