Skip to content

feat(calendar-picker): 添加日期跳转边界处理#7048

Open
Passing-of-A-Dream wants to merge 5 commits into
ant-design:masterfrom
Passing-of-A-Dream:fix-calendar-jumpTo-min
Open

feat(calendar-picker): 添加日期跳转边界处理#7048
Passing-of-A-Dream wants to merge 5 commits into
ant-design:masterfrom
Passing-of-A-Dream:fix-calendar-jumpTo-min

Conversation

@Passing-of-A-Dream
Copy link
Copy Markdown
Contributor

@Passing-of-A-Dream Passing-of-A-Dream commented May 18, 2026

close #6518

Summary by CodeRabbit

  • 错误修复

    • 优化日历选择器跳转:跳转时会在存在最小/最大边界时钳制到边界月份,未设置边界时会自动扩展显示范围以包含目标月份;今日跳转已统一使用相同规则,组件的显示范围会与外部边界同步更新。
  • 测试

    • 添加跳转相关测试,覆盖范围扩展、选中日期保留及边界钳制行为。

Review Change Stack

- 新增 jumpToPage 方法处理默认 min/max 边界
- 重构 jumpTo 和 jumpToToday 使用新方法
- 添加测试验证边界扩展逻辑
@dosubot dosubot Bot added size:S This PR changes 10-29 lines, ignoring generated files. feature labels May 18, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 18, 2026

Preview is ready

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 27abcb5f-6b62-4834-a9ea-f104e1348511

📥 Commits

Reviewing files that changed from the base of the PR and between f719794 and a005045.

📒 Files selected for processing (1)
  • src/components/calendar-picker-view/calendar-picker-view.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/calendar-picker-view/calendar-picker-view.tsx

📝 Walkthrough

Walkthrough

新增内部 jumpToPage 以统一处理 jumpTo/jumpToToday 的跳转逻辑:把 Page 转为月份 dayjs、在无外部 min/max 时扩展 defaultMin/defaultMax、在有外部边界时钳制目标月份,随后更新 current 并触发滚动;增加三组测试覆盖扩展、保持选中项与钳制行为。

Changes

日历跳转统一化

Layer / File(s) Summary
jumpToPage 内部实现与逻辑统一
src/components/calendar-picker-view/calendar-picker-view.tsx
新增 VISIBLE_MONTHSalignRange,调整 defaultMin/defaultMax 的初始化与 useEffect 依赖;新增 jumpToPage(page),将 Page 转为 dayjs 月份、按外部 min/max 做钳制、在必要时扩展默认边界,并最终调用 setCurrent(next)scrollTo(next)useImperativeHandle 中的 jumpTojumpToToday 改为委托该方法。
边界扩展与钳制行为测试
src/components/calendar-picker-view/tests/calendar-picker-view.test.tsx
新增三条测试:验证无 min/maxjumpTo 会扩展/重置渲染窗口、验证 jumpTo 保持已选日期仍在渲染范围内、验证在设置 min/maxjumpTo 会将目标钳制到边界月份(2023-1 / 2023-12)。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 小兔轻蹦向月台,
跳转有法不迷开,
边界伸缩心自知,
选中如旧并且在,
测试护航步更稳。

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 拉取请求标题清晰准确地概括了主要变更:为日期跳转功能添加边界处理逻辑,这正是代码更改的核心内容。
Linked Issues check ✅ Passed 代码实现完整满足 issue #6518 的需求:在 CalendarPickerView 中新增统一的 jumpToPage 方法,对目标月份进行 min/max 边界钳制,修复了设置 min 属性后 jumpTo 和 jumpToToday 方法失效的问题。
Out of Scope Changes check ✅ Passed 所有变更均在范围内,均为实现日期跳转边界处理功能的必要修改,包括核心逻辑优化和相应的测试用例补充。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 18, 2026

npm i https://pkg.pr.new/antd-mobile@7048

commit: a005045

@codecov
Copy link
Copy Markdown

codecov Bot commented May 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.97%. Comparing base (7e59dc8) to head (a005045).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7048      +/-   ##
==========================================
- Coverage   92.97%   92.97%   -0.01%     
==========================================
  Files         337      337              
  Lines        7374     7388      +14     
  Branches     1868     1847      -21     
==========================================
+ Hits         6856     6869      +13     
- Misses        482      511      +29     
+ Partials       36        8      -28     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/components/calendar-picker-view/tests/calendar-picker-view.test.tsx (1)

198-235: ⚡ Quick win

建议补充“已设置 min”场景的回归测试。

当前用例只验证了未设置 min/max 时的自动扩展;但该 PR 关联问题是 min 存在时 jumpTo/jumpToToday 异常。建议新增一条用例覆盖 min 已设置时的跳转行为(边界内可跳转、越界按边界处理),避免问题回归。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/calendar-picker-view/tests/calendar-picker-view.test.tsx`
around lines 198 - 235, Add a regression test that covers the case when a `min`
(and optionally `max`) prop is provided so `jumpTo`/`jumpToToday` respect
boundaries: create a test (e.g., "jumpTo respects provided min/max boundaries")
that renders a component like the existing test but passes `min={{ year: 2022,
month: 3 }}` to CalendarPickerView (using the same `CalendarPickerViewRef` and
`jumpTo` buttons), then assert that a `jumpTo` to an in-range month (e.g.,
2022-4) renders that month, while a `jumpTo` to an out-of-range past month
(e.g., 2020-1) results in rendering clipped to the `min`
(data-year-month="2022-3"); also add a check for `jumpToToday` behavior when
today is before the `min` to ensure it lands on `min`.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/calendar-picker-view/calendar-picker-view.tsx`:
- Around line 165-175: The jumpToPage flow sets next = convertPageToDayjs(page)
but never clamps that date to external props.min/props.max, so setCurrent(next)
and scrollTo(next) can move outside the rendered range; update jumpToPage to
first clamp next to the inclusive [props.min, props.max] bounds at month
granularity (use startOf('month')/endOf('month') comparisons or isBefore/isAfter
with month-normalized values), then keep the existing behavior that expands
defaultMin/defaultMax only when props.min/props.max are not provided (i.e., call
setDefaultMin/setDefaultMax as before), and finally call setCurrent(clampedNext)
and scrollTo(clampedNext); apply the same clamping change to the analogous jump
handler later in the file (the other jump/scroll block referenced around lines
188-193).

---

Nitpick comments:
In `@src/components/calendar-picker-view/tests/calendar-picker-view.test.tsx`:
- Around line 198-235: Add a regression test that covers the case when a `min`
(and optionally `max`) prop is provided so `jumpTo`/`jumpToToday` respect
boundaries: create a test (e.g., "jumpTo respects provided min/max boundaries")
that renders a component like the existing test but passes `min={{ year: 2022,
month: 3 }}` to CalendarPickerView (using the same `CalendarPickerViewRef` and
`jumpTo` buttons), then assert that a `jumpTo` to an in-range month (e.g.,
2022-4) renders that month, while a `jumpTo` to an out-of-range past month
(e.g., 2020-1) results in rendering clipped to the `min`
(data-year-month="2022-3"); also add a check for `jumpToToday` behavior when
today is before the `min` to ensure it lands on `min`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 436ef4f2-3394-439a-9ee7-ae8cfaf1dbef

📥 Commits

Reviewing files that changed from the base of the PR and between 7e59dc8 and 628e91a.

📒 Files selected for processing (2)
  • src/components/calendar-picker-view/calendar-picker-view.tsx
  • src/components/calendar-picker-view/tests/calendar-picker-view.test.tsx

Comment thread src/components/calendar-picker-view/calendar-picker-view.tsx
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors calendar navigation by introducing a jumpToPage function that automatically expands the rendering range when bounds are not explicitly defined. A review comment identifies critical issues regarding boundary clamping for fixed ranges and potential date rollover bugs when using Dayjs, providing a more robust implementation suggestion.

Comment on lines +165 to +175
const jumpToPage = (page: Page) => {
const next = convertPageToDayjs(page)
if (!props.min && next.isBefore(defaultMin)) {
setDefaultMin(next.date(1))
}
if (!props.max && next.isAfter(defaultMax)) {
setDefaultMax(next.endOf('month'))
}
setCurrent(next)
scrollTo(next)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The jumpToPage function has two issues:

  1. Boundary Clamping: If props.min or props.max are provided, the rendering range is fixed. If the target page is outside these bounds, setCurrent(next) will set an unreachable month, and scrollTo(next) will fail because the corresponding DOM element won't be rendered. The target date should be clamped to the allowed range defined by minDay and maxDay.
  2. Dayjs Rollover Bug: The convertPageToDayjs utility (used here) has a potential bug where it can roll over to the wrong month if today is the 31st (e.g., calling it for February on January 31st might result in March). It's safer to create the dayjs object by setting the date to the 1st before setting the year and month.

Additionally, next.date(1) is redundant if the date is already set to the 1st.

  const jumpToPage = (page: Page) => {
    // Use a safe way to create the dayjs object to avoid rollover issues when today is the 31st
    let next = dayjs().date(1).year(page.year).month(page.month - 1)

    if (next.isBefore(minDay, 'month')) {
      if (props.min) {
        next = minDay.date(1)
      } else {
        setDefaultMin(next)
      }
    } else if (next.isAfter(maxDay, 'month')) {
      if (props.max) {
        next = maxDay.date(1)
      } else {
        setDefaultMax(next.endOf('month'))
      }
    }

    setCurrent(next)
    scrollTo(next)
  }

- 当跳转日期超出min/max范围时自动修正到边界值
- 添加测试用例验证边界条件处理
- 调整跳转逻辑保持选中日期在渲染范围内
- 优化默认最小/最大日期的更新条件
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:S This PR changes 10-29 lines, ignoring generated files. labels May 18, 2026
setDefaultMin(next)
}
if (!props.max) {
setDefaultMax(next.add(6, 'month').endOf('month'))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

有点 hardcode,要不然抽一个 alignRange 的方法。然后初始化和jumpTo 都通过这个方法来重置好了?

- 提取 VISIBLE_MONTHS 为常量
- 新增 alignRange 方法统一处理边界对齐
- 默认 max 值调整为月份结束日期
- 简化默认max的计算逻辑
- 保持min和max计算方式一致
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CalendarPickerView 相关组件设置了 min 属性后 jumpTo jumpToToday 等方法不生效

2 participants