Skip to content

feat: add responsive BackToTop floating button#160

Open
hari2k7 wants to merge 5 commits into
vishnukothakapu:mainfrom
hari2k7:feat/back-to-top-button
Open

feat: add responsive BackToTop floating button#160
hari2k7 wants to merge 5 commits into
vishnukothakapu:mainfrom
hari2k7:feat/back-to-top-button

Conversation

@hari2k7

@hari2k7 hari2k7 commented May 19, 2026

Copy link
Copy Markdown

What does this PR do?

Adds a reusable floating "Back to Top" button component to improve
navigation experience across long pages of the LinkID platform. The
button appears after scrolling 300px, smoothly scrolls to the top on
click, and automatically adapts to both light and dark mode.

Related Issue

Closes #159

Type of Change

  • Bug fix
  • New feature
  • Documentation
  • Refactor

How to Test

  1. Run the app locally with npm run dev
  2. Navigate to any long page (e.g. a public profile page)
  3. Scroll down more than 300px — button appears at bottom-right
  4. Click the button — page smoothly scrolls back to top
  5. Scroll less than 300px — button disappears
  6. Toggle dark/light mode — button adapts automatically
  7. Resize to mobile viewport — button remains responsive

Screenshots (if UI change)

before:
image

after:

LinkID.-.Google.Chrome.2026-05-19.10-25-40.mp4

Checklist

  • Code follows project conventions (TypeScript strict, Tailwind only)
  • Self-reviewed the changes
  • No console.log left behind
  • No new TypeScript errors
  • Uses lucide-react ArrowUp icon (already in project)
  • Uses shadcn/ui CSS variables (bg-primary, text-primary-foreground)
  • Tested on desktop and mobile viewport
  • Tested in both light and dark mode
  • Component placed in app/components/ per project structure

I am a GSSoC'26 contributor working on issue #159.

Summary by CodeRabbit

  • New Features
    • Added a floating "Back to Top" button that appears after scrolling and smoothly returns the page to the top.
    • Integrated the Back to Top button into the app layout so it’s available across pages, improving navigation reachability and keyboard/accessibility support for long pages.

Review Change Stack

@vercel

vercel Bot commented May 19, 2026

Copy link
Copy Markdown

@hari2k7 is attempting to deploy a commit to the vishnukothakapu's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 03f95c9a-bfb6-4f1d-93ac-442e4d80de74

📥 Commits

Reviewing files that changed from the base of the PR and between 3f3d0db and b2b829e.

📒 Files selected for processing (1)
  • components/ui/BackToTop.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/ui/BackToTop.tsx

📝 Walkthrough

Walkthrough

Adds a client-side BackToTop React component that appears after scrolling past a threshold and smoothly scrolls the page to a target; the component is imported and rendered inside the RootLayout.

Changes

Back to Top Button Implementation

Layer / File(s) Summary
BackToTop component implementation
components/ui/BackToTop.tsx
Adds a client-side BackToTop component ("use client") with BackToTopProps (threshold?: number, scrollTo?: number), visibility state driven by window.scrollY, a passive scroll listener, a smooth window.scrollTo click handler, and a fixed circular button rendering an ArrowUp icon with accessibility attributes.
Layout import and render
app/layout.tsx
Imports BackToTop and inserts <BackToTop /> into the RootLayout render output.

Sequence Diagram(s)

sequenceDiagram
  participant Page
  participant BackToTop
  participant Window
  Page->>BackToTop: scroll event / read window.scrollY
  BackToTop->>BackToTop: update visible state
  User->>BackToTop: click BackToTop button
  BackToTop->>Window: window.scrollTo({ top: scrollTo, behavior: 'smooth' })
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

feature, enhancement, level1, quality:clean

Suggested reviewers

  • vedhapprakashni

Poem

I hop and watch the page scroll stop,
A round bright button near the crop,
Click once and feel the smooth sky sweep,
Back to the summit, up we leap,
Rabbit cheers — a gentle hop! 🐇⬆️

🚥 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 'feat: add responsive BackToTop floating button' accurately and clearly summarizes the main change—addition of a responsive Back to Top button component.
Linked Issues check ✅ Passed All coding requirements from issue #159 are met: button appears after scroll threshold, smooth scroll to top works, and component is responsive across desktop and mobile.
Out of Scope Changes check ✅ Passed All changes are in scope: BackToTop.tsx implements the required button component, and app/layout.tsx integrates it into the global layout as intended.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 `@components/ui/BackToTop.tsx`:
- Around line 10-15: The embedded usage docs in the header of the BackToTop
component reference the wrong path; update the example import and instructions
to the actual component path used in this repo. Edit the usage block in
components/ui/BackToTop.tsx so the sample import shows the correct module (e.g.,
import BackToTop from "`@/components/ui/BackToTop`";) and adjust the placement
guidance to match that file, keeping the example JSX (<BackToTop />) and any
surround text intact.
- Around line 44-73: The BackToTop button remains focusable/announced when
hidden; update the button element in the BackToTop component to toggle
accessibility attributes with the visible state: set tabIndex to 0 when visible
and -1 when not, and set aria-hidden to true when not visible (aria-hidden={
!visible }), so keyboard and screen-reader users won't focus or hear the hidden
button; keep existing className and handleClick behavior unchanged.
- Around line 33-37: The visibility state in BackToTop isn't initialized on
mount so if the page loads scrolled past threshold the button stays hidden until
a scroll event; inside the useEffect that registers handleScroll (the function
that calls setVisible based on window.scrollY and threshold), invoke
handleScroll once immediately after adding the listener (or before) so
visibility is computed on mount as well as on future scrolls.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ec979092-00e6-44c5-a06a-e022849fc54a

📥 Commits

Reviewing files that changed from the base of the PR and between ce2c4e7 and 12ee186.

📒 Files selected for processing (2)
  • app/layout.tsx
  • components/ui/BackToTop.tsx

Comment thread components/ui/BackToTop.tsx Outdated
Comment thread components/ui/BackToTop.tsx
Comment thread components/ui/BackToTop.tsx
@vishnukothakapu

Copy link
Copy Markdown
Owner

Hi @hari2k7,
Please resolve all the above CodeRabbit review comments and make the required changes accordingly. After making the fixes, kindly mark all the review comments as resolved in the PR.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@components/ui/BackToTop.tsx`:
- Around line 15-24: The component currently causes an extra render by computing
initial visibility from window.scrollY and then immediately calling setVisible
in the useEffect; change the useState initialization to always start false
(useState(false)) and move the initial visibility check into the existing effect
so the effect both sets initial visibility and registers the scroll listener;
update references to visible/setVisible, keep threshold in the effect dependency
array, and ensure handleScroll still uses setVisible(window.scrollY > threshold)
and is cleaned up via removeEventListener.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0593cec8-a19e-402a-8449-a33cea8046b8

📥 Commits

Reviewing files that changed from the base of the PR and between feb47b4 and 68301b6.

📒 Files selected for processing (1)
  • components/ui/BackToTop.tsx

Comment thread components/ui/BackToTop.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
components/ui/BackToTop.tsx (1)

17-22: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

The double-render issue flagged by ESLint remains unresolved.

Line 18 still calls setVisible directly inside the effect, causing a cascading render when the page loads scrolled past the threshold. This was flagged in previous reviews and is confirmed by the ESLint error.

⚡ Fix to eliminate the extra render on mount
   useEffect(() => {
-    setVisible(window.scrollY > threshold);
     const handleScroll = () => setVisible(window.scrollY > threshold);
+    handleScroll();
     window.addEventListener("scroll", handleScroll, { passive: true });
     return () => window.removeEventListener("scroll", handleScroll);
   }, [threshold]);
🤖 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 `@components/ui/BackToTop.tsx` around lines 17 - 22, The effect currently calls
setVisible on mount causing an unnecessary extra render; instead initialize
visibility from the current scroll position and only register the scroll handler
in useEffect. Update the BackToTop component so the visible state is created
with useState(() => (typeof window !== "undefined" ? window.scrollY > threshold
: false)) and remove the initial setVisible(window.scrollY > threshold) from the
useEffect; keep the handleScroll function and the
window.addEventListener/cleanup as-is so subsequent scrolls still update
setVisible based on threshold.
🤖 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.

Duplicate comments:
In `@components/ui/BackToTop.tsx`:
- Around line 17-22: The effect currently calls setVisible on mount causing an
unnecessary extra render; instead initialize visibility from the current scroll
position and only register the scroll handler in useEffect. Update the BackToTop
component so the visible state is created with useState(() => (typeof window !==
"undefined" ? window.scrollY > threshold : false)) and remove the initial
setVisible(window.scrollY > threshold) from the useEffect; keep the handleScroll
function and the window.addEventListener/cleanup as-is so subsequent scrolls
still update setVisible based on threshold.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ffa1b004-4755-467d-af24-a18fedf8d4f0

📥 Commits

Reviewing files that changed from the base of the PR and between 68301b6 and 3f3d0db.

📒 Files selected for processing (1)
  • components/ui/BackToTop.tsx

@hari2k7

hari2k7 commented May 19, 2026

Copy link
Copy Markdown
Author

Hi @vishnukothakapu, I have addressed all CodeRabbit review comments:

  1. Fixed the import path in usage docs to @/components/ui/BackToTop
  2. Initialized visibility on mount via useEffect to handle page restore at scrolled position
  3. Added tabIndex and aria-hidden to remove hidden button from keyboard/screen-reader navigation
  4. Eliminated double render on mount by simplifying useState to false and letting useEffect handle initial check

All conversations resolved. Kindly review when you get a chance

I am a GSSoC'26 contributor working on this issue.

@vercel

vercel Bot commented May 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
linkid Ready Ready Preview, Comment May 27, 2026 1:39pm

@vedhapprakashni

Copy link
Copy Markdown
Collaborator

hey @hari2k7. your last two commits dint solve the coderabbit's errors:

The second last commit fixed a11y & mount check but introduced double initialization (both useState AND useEffect computing visibility)

The last commit's title says "eliminate double render" but didn't actually fix it . The setVisible still runs unconditionally at the top of useEffect. The simple fix is to just call handleScroll() instead of a separate setVisible() line.

lmk after u fix it

@hari2k7

hari2k7 commented May 27, 2026

Copy link
Copy Markdown
Author

Hi @vedhapprakashni, Fixed — removed the separate setVisible call and replaced it with
handleScroll() called once on mount to initialize visibility.
This eliminates the double render.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] Add responsive Back to Top button for improved navigation

3 participants