feat: Add footer bento spotlight, page transitions and features in ed…#449
feat: Add footer bento spotlight, page transitions and features in ed…#449dhawneetg wants to merge 3 commits into
Conversation
|
Someone is attempting to deploy a commit to the adityapaul2603-gmailcom's projects Team on Vercel. A member of the Team first needs to authorize it. |
✅ Deploy Preview for astounding-nougat-da0f6a ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds Framer Motion route-change animations to AppLayout; upgrades CodeEditor with mouse-tracking spotlight, Monaco cursor subscriptions, download-to-file, a status HUD, and an animated shortcuts drawer; refactors Footer into spotlight-enabled FooterBentoCard tiles with smooth scroll behavior. ChangesInteractive UI Enhancements with Spotlight Effects & Route Animations
Sequence Diagram(s)sequenceDiagram
participant User
participant CodeEditor
participant Monaco
participant StatusHUD
participant ShortcutsDrawer
User->>CodeEditor: mousemove over editor card
CodeEditor->>CodeEditor: compute mousePosition (relative to card)
CodeEditor->>CodeEditor: update spotlight (motion)
User->>Monaco: type / move cursor
Monaco->>CodeEditor: cursor position change event
CodeEditor->>StatusHUD: update line/char and cursor display
User->>StatusHUD: click Shortcuts toggle
StatusHUD->>ShortcutsDrawer: showShortcuts = true
ShortcutsDrawer->>ShortcutsDrawer: animate entry (AnimatePresence)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 6 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (6 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/components/Footer.jsx (2)
231-233: ⚡ Quick winUse a stable key instead of array index for algorithm cards.
Line 232 uses
key={i}. Usealgo.path(or another stable unique field) to prevent reconciliation/state bugs and reduce avoidable remounts if order changes.Suggested change
- {algorithms.map((algo, i) => ( - <FooterBentoCard key={i} algo={algo} /> + {algorithms.map((algo) => ( + <FooterBentoCard key={algo.path} algo={algo} /> ))}As per coding guidelines, “Focus on React best practices, avoiding unnecessary re-renders, and efficient state management.”
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/Footer.jsx` around lines 231 - 233, Replace the unstable index key on algorithm cards with a stable unique identifier: in the algorithms.map callback that renders <FooterBentoCard key={i} algo={algo} />, use a unique field from each algo (e.g., algo.path or another guaranteed-unique property) as the key so React can correctly reconcile items and avoid unnecessary remounts.
11-18: ⚡ Quick winAvoid per-mousemove React state updates in spotlight tracking.
Line 14 and Line 28/29 cause frequent rerenders on every cursor move/hover event. For this visual-only effect, prefer CSS variables on the element ref (optionally throttled with
requestAnimationFrame) to keep React render cycles lower.Suggested refactor
const handleMouseMove = (e) => { if (!cardRef.current) return const rect = cardRef.current.getBoundingClientRect() - setMousePosition({ - x: e.clientX - rect.left, - y: e.clientY - rect.top, - }) + const x = e.clientX - rect.left + const y = e.clientY - rect.top + cardRef.current.style.setProperty('--spotlight-x', `${x}px`) + cardRef.current.style.setProperty('--spotlight-y', `${y}px`) }style={{ background: isHovering - ? `radial-gradient(300px circle at ${mousePosition.x}px ${mousePosition.y}px, var(--theme-border-strong), transparent 45%)` + ? `radial-gradient(300px circle at var(--spotlight-x) var(--spotlight-y), var(--theme-border-strong), transparent 45%)` : 'transparent', }}As per coding guidelines, “Focus on React best practices, avoiding unnecessary re-renders, and efficient state management.”
Also applies to: 27-30, 37-49
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/Footer.jsx` around lines 11 - 18, The handler handleMouseMove currently calls setMousePosition on every mousemove causing frequent React rerenders; instead compute local x/y from cardRef.getBoundingClientRect() and write them into CSS custom properties on the DOM node (e.g., cardRef.current.style.setProperty('--spot-x', `${x}px`), '--spot-y' ) and remove the setMousePosition state usage; to avoid too many updates, wrap the DOM updates in a requestAnimationFrame loop (or throttle) and ensure your event listeners read from cardRef and only schedule the rAF update, then apply styles directly on cardRef.current so the spotlight is driven by CSS variables rather than React state.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/CodeEditor.jsx`:
- Around line 92-102: The Monaco editor cursor subscription created in
handleEditorMount via editor.onDidChangeCursorPosition(...) returns an
IDisposable that must be saved and disposed to avoid leaks; modify
handleEditorMount (and/or add a useEffect) to store the returned disposable
(from editor.onDidChangeCursorPosition) on editorRef or component state and
dispose it in a cleanup function when the component unmounts (call
disposable.dispose()); ensure setCursorPos is only called while mounted by
disposing the subscription in the useEffect return so the handler is removed on
unmount.
---
Nitpick comments:
In `@src/components/Footer.jsx`:
- Around line 231-233: Replace the unstable index key on algorithm cards with a
stable unique identifier: in the algorithms.map callback that renders
<FooterBentoCard key={i} algo={algo} />, use a unique field from each algo
(e.g., algo.path or another guaranteed-unique property) as the key so React can
correctly reconcile items and avoid unnecessary remounts.
- Around line 11-18: The handler handleMouseMove currently calls
setMousePosition on every mousemove causing frequent React rerenders; instead
compute local x/y from cardRef.getBoundingClientRect() and write them into CSS
custom properties on the DOM node (e.g.,
cardRef.current.style.setProperty('--spot-x', `${x}px`), '--spot-y' ) and remove
the setMousePosition state usage; to avoid too many updates, wrap the DOM
updates in a requestAnimationFrame loop (or throttle) and ensure your event
listeners read from cardRef and only schedule the rAF update, then apply styles
directly on cardRef.current so the spotlight is driven by CSS variables rather
than React state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro Plus
Run ID: 04feedf7-d5b4-40d3-927f-a026d65fb680
📒 Files selected for processing (3)
src/components/AppLayout.jsxsrc/components/CodeEditor.jsxsrc/components/Footer.jsx
| const handleEditorMount = (editor) => { | ||
| editorRef.current = editor | ||
|
|
||
| // Listen to cursor position updates | ||
| editor.onDidChangeCursorPosition((e) => { | ||
| setCursorPos({ | ||
| line: e.position.lineNumber, | ||
| column: e.position.column | ||
| }) | ||
| }) | ||
| } |
There was a problem hiding this comment.
Monaco cursor subscription is never disposed — memory leak risk.
The editor.onDidChangeCursorPosition() call returns an IDisposable that must be cleaned up when the component unmounts. Without disposal, the subscription keeps firing even after navigation, potentially calling setCursorPos on an unmounted component and leaking memory.
You'll need to store the disposable and clean it up via a useEffect return function.
🛠️ Suggested fix using useEffect cleanup
+ const cursorDisposableRef = useRef(null)
+
const handleEditorMount = (editor) => {
editorRef.current = editor
-
- // Listen to cursor position updates
- editor.onDidChangeCursorPosition((e) => {
+
+ // Store disposable for cleanup
+ cursorDisposableRef.current = editor.onDidChangeCursorPosition((e) => {
setCursorPos({
line: e.position.lineNumber,
column: e.position.column
})
})
}
+
+ useEffect(() => {
+ return () => {
+ // Dispose cursor subscription on unmount
+ cursorDisposableRef.current?.dispose()
+ }
+ }, [])📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const handleEditorMount = (editor) => { | |
| editorRef.current = editor | |
| // Listen to cursor position updates | |
| editor.onDidChangeCursorPosition((e) => { | |
| setCursorPos({ | |
| line: e.position.lineNumber, | |
| column: e.position.column | |
| }) | |
| }) | |
| } | |
| const cursorDisposableRef = useRef(null) | |
| const handleEditorMount = (editor) => { | |
| editorRef.current = editor | |
| // Store disposable for cleanup | |
| cursorDisposableRef.current = editor.onDidChangeCursorPosition((e) => { | |
| setCursorPos({ | |
| line: e.position.lineNumber, | |
| column: e.position.column | |
| }) | |
| }) | |
| } | |
| useEffect(() => { | |
| return () => { | |
| // Dispose cursor subscription on unmount | |
| cursorDisposableRef.current?.dispose() | |
| } | |
| }, []) |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/components/CodeEditor.jsx` around lines 92 - 102, The Monaco editor
cursor subscription created in handleEditorMount via
editor.onDidChangeCursorPosition(...) returns an IDisposable that must be saved
and disposed to avoid leaks; modify handleEditorMount (and/or add a useEffect)
to store the returned disposable (from editor.onDidChangeCursorPosition) on
editorRef or component state and dispose it in a cleanup function when the
component unmounts (call disposable.dispose()); ensure setCursorPos is only
called while mounted by disposing the subscription in the useEffect return so
the handler is removed on unmount.
|
@adityapaul26 see this |
Pull Request Summary
What changed?
Upgraded
CodeEditor.jsxwith active language badges, a keyboard shortcutsdrawer, and a real-time stats HUD. Added high-fidelity route transition
animations in
AppLayout.jsxusing Framer Motion. RefactoredFooter.jsxbento cells into a
FooterBentoCardcomponent with live cursor-trackingradial spotlight overlays and masked border glows.
Why is this needed?
The footer, page routing, and code editor lacked interactive visual feedback
and felt abrupt. This PR restores premium UI animations and editor upgrades
to make the experience feel polished and cohesive.
Closes #444
Type of Change
feat- New user-facing feature or algorithm capabilitystyle- Formatting or styling change with no behavior changeRelease Notes
Release note category:
Release note entry:
editor upgrades (language badges, shortcuts drawer, stats HUD)
Testing and Verification
npm ciornpm installnpm run lintnpm run buildhttp://localhost:5173Skipped or additional testing notes:
Skipped
npm run format:check— no formatting-only changes made.UI Evidence
Before: Standard static footer cards, instant page switches, plain Monaco container.


After:
CI/CD and Deployment Impact
Deployment notes:
No secrets, environment variables, or migration steps required.
Reviewer Checklist
Summary by CodeRabbit
Release Notes