Skip to content

fix: discard a rejected value on popup close - #1020

Open
Ye-YiChen wants to merge 1 commit into
react-component:masterfrom
Ye-YiChen:fix-picker-reject-value-on-popup-close
Open

Ye-YiChen wants to merge 1 commit into
react-component:masterfrom
Ye-YiChen:fix-picker-reject-value-on-popup-close

Conversation

@Ye-YiChen

@Ye-YiChen Ye-YiChen commented Oct 12, 2026 •

Copy link
Copy Markdown

Fixes #1018

Problem: a date rejected by disabledDate is not reverted when the input is blurred (the popup closes) — the input keeps showing it while the committed value was never updated. Pressing Enter for the same input works.

Why: resolveAction decides the action before the submit happens, so it cannot know the submit will be rejected. On the blur path the popup close is what triggers the submit; after the rejection reset() only clears the bookkeeping and leaves the temporary value behind, and switchNext is a submit action, so nothing ever reaches resetValue. Enter only works by accident: its close event arrives one step later and lands on the currentIndex === null branch.

Changes

  • flushSubmit now reports the submit result (boolean | void), and submitField discards the temporary value when it comes back false — equivalent to running resetAll on the spot.
  • preserveInvalidOnBlur keeps the previous behaviour by skipping that discard (the default is to discard).
  • RangePicker goes through the same path and is covered as well.

Tests in tests/blur.spec.tsx: rejected → reverted, rejected with preserveInvalidOnBlur → kept, accepted → committed.

One thing to confirm: Does the preserveInvalidOnBlur prop affect disabledDate?

A field submitted by closing the popup kept its temporary calendar value
when the submit was rejected by disabledDate, so the selector displayed a
value the committed value never accepted. Blur and Enter also behaved
differently for the same input, since Enter's close event arrives one step
later and lands on the `currentIndex === null` branch.

Let `flushSubmit` report whether the flushed value was accepted, and reset
the temporary value inside `submitField` when it was rejected. Consumers
that explicitly ask for the typed text to survive blur
(`preserveInvalidOnBlur`) keep the previous behaviour.
@vercel

vercel Bot commented Oct 12, 2026

Copy link
Copy Markdown

@Ye-YiChen is attempting to deploy a commit to the afc163's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9584db6b-8314-49ad-9766-e17f7f5b549f

📥 Commits

Reviewing files that changed from the base of the PR and between 97fbf8a and a9cb0bb.


📒 Files selected for processing (5)
  • src/PickerInput/RangePicker.tsx
  • src/PickerInput/SinglePicker.tsx
  • src/PickerInput/hooks/useRangeValue.ts
  • src/PickerInput/hooks/useRangeValueChange.ts
  • tests/blur.spec.tsx

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.



Walkthrough

单日期和范围日期选择器现可获知字段提交的校验结果。提交被拒绝时,值变更流程默认重置临时值;启用 preserveInvalidOnBlur 时保留输入。新增测试验证拒绝值回退、保留输入和获准日期提交。

Changes

被拒绝日期的失焦处理

Layer / File(s) Summary
提交结果传递
src/PickerInput/hooks/useRangeValue.ts、src/PickerInput/hooks/useRangeValueChange.ts、src/PickerInput/RangePicker.tsx、src/PickerInput/SinglePicker.tsx
flushSubmit 和两个选择器的 flushFieldSubmit 传递提交校验结果。两个选择器将 preserveInvalidOnBlur 传入值变更流程。
拒绝值处理与验证
src/PickerInput/hooks/useRangeValueChange.ts、tests/blur.spec.tsx
提交返回 false 时,submitField 默认重置临时值;启用保留配置时不重置。新增测试覆盖拒绝日期回退、保留拒绝输入及获准日期触发 onChange。

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: zombiej

Merge Risk: ⚪ Minimal · up to a9cb0

With this change, a date rejected by disabledDate reverts to the previous value when the picker closes, unless preserveInvalidOnBlur keeps the typed input. Accepted dates are still submitted normally. No outstanding issue blocks merging.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 5 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed PR 满足直接关联的开放问题 [#1018]。useRangeValue 的 flushSubmit 返回业务校验结果。useRangeValueChange.submitField 在结果为 false 且未启用 preserveInvalidOnBlur 时调用 resetValue(),因此失焦提交被 disabledDate 拒绝时会恢复受控值。`SingleP…
Out of Scope Changes check Passed 改动均与 [#1018] 的提交失败处理相关。RangePicker 复用同一提交路径,属于相同问题的相关场景。新增测试验证默认回退、preserveInvalidOnBlur 保留和成功提交,没有发现与该问题无关的代码或测试改动。
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed 标题准确概括了主要变更:弹层关闭时丢弃被拒绝的临时值。该描述与代码修改和测试目标一致,且简洁明确。

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Commit to this branch
  • Create a new PR

🧪 Generate unit tests (beta)
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Disabled date entered manually is not reverted on blur

1 participant