fix: standalone BottomSheet dismisses on Escape during IME composition-cancel - #5357
fix: standalone BottomSheet dismisses on Escape during IME composition-cancel#5357HelloOjasMutreja wants to merge 2 commits into
Conversation
The standalone BottomSheet's handleKeyDown read a bare `event.key === 'Escape'`, so a CJK user pressing Escape to cancel an in-progress IME composition dismissed the sheet instead. Dialog and BottomSheetSwitcher already guard their own Escape handling with isImeKeyEvent(); the standalone sheet's handleKeyDown was the one path that didn't. handleCancel is left unguarded, matching both of those: it only ever fires from the browser's native close-watcher, which does not run when handleKeyDown's preventDefault() is skipped for a composing keydown.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR Analysis Report📚 Storybook PreviewView Storybook for this PR 🧪 Sandbox PreviewView Sandbox for this PR Modified ComponentsBottomSheet (@astryxdesign/core) · View in Storybook
Bundle Size Summary
Accessibility AuditStatus: No accessibility violations detected. Generated by PR Enrichment workflow | Storybook | Sandbox | View full report |
|
Closing as a duplicate: #5322 landed on main with the same fix (isImeKeyEvent guard on handleKeyDown, same reasoning for leaving handleCancel unguarded) while this was in review. Thanks for beating me to it! |
|
Thanks for jumping on this — your read of the bug was right. Two PRs came in for #5302 and we've gone with #5322, now merged. The deciding difference is small and not obvious: it calls Worth knowing the comment at Please do send more. If you'd rather talk something through with a person, we're in Discord. [Reviewed by Robohands] |
Fixes #5302.
Problem
The standalone
BottomSheet'shandleKeyDownreads a bareevent.key === 'Escape', so a CJK (Korean/Japanese/Chinese) user pressing Escape to cancel an in-progress IME composition dismisses the sheet instead of just cancelling the candidate.Dialogguards this in its nativekeydownlistener viaisImeKeyEvent(event), andBottomSheetSwitcher's ownhandleKeyDownguards it the same way (!isImeKeyEvent(event.nativeEvent)). The standalone sheet'shandleKeyDownwas the one path in this family that didn't.Reachable via the documented
purpose="form"and mobile-keyboard (height="tall") use cases, which put a text field inside a standalone sheet.Fix
One deviation from the issue's suggested fix: I left
handleCancelunguarded. Checked both existing precedents first — neitherDialog.handleCancelnorBottomSheetSwitcher.handleCancelcheckisImeKeyEvent, onlyhandleKeyDowndoes in both. That's not an oversight:handleCancelonly runs off the browser's native<dialog>close-watcher, which doesn't fire whenhandleKeyDownskipspreventDefault()for a composing keydown — the browser's own IME handling takes it from there. GuardinghandleCanceltoo would be dead code with no existing precedent for it anywhere in this component family.Verification
Added a regression test (
ignores Escape while an IME composition is active) mirroring the existing one inBottomSheetSwitcher.test.tsx. Confirmed it fails against the pre-fix code (reverted the implementation locally, test failed withonOpenChangecalled twice) and passes with the fix. FullBottomSheetsuite (186 tests) passes, typecheck and lint are clean.Not a visual change, so no before/after screenshot.