-
-
Notifications
You must be signed in to change notification settings - Fork 324
fix: presets和maxDate的对比 #930
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?
Conversation
fix: presets和maxDate的比较
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
""" Walkthrough本次更改在日期选择器相关组件中引入了 Changes
Sequence Diagram(s)sequenceDiagram
participant RangePicker/SinglePicker
participant Popup
participant PresetPanel
RangePicker/SinglePicker->>Popup: 传递 maxDate 属性
Popup->>PresetPanel: 传递 maxDate 属性
PresetPanel->>PresetPanel: 判断预设项是否超出 maxDate,超出则禁用
User->>PresetPanel: 鼠标悬停或点击预设项
PresetPanel-->>User: 若禁用则不响应事件
Suggested reviewers
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
src/PickerInput/Popup/PresetPanel.tsxOops! Something went wrong! :( ESLint: 8.57.1 Error: Cannot read config file: /.eslintrc.js
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ 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:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. 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 (
|
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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/PickerInput/Popup/PresetPanel.tsx
(3 hunks)src/PickerInput/Popup/index.tsx
(3 hunks)src/PickerInput/RangePicker.tsx
(1 hunks)src/PickerInput/SinglePicker.tsx
(1 hunks)tests/picker.spec.tsx
(1 hunks)
🔇 Additional comments (6)
src/PickerInput/SinglePicker.tsx (1)
524-524
: 代码修改看起来不错!正确地将
maxDate
属性传递给了Popup
组件。src/PickerInput/Popup/index.tsx (2)
37-38
: 接口定义正确!正确地为
PopupProps
接口添加了可选的maxDate
属性。
72-73
: 属性传递实现正确!正确地从 props 中解构了
maxDate
并传递给PresetPanel
组件。Also applies to: 151-151
tests/picker.spec.tsx (1)
1118-1143
: 测试用例编写得很好!测试清晰地验证了当预设值超过
maxDate
时,不会触发onChange
和onHover
回调的行为。src/PickerInput/Popup/PresetPanel.tsx (1)
3-3
:❌ Incorrect review comment
使用一致的日期库
项目中其他地方使用的是
dayjs
(如测试文件所示),但这里引入了moment
。为保持一致性,建议使用相同的日期库。Also applies to: 30-30
🏁 Script executed:
#!/bin/bash # 检查项目中使用的日期库 echo "=== 检查 dayjs 的使用情况 ===" rg -A 2 "import.*dayjs" --type ts --type tsx echo -e "\n=== 检查 moment 的使用情况 ===" rg -A 2 "import.*moment" --type ts --type tsx echo -e "\n=== 检查 package.json 中的依赖 ===" cat package.json | jq '.dependencies, .devDependencies' | grep -E "(dayjs|moment)"Length of output: 467
Ripgrep 未识别
tsx
类型,导致第一次搜索不生效。我们需要在所有 TypeScript/JavaScript 文件中全局查找dayjs
和moment
的导入,确认项目中实际使用情况,请执行:
🏁 Script executed:
#!/bin/bash echo "=== 检查 dayjs 导入 ===" rg -A2 "import.*dayjs" -g '*.ts*' -g '*.js*' echo -e "\n=== 检查 moment 导入 ===" rg -A2 "import.*moment" -g '*.ts*' -g '*.js*'Length of output: 12359
忽略统一为 dayjs 的建议
项目设计上支持多种日期库(dayjs、moment、luxon 等),PresetPanel.tsx 中引入
moment
是为了为 Moment 类型提供专属预设面板。以下位置也使用了moment
,与之保持一致更合理:
- src/generate/moment.ts
- 测试文件:tests/picker.spec.tsx、tests/generate.spec.tsx、tests/util/commonUtil.tsx 等
- 文档示例:docs/examples 下多处示例均引入
moment
无需将该处替换为 dayjs。
Likely an incorrect or invalid review comment.
src/PickerInput/RangePicker.tsx (1)
595-595
: 新增maxDate
属性以支持禁用超出最大日期的预设项
此处在<Popup>
组件上显式传递了maxDate={maxDate}
,用以让下层PresetPanel
根据上限日期禁用对应的预设选项。请确认:
PopupProps
接口已同步扩展,包含对maxDate
的类型声明。PresetPanel
中对该属性的逻辑处理已正确实现并有对应单元测试覆盖。
export default function PresetPanel<DateType extends object = any>( | ||
props: PresetPanelProps<DateType>, | ||
) { | ||
const { prefixCls, presets, onClick, onHover } = props; | ||
const { prefixCls, presets, onClick, onHover, maxDate } = props; |
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
需要 generateConfig 进行日期比较
为了与项目其他部分保持一致并支持不同的日期库,建议通过 props 传入 generateConfig
。
export interface PresetPanelProps<ValueType = any> {
prefixCls: string;
presets: ValueDate<ValueType>[];
onClick: (value: ValueType) => void;
onHover: (value: ValueType) => void;
- maxDate?: DateType;
+ maxDate?: ValueType;
+ generateConfig: GenerateConfig<ValueType>;
}
export default function PresetPanel<DateType extends object = any>(
props: PresetPanelProps<DateType>,
) {
- const { prefixCls, presets, onClick, onHover, maxDate } = props;
+ const { prefixCls, presets, onClick, onHover, maxDate, generateConfig } = props;
还需要在调用此组件的地方传入 generateConfig
。
🏁 Script executed:
#!/bin/bash
# 检查 PresetPanel 的使用位置,确认是否可以访问 generateConfig
echo "=== 查找 PresetPanel 的使用位置 ==="
rg "PresetPanel" --type ts --type tsx -A 5 -B 5
echo -e "\n=== 检查 generateConfig 的使用模式 ==="
ast-grep --pattern 'generateConfig'
Length of output: 33299
🏁 Script executed:
#!/bin/bash
echo "=== Inspect PresetPanel.tsx ==="
sed -n '1,200p' src/PickerInput/Popup/PresetPanel.tsx || true
echo -e "\n=== Search for maxDate usage ==="
grep -R "maxDate" -n src/PickerInput/Popup/PresetPanel.tsx || true
Length of output: 1930
需要为 PresetPanel 添加 generateConfig 支持,移除对 moment 的直接依赖
为了与项目其他地方保持一致并支持多种日期库,建议对 src/PickerInput/Popup/PresetPanel.tsx
做以下修改:
• 在 Props 接口中:
- 修正错误的
maxDate?: dateTy;
为maxDate?: ValueType;
- 新增
generateConfig: GenerateConfig<ValueType>;
• 在组件签名和解构 props 时引入 generateConfig
• 将
const isDisabled = moment(value).isAfter(maxDate) || moment(value).isSame(maxDate);
替换为
const rawValue = executeValue(value);
const isDisabled =
generateConfig.isAfter(rawValue, maxDate) ||
generateConfig.isSame(rawValue, maxDate);
• 在调用此组件的地方(如 PopupPanel.tsx
)传入 generateConfig
示例 diff:
--- a/src/PickerInput/Popup/PresetPanel.tsx
+++ b/src/PickerInput/Popup/PresetPanel.tsx
@@
-export interface PresetPanelProps<ValueType = any> {
+export interface PresetPanelProps<ValueType = any> {
prefixCls: string;
presets: ValueDate<ValueType>[];
onClick: (value: ValueType) => void;
onHover: (value: ValueType) => void;
- maxDate?: dateTy;
+ maxDate?: ValueType;
+ generateConfig: GenerateConfig<ValueType>;
}
-export default function PresetPanel<DateType extends object = any>(
- props: PresetPanelProps<DateType>,
-) {
- const { prefixCls, presets, onClick, onHover, maxDate } = props;
+export default function PresetPanel<DateType extends object = any>(
+ props: PresetPanelProps<DateType>,
+) {
+ const { prefixCls, presets, onClick, onHover, maxDate, generateConfig } = props;
@@
- const isDisabled = moment(value).isAfter(maxDate) || moment(value).isSame(maxDate);
+ const raw = executeValue(value);
+ const isDisabled =
+ generateConfig.isAfter(raw, maxDate) ||
+ generateConfig.isSame(raw, maxDate);
请同时在使用 <PresetPanel>
的所有调用处(如 PopupPanel)传入当前的 generateConfig
。
🤖 Prompt for AI Agents
In src/PickerInput/Popup/PresetPanel.tsx lines 17 to 20, the component currently
does not accept generateConfig as a prop and directly uses moment for date
comparison, which reduces flexibility and consistency. To fix this, add
generateConfig: GenerateConfig<ValueType> to the component's props interface,
destructure it from props, and replace the moment-based date comparison with
generateConfig.isAfter and generateConfig.isSame calls using the computed
rawValue. Also, ensure that all usages of PresetPanel pass in the generateConfig
prop to maintain proper functionality.
{presets.map(({ label, value }, index) => { | ||
const isDisabled = moment(value).isAfter(maxDate) || moment(value).isSame(maxDate); | ||
return ( | ||
<li | ||
key={index} | ||
onClick={() => { | ||
if (!isDisabled) { | ||
onClick(executeValue(value)); | ||
} | ||
}} | ||
onMouseEnter={() => { | ||
if (!isDisabled) { | ||
onHover(executeValue(value)); | ||
} | ||
}} | ||
onMouseLeave={() => { | ||
onHover(null); | ||
}} | ||
> | ||
{label} | ||
</li> | ||
); | ||
})} |
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
修复禁用逻辑和处理函数值
当前实现存在几个问题需要修复:
- 根据 PR 目标,应该只禁用大于
maxDate
的日期,而不是大于等于 - 没有处理
value
为函数的情况 - 没有为禁用的预设项添加视觉指示
- {presets.map(({ label, value }, index) => {
- const isDisabled = moment(value).isAfter(maxDate) || moment(value).isSame(maxDate);
- return (
- <li
- key={index}
- onClick={() => {
- if (!isDisabled) {
- onClick(executeValue(value));
- }
- }}
- onMouseEnter={() => {
- if (!isDisabled) {
- onHover(executeValue(value));
- }
- }}
- onMouseLeave={() => {
- onHover(null);
- }}
- >
- {label}
- </li>
- );
- })}
+ {presets.map(({ label, value }, index) => {
+ const actualValue = executeValue(value);
+ const isDisabled = maxDate && generateConfig.isAfter(actualValue, maxDate);
+ return (
+ <li
+ key={index}
+ className={isDisabled ? `${prefixCls}-presets-item-disabled` : undefined}
+ onClick={() => {
+ if (!isDisabled) {
+ onClick(actualValue);
+ }
+ }}
+ onMouseEnter={() => {
+ if (!isDisabled) {
+ onHover(actualValue);
+ }
+ }}
+ onMouseLeave={() => {
+ onHover(null);
+ }}
+ >
+ {label}
+ </li>
+ );
+ })}
注意:这里假设组件可以访问 generateConfig
。如果不能,需要将其作为 prop 传入。
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/PickerInput/Popup/PresetPanel.tsx lines 29 to 51, the code checks if a
preset date is after or the same as maxDate to disable it, but the logic should
only disable dates strictly after maxDate. Also, the code does not handle cases
where value might be a function, nor does it visually indicate disabled items.
Fix this by updating the isDisabled condition to only check if value is after
maxDate, add handling for function values, and add a disabled style or attribute
to visually distinguish disabled items.
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)
tests/picker.spec.tsx (1)
1200-1224
: 建议增加更多测试场景当前测试覆盖了预设值超过
maxDate
的情况。建议额外测试以下场景以提高覆盖率:
- 预设值在
maxDate
范围内时,应该正常触发回调- 同时设置
minDate
和maxDate
时的边界情况- RangePicker 组件中的类似行为
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/PickerInput/Popup/index.tsx
(3 hunks)src/PickerInput/RangePicker.tsx
(1 hunks)src/PickerInput/SinglePicker.tsx
(1 hunks)tests/picker.spec.tsx
(1 hunks)
🔇 Additional comments (5)
src/PickerInput/SinglePicker.tsx (1)
537-537
: 代码变更正确!正确地将
maxDate
属性传递给Popup
组件,使得子组件能够访问最大日期限制。src/PickerInput/Popup/index.tsx (2)
47-48
: 属性传递实现正确!代码变更遵循了现有的模式:
- 在
PopupProps
接口中正确添加了可选的maxDate
属性- 从 props 中解构
maxDate
- 将其传递给
PresetPanel
组件这确保了
PresetPanel
能够基于最大日期限制来禁用相应的预设选项。Also applies to: 84-85, 188-188
188-188
:❓ Verification inconclusive
建议验证 PresetPanel 的实现
虽然
maxDate
被正确传递给了PresetPanel
,但建议确认PresetPanel
组件已正确实现了基于maxDate
禁用预设项的逻辑。运行以下脚本来验证 PresetPanel 的实现:
🏁 Script executed:
#!/bin/bash # 描述:检查 PresetPanel 组件是否正确处理 maxDate 属性 # 查找 PresetPanel 组件的实现 fd "PresetPanel" --type f --extension tsx --extension ts --exec rg -A 20 "maxDate" {} \; # 查找 PresetPanel 中与禁用逻辑相关的代码 ast-grep --pattern 'const PresetPanel = $_' src/PickerInput/Popup/PresetPanel.tsxLength of output: 1306
确认 PresetPanel 的 maxDate 禁用逻辑
已验证
src/PickerInput/Popup/PresetPanel.tsx
中对maxDate
的处理逻辑:
- 在渲染预设项时,通过
moment(value).isAfter(maxDate) || moment(value).isSame(maxDate)
判断并禁用大于或等于maxDate
的值。请确认以下事项:
- 预期是否要同时禁用等于
maxDate
的预设项?
- 如果应允许等于
maxDate
,建议将禁用条件修改为仅moment(value).isAfter(maxDate)
。tests/picker.spec.tsx (1)
1200-1224
: 测试用例实现完善!新增的测试用例正确验证了当预设日期超过
maxDate
时的行为:
- 设置明天作为预设值,今天作为
maxDate
,使预设项被禁用- 验证了鼠标悬停和点击事件都不会触发相应的回调函数
- 测试逻辑清晰,符合现有的测试模式
这个测试用例很好地覆盖了 PR 要解决的核心问题。
src/PickerInput/RangePicker.tsx (1)
624-624
: 正确的属性传递实现向 Popup 组件添加
maxDate
属性是正确的实现。这个修改使得 Popup 组件能够感知最大允许日期,从而支持禁用超出最大日期的预设项功能,与 PR 目标完全一致。
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #930 +/- ##
=======================================
Coverage 98.80% 98.80%
=======================================
Files 65 65
Lines 2669 2675 +6
Branches 737 742 +5
=======================================
+ Hits 2637 2643 +6
Misses 29 29
Partials 3 3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
maxDate和presets的值的对比,禁用点击 ant-design/ant-design#53693
Summary by CodeRabbit
新功能
测试