Skip to content

fix(RelativeDateField): read latest state on deferred blur#287

Open
dgaponov wants to merge 1 commit into
mainfrom
fix/relative-date-field-async-blur
Open

fix(RelativeDateField): read latest state on deferred blur#287
dgaponov wants to merge 1 commit into
mainfrom
fix/relative-date-field-async-blur

Conversation

@dgaponov

Copy link
Copy Markdown
Contributor

Проблема

После обновления @gravity-ui/uikit (7.45.1) useFocusWithin стал диспатчить onBlurWithin асинхронно — через setTimeout(…, 0). Из-за этого падал тест RelativeDateField > clears invalid draft text when controlled value becomes null:

  1. Пользователь вводит невалидный now - 1x (это draft; закоммиченное значение остаётся now - 1d).
  2. Клик по «reset» → синхронно setValue(null) → текст сбрасывается в ''.
  3. Позже срабатывает отложенный blur → confirmValue() выполняется со старым замыканием (text="now - 1x", value="now - 1d"), восстанавливает и заново коммитит now - 1d, затирая сброс.

Исправление

  • useRelativeDateFieldState: confirmValue читает актуальные text/value/parsedDate из ref, а не из замыкания рендера. Теперь отложенный blur, сработавший после внешнего обновления значения, видит свежее состояние (text="") и корректно выходит, ничего не перекоммичивая.
  • Тест restores the last correct value on blur: падал по той же причине (проверял значение синхронно, до отложенного blur). Заменён на await expect.poll(...), чтобы дождаться асинхронного blur.

Проверка

npx vitest run --project unit src/components/RelativeDateField — все 6 тестов проходят стабильно (проверено несколькими прогонами), lint чистый.

🤖 Generated with Claude Code

useFocusWithin now dispatches onBlurWithin asynchronously (via
setTimeout), so confirmValue could run after an external value update
with a stale render closure and re-commit the old value — clobbering a
reset to null. Read the current text/value/parsedDate from a ref so the
deferred blur always sees fresh state.

Also await the async blur in the "restores last correct value" test,
which asserted synchronously before the deferred blur fired.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 66.47% 1727 / 2598
🔵 Statements 66.64% 1762 / 2644
🔵 Functions 70.4% 345 / 490
🔵 Branches 60.69% 1416 / 2333
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
src/components/RelativeDateField/hooks/useRelativeDateFieldState.ts 88.88% 86.04% 100% 88.63% 81, 99, 115, 121-122
Generated in workflow #101 for commit d4196da by the Vitest Coverage Report Action

@gravity-ui-bot

Copy link
Copy Markdown
Contributor

Preview is ready.

@gravity-ui-bot

Copy link
Copy Markdown
Contributor

🎭 Tests Report is ready.
🎭 Coverage Report is ready.

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.

2 participants