Repository navigation
feat(frontend): add responsive mobile drawer and touch gestures to Co… - #1685
Conversation
…mmand Palette - Render the palette as a bottom drawer below sm (drag handle, 85dvh max height, safe-area padding, slide-up entry) and keep the centered palette on larger screens - Swipe down to dismiss via a new reusable useSwipeToDismiss hook: the drawer follows the finger, snaps back below the distance/velocity threshold, and only drags from the command list when it is scrolled to the top - Add a header search button (below lg) and openCommandPalette() event so touch users can open the palette without Cmd/Ctrl+K - Add a Cancel button and touch-specific footer hint; hide keyboard hints on mobile; tap feedback and touch-manipulation on options - Focus the dialog instead of the input on coarse pointers so the on-screen keyboard does not cover the drawer; lock body scroll while open - Leave swipe handling to the converter view, which has its own drawer - Fix flaky focus tests by waiting for the rAF focus in openPalette(), and update the outdated snapshot Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@Thosine-01 is attempting to deploy a commit to the Emmanuel's projects Team on Vercel. A member of the Team first needs to authorize it. |
…touch-gestures-to-command-palette
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 38865302 | Triggered | Generic High Entropy Secret | 2905902 | backend/src/routes/sep0001.test.js | View secret |
| 38865302 | Triggered | Generic High Entropy Secret | 2905902 | backend/src/lib/sep0001-generator.sanitization.test.js | View secret |
| 38864685 | Triggered | Generic High Entropy Secret | 2905902 | backend/src/lib/exchange-rate-oracle-sanitizer.test.js | View secret |
| 38865486 | Triggered | Generic High Entropy Secret | 2905902 | backend/src/lib/websocket-relay-retry.test.js | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secrets safely. Learn here the best practices.
- Revoke and rotate these secrets.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
Summary
Closes #1508
Makes the Command Palette usable on phones. Before this change it could only be opened with Cmd/Ctrl+K, so touch users couldn't reach it at all. It now has an on-screen trigger, opens as a bottom drawer on mobile, and can be swiped down to close. Desktop behaviour is unchanged.
What changed
Opening on touch devices
CommandPaletteTriggersearch button in the dashboard header, shown belowlgnext to the notification bellopenCommandPalette()helper (dispatches acommand-palette:openwindow event), so any component can open the paletteResponsive drawer (
CommandPalette.tsx)smthe palette is a bottom sheet with a drag handle, a85dvhmax height andenv(safe-area-inset-bottom)padding. It slides up with amotion-safeanimation.smup, the centered palette is unchangedmax-h-72on desktopTouch gestures
AssetConverteralready uses swipe-down for "back". The palette shell also dropsoverflow-hidden/backdrop-bluron mobile in that view so the converter's fixed drawer isn't clipped.New reusable hook:
useSwipeToDismiss(src/hooks/useSwipeToDismiss.ts)offset,draggingand touchhandlers, and acceptsenabled,scrollRef,distanceandvelocity.shouldDismissSwipe()function for testing the thresholdstouchStart/touchEndlogic) can adopt itMobile UX details
ESChint on mobile, since touch users have no Escape keyactive:states) andtouch-manipulationon optionsAccessibility
aria-labelandaria-haspopup="dialog"; the drag handle isaria-hiddenTest fixes
On
main,CommandPalette.test.tsxhad 2 failing tests:openPalette()waited for the dialog but not for therequestAnimationFramefocus. It now waits for focus inside the dialog, and the suite passes reliably (verified 3 consecutive runs).Files
frontend/src/components/CommandPalette.tsx: drawer layout, gestures, trigger, open event, touch focus handlingfrontend/src/hooks/useSwipeToDismiss.ts: new reusable hookfrontend/src/hooks/useSwipeToDismiss.test.ts: new, 9 testsfrontend/src/components/CommandPalette.test.tsx: 9 new mobile drawer tests plus theopenPalette()fixfrontend/src/components/__snapshots__/CommandPalette.test.tsx.snap: regeneratedfrontend/src/app/(authenticated)/layout.tsx: header triggerfrontend/tailwind.config.js:palette-drawer-inkeyframeTesting
npx vitest run src/components/CommandPalette.test.tsx src/components/CommandPalette.test.ts src/hooks/useSwipeToDismiss.test.ts: 53/53 passing. Type check and lint are clean.New test coverage:
openCommandPalette()enabled: false,scrollRefguard, touch cancelManual testing
Screenshots
Notes
This PR and # both add keyframes in the same place in
tailwind.config.js, so whichever merges second will probably need a small conflict resolved.🤖 Generated with Claude Code