feat: Implement smooth modal closing animations - #41
Conversation
- Add a `window.closeModal` helper in `src/app.js` with timeout and race-condition prevention to handle smooth transitions. - Replace abrupt `overlay.style.display = 'none'` logic with the helper logic for modal overlays. - Define `.closing` keyframes (`ci-overlay-fade-out` and `ci-modal-pop-out`) in `src/style.css` for graceful transitions matching Material Design 3 guidelines. - Append learning logic to `.Jules/palette.md` for consistent UX application across the project architecture. Co-authored-by: bugragungoz <209906170+bugragungoz@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
There was a problem hiding this comment.
Pull request overview
This PR introduces smoother modal close micro-interactions by replacing abrupt display = 'none' closes with a shared close helper that triggers a short CSS exit animation before hiding the overlay.
Changes:
- Added
.closingexit animations for modal overlays/modals in CSS. - Introduced a global
window.closeModal(overlay)helper insrc/app.jsand updated multiple modules to use it when closing overlays. - Added a UX guideline entry documenting the expected modal-close behavior.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/style.css | Adds .closing styles and keyframes for overlay fade-out + modal pop-out. |
| src/app.js | Introduces window.closeModal() and wires it into common close handlers. |
| src/modules/table.js | Uses window.closeModal() for the bulk-delete confirmation overlay. |
| src/modules/projects.js | Uses window.closeModal() after saving project assignment. |
| src/modules/modals.js | Uses window.closeModal() for edit/detail/confirm modal closes. |
| src/modules/import.js | Uses window.closeModal() after import completion. |
| src/modules/export.js | Uses window.closeModal() when choosing an export format. |
| src/modules/bulk_categorize.js | Uses window.closeModal() for the bulk categorize overlay. |
| src/modules/ai.js | Uses window.closeModal() for the categorize progress overlay. |
| .Jules/palette.md | Documents the UX rule for modal close animations and the helper usage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (newName === (isSub ? oldSub : oldCat)) { | ||
| overlay.style.display = 'none'; | ||
| window.closeModal(overlay); | ||
| return; |
| // Clear any pending timeout to prevent race conditions | ||
| if (overlay.dataset.closeTimeout) { | ||
| clearTimeout(parseInt(overlay.dataset.closeTimeout)); | ||
| } | ||
|
|
||
| // Only animate if it's a modal overlay | ||
| if (overlay.classList.contains('modal-overlay')) { | ||
| overlay.classList.add('closing'); | ||
| const timeoutId = setTimeout(() => { | ||
| overlay.style.display = 'none'; | ||
| overlay.classList.remove('closing'); | ||
| delete overlay.dataset.closeTimeout; | ||
| }, 140); | ||
| overlay.dataset.closeTimeout = timeoutId.toString(); |
| window.closeModal = function(overlay) { | ||
| if (!overlay) return; | ||
|
|
||
| // Clear any pending timeout to prevent race conditions | ||
| if (overlay.dataset.closeTimeout) { | ||
| clearTimeout(parseInt(overlay.dataset.closeTimeout)); |
This change implements a smooth micro-UX improvement for modal interactions.
Previously, modals and overlays were abruptly hidden by hardcoding
display = 'none', which breaks common micro-interaction design patterns (like fade and scale-out).Changes include:
window.closeModal(overlay)JavaScript helper insidesrc/app.jsapplying a 140ms timeout with.closinganimation class, including a mechanism to stop potential race condition timeouts.display = 'none'logic with the new helper insideapp.jsand various JS modules (modals.js,ai.js,bulk_categorize.js,import.js,export.js,projects.js,table.js)..closingCSS definitions tosrc/style.css..Jules/palette.mdto reinforce UX consistency across the Vanilla JS/Tauri application.PR created automatically by Jules for task 2196284633839480676 started by @bugragungoz