Skip to content

fix: resolve icon shifting issue while scrolling on Apply page#682

Merged
Zahnentferner merged 2 commits intoAOSSIE-Org:mainfrom
madhavansingh:fix/apply-page-icon-shift
Mar 17, 2026
Merged

fix: resolve icon shifting issue while scrolling on Apply page#682
Zahnentferner merged 2 commits intoAOSSIE-Org:mainfrom
madhavansingh:fix/apply-page-icon-shift

Conversation

@madhavansingh
Copy link
Copy Markdown
Contributor

@madhavansingh madhavansingh commented Mar 16, 2026

Addressed Issues:

Fixes #681

Screenshots/Recordings:

Before Fix (icons shift incorrectly while scrolling):

Screen.Recording.2026-03-16.at.9.08.24.PM-2.mov

After Fix (smooth animation and improved alignment):

Screen.Recording.2026-03-16.at.11.15.36.PM.mov

Additional Notes:

This PR fixes a UI/UX issue on the Apply page where the icons in the steps section:

  • Join us on Discord
  • Start Contributing
  • Write a Draft Application
  • Discuss with Mentors
  • Submit Application

were shifting incorrectly to the left during scrolling.

The fix ensures that the icons now move smoothly and consistently from right to left without abrupt horizontal shifts.

Additionally, small UI/UX improvements were made to the top row of the five icons to improve alignment and visual consistency while keeping the original design intact.

AI Usage Disclosure:

  • This PR does not contain AI-generated code at all.

I have used the following AI models and tools: None

Checklist

  • My PR addresses a single issue, fixes a single bug or makes a single improvement.
  • My code follows the project's code style and conventions
  • If applicable, I have made corresponding changes or additions to the documentation
  • If applicable, I have made corresponding changes or additions to tests
  • My changes generate no new warnings or errors
  • I have joined the Discord server and I will share a link to this PR with the project maintainers there
  • I have read the Contribution Guidelines
  • Once I submit my PR, CodeRabbit AI will automatically review it and I will address CodeRabbit's comments.
  • I have filled this PR template completely and carefully.

Summary by CodeRabbit

  • New Features

    • Added scroll-linked parallax animation to the timeline navigation for dynamic horizontal movement as you scroll.
  • Improvements

    • Simplified timeline entries to display title, time, and description with clearer layout.
    • Split icon and content animations and applied smoother spring-based transitions and refined timing for a more polished, responsive appearance.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 16, 2026

📝 Walkthrough

Walkthrough

TimelineElement's animation structure was refactored to separate icon and content animations; ApplyHeader gained scroll-linked horizontal translation using framer-motion hooks to drive a smooth, spring-based parallax effect.

Changes

Cohort / File(s) Summary
Timeline Animation Refactor
src/components/about/TimelineElement.jsx
Function signature reduced to { title, description, time }. Replaced a single motion.li with separate motion.span (icon) and motion.div (content). Icon animation changed (x: 50, spring: stiffness 50, damping 20, viewport amount 0.5, once true). Content animation added delay 0.1; title/time/description moved inside content block.
Apply Header — Scroll-linked Parallax
src/components/apply/ApplyHeader.jsx
Added framer-motion scroll hooks (useScroll, useTransform, useSpring) to produce a smoothed scroll value and a translateX transform applied to the timeline container to enable horizontal, scroll-driven movement. No public signature changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • Zahnentferner

Poem

🐰
I hopped along the timeline track,
Split my steps, then bounced right back.
Springs made motion soft and kind,
Scroll and icon now aligned.
A happy hop — no shift to find! 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main issue being fixed (icon shifting while scrolling on Apply page) and aligns with the PR's primary objective.
Linked Issues check ✅ Passed The code changes implement the required fix for issue #681 by modifying TimelineElement and ApplyHeader to prevent unintended icon shifting during scroll through animation parameter adjustments.
Out of Scope Changes check ✅ Passed All changes are focused on fixing the icon shifting issue; TimelineElement refactoring and scroll-based animation in ApplyHeader are directly related to resolving the reported bug.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can customize the high-level summary generated by CodeRabbit.

Configure the reviews.high_level_summary_instructions setting to provide custom instructions for generating the high-level summary.

@madhavansingh
Copy link
Copy Markdown
Contributor Author

Hi @Zahnentferner

I’ve opened a PR fixing the icon shifting issue on the Apply page and improving the alignment of the five step icons.
I’ve also added before and after recordings in the PR.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/components/apply/ApplyHeader.jsx (1)

14-20: Consider extracting steps array to module scope.

The steps array is recreated on every render. While the impact is negligible for this component, moving it outside the component as a constant is a minor optimization and cleaner pattern.

♻️ Suggested refactor
+const STEPS = [
+    { icon: faDiscord, label: "Join Discord" },
+    { icon: faGithub, label: "Start Contributing" },
+    { icon: faLightbulb, label: "Choose Idea" },
+    { icon: faComments, label: "Discuss" },
+    { icon: faPaperPlane, label: "Submit App" },
+];
+
 export function ApplyHeader({ children }) {
     const { scrollY } = useScroll();
     const smoothScroll = useSpring(scrollY, { stiffness: 100, damping: 30, restDelta: 0.001 });
     const translateX = useTransform(smoothScroll, [0, 800], [0, -30]);

-    const steps = [
-        { icon: faDiscord, label: "Join Discord" },
-        { icon: faGithub, label: "Start Contributing" },
-        { icon: faLightbulb, label: "Choose Idea" },
-        { icon: faComments, label: "Discuss" },
-        { icon: faPaperPlane, label: "Submit App" },
-    ];

Then update line 65 to use STEPS.map(...).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/apply/ApplyHeader.jsx` around lines 14 - 20, Move the steps
array out of the ApplyHeader component into module scope as a constant (e.g.,
export or const STEPS = [...]) so it isn't recreated on every render; update the
component to reference STEPS instead of the local steps variable and change the
mapping call where steps was iterated (currently using steps.map in ApplyHeader)
to STEPS.map. Ensure the new constant uses the same objects (icon and label) as
the original steps and import any icon symbols (faDiscord, faGithub,
faLightbulb, faComments, faPaperPlane) at top-level if needed.
src/components/about/TimelineElement.jsx (1)

13-13: Remove duration from spring transitions with explicit stiffness/damping.

In framer-motion, type: "spring" supports two distinct configuration modes:

  • Physics-based: Use stiffness, damping, and mass (duration is an outcome of these values)
  • Duration-based: Use duration and bounce instead

Combining physics parameters (stiffness: 50, damping: 20) with duration: 0.8 mixes these approaches, which can lead to the duration being ignored or producing inconsistent behavior.

♻️ Suggested simplification
-                transition={{ type: "spring", stiffness: 50, damping: 20, duration: 0.8 }}
+                transition={{ type: "spring", stiffness: 50, damping: 20 }}
-                transition={{ type: "spring", stiffness: 50, damping: 20, duration: 0.8, delay: 0.1 }}
+                transition={{ type: "spring", stiffness: 50, damping: 20, delay: 0.1 }}

Also applies to: 23-23

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/about/TimelineElement.jsx` at line 13, The transition for the
motion element in TimelineElement.jsx currently mixes physics and duration-based
config (transition prop with type: "spring", stiffness: 50, damping: 20,
duration: 0.8); remove the duration when using physics parameters
(stiffness/damping) or convert the transition to a duration-based spring (use
duration and bounce instead). Update the transition object used in the component
(the transition prop passed to the motion element) to either drop duration or
replace stiffness/damping with duration/bounce consistently, and apply the same
change to the other occurrence noted in the file.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/about/TimelineElement.jsx`:
- Line 6: Remove unused props and unused import from the TimelineElement
component: delete button, link, and classCondition from the TimelineElement({
... }) signature and remove the unused clsx import so the component only accepts
title, description, and time. Also fix the animation configs used in the motion
variants inside TimelineElement (the spring configs referenced in the current
animate/initial variants): either remove the duration property from the spring
configs (and rely on stiffness/damping/mass) or change the animation type to
"tween" and supply duration in that tween config (e.g., replace type: "spring" +
duration with type: "tween" + duration), updating both spring occurrences so
they are consistent.

---

Nitpick comments:
In `@src/components/about/TimelineElement.jsx`:
- Line 13: The transition for the motion element in TimelineElement.jsx
currently mixes physics and duration-based config (transition prop with type:
"spring", stiffness: 50, damping: 20, duration: 0.8); remove the duration when
using physics parameters (stiffness/damping) or convert the transition to a
duration-based spring (use duration and bounce instead). Update the transition
object used in the component (the transition prop passed to the motion element)
to either drop duration or replace stiffness/damping with duration/bounce
consistently, and apply the same change to the other occurrence noted in the
file.

In `@src/components/apply/ApplyHeader.jsx`:
- Around line 14-20: Move the steps array out of the ApplyHeader component into
module scope as a constant (e.g., export or const STEPS = [...]) so it isn't
recreated on every render; update the component to reference STEPS instead of
the local steps variable and change the mapping call where steps was iterated
(currently using steps.map in ApplyHeader) to STEPS.map. Ensure the new constant
uses the same objects (icon and label) as the original steps and import any icon
symbols (faDiscord, faGithub, faLightbulb, faComments, faPaperPlane) at
top-level if needed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ef3a6db4-45e8-4953-b950-4a492679d99c

📥 Commits

Reviewing files that changed from the base of the PR and between 69ce9e3 and 786227f.

📒 Files selected for processing (2)
  • src/components/about/TimelineElement.jsx
  • src/components/apply/ApplyHeader.jsx

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/components/about/TimelineElement.jsx (1)

39-41: Render <time> only when time exists.

TimelineElement is used without time in src/app/apply/page.jsx (Lines 22-41), so this currently renders an empty <time> block. Guarding it avoids unnecessary spacing and empty semantic markup.

♻️ Suggested change
-                <time className="block mb-2 font-mono text-sm font-normal leading-none text-gray-400 dark:text-gray-500">
-                    {time}
-                </time>
+                {time ? (
+                    <time className="block mb-2 font-mono text-sm font-normal leading-none text-gray-400 dark:text-gray-500">
+                        {time}
+                    </time>
+                ) : null}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/about/TimelineElement.jsx` around lines 39 - 41, The <time>
element in the TimelineElement component is always rendered even when the time
prop is falsy, producing empty semantic markup and extra spacing; update the
TimelineElement render to conditionally include the <time> block only when the
time prop is present (e.g., wrap the existing <time
className="...">{time}</time> in a conditional that checks the time prop) so
that TimelineElement omits the element when time is undefined/null/empty.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/components/about/TimelineElement.jsx`:
- Around line 39-41: The <time> element in the TimelineElement component is
always rendered even when the time prop is falsy, producing empty semantic
markup and extra spacing; update the TimelineElement render to conditionally
include the <time> block only when the time prop is present (e.g., wrap the
existing <time className="...">{time}</time> in a conditional that checks the
time prop) so that TimelineElement omits the element when time is
undefined/null/empty.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 787a56d6-3f33-464e-a3a3-838db951916d

📥 Commits

Reviewing files that changed from the base of the PR and between 786227f and fe18e39.

📒 Files selected for processing (1)
  • src/components/about/TimelineElement.jsx

Copy link
Copy Markdown
Collaborator

@Zahnentferner Zahnentferner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@Zahnentferner Zahnentferner merged commit 56b324c into AOSSIE-Org:main Mar 17, 2026
1 check passed
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.

[BUG]: Icons shift left while scrolling on Apply page

2 participants