Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Navigation

Bounce Sidebar

Navigation

Bounce Sidebar React component for Tailwind CSS v4

Back To TopBreadcrumb
Live props
Appearance
dotColor
headingColor
dotSize6px
size
activeColor
textColor
Behavior
duration0.25s
arc14px
Code
import { BounceSidebar } from "@/components/ui/bounce-sidebar"

<BounceSidebar />
  1. Home
  2. Components
  3. Navigation
  4. Bounce Sidebar
Free

Bounce Sidebar React component for Tailwind CSS v4

v1.0.1·Updated in 1.2.1

A React sidebar navigation list where a small dot hops along an arc to the active item, for docs, settings and scrollspy.

Click any item to bounce the marker over to it along a short arc. Tab moves between items and Enter or Space selects one. Heading rows are plain labels, so the dot skips past them. Drive the value from the scroll position and the marker follows the section you are reading.

Bounce Sidebar is a free React component in the React navigation components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add bounce-sidebar, together with Motion presets and UIProvider and the npm package motion.

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add bounce-sidebar

Usage

Import BounceSidebar from @/components/ui/bounce-sidebar.

import { BounceSidebar } from "@/components/ui/bounce-sidebar"

const items = [
  { label: "General", heading: true },
  { label: "Home", href: "/" },
  { label: "About", href: "/about" },
]

export function Demo() {
  return <BounceSidebar items={items} defaultValue={1} dotColor="#FC4C01" />
}

Props

  • items*
    Array<string | { label: string; href?: string } | { label: string; heading: true }>

    Rows rendered as the vertical list. A plain string or an object with a label is a nav item, and href turns it into a link. Add heading: true to render a non-selectable group label the marker skips over.

  • dotColordefault "#FC4C01"
    string

    Any CSS color for the bouncing active marker (hex, rgb, hsl, var). Heading rows use it for their text too unless headingColor is set.

  • headingColordefault ""
    string

    Any CSS color for the heading rows. Empty follows dotColor.

  • dotSizedefault 6
    number

    Diameter of the marker in pixels. It is snapped to the device pixel grid so it stays crisp at any zoom.

  • sizedefault "md"
    "sm" | "md" | "lg"

    Text size and row padding: 12px (sm), 14px (md) or 16px (lg) labels. On touch screens every row is at least 44px tall whatever the size, and the dot re-centers on its row by itself.

  • activeColordefault "auto"
    string

    Text color of the active item, any CSS color. Auto uses the foreground color of the theme.

  • textColordefault "auto"
    string

    Text color of the other items, any CSS color. Auto is the foreground color at 70% opacity.

  • durationdefault 0.25
    number

    Seconds the dot takes to hop to a new item. Set it to 0 to jump without travel; reduced motion always jumps.

  • arcdefault 14
    number

    How far the dot bows out sideways on its hop, in pixels. Short hops are capped so the arc never loops; 0 slides in a straight line.

  • value
    number

    Active item index for controlled usage. When set, the component won't manage its own state. Headings count toward the index.

  • defaultValuedefault 0
    number

    Initial active index for uncontrolled usage. Ignored when value is provided.

  • onChange
    (index: number) => void

    Called with the new index whenever an item is selected.

  • className
    string

    Extra classes merged onto the root <ul> element. Any other <ul> attribute is passed through too.

Parts

  • BounceSidebarItem

    type

    One row of items: a plain string, { label, href? } for a nav item (href renders a link), or { label, heading: true } for a group label the dot skips.

Examples

Settings navigation

Controlled with value and onChange: the dot hops to the section and the panel beside it swaps its content.

Sizes

sm, md and lg scale the type, the row padding and the group headings together.

Grouped with headings

Heading rows label each group. They are not selectable, so the dot hops straight over them.

Custom marker color

Pass any CSS color to dotColor to match your brand.

Dependencies

motionmotionui-config

Files

  • components/ui/bounce-sidebar.tsx

FAQ

Is the React Bounce Sidebar component free?

Yes. The source is free and needs no account: copy it from the Code tab or install it with the CLI.

How do I install Bounce Sidebar?

Run npx wingo-ui@latest add bounce-sidebar. It also adds the Wingo UI items it builds on (Motion presets and UIProvider) and the npm package motion. With shadcn, run npx shadcn@latest add https://wingo-ui.com/r/bounce-sidebar.json.

See also

Hook SidebarProximity SidebarTable Of ContentsSidebarNav Tabs

More React navigation components

Gooey NavUser MenuNav MenuBack To TopCommand MenuGlobal Search
All 19 React navigation components
PreviousBack To TopNext Breadcrumb
  • Contents

Bounce Sidebar

A table of contents whose marker hops from entry to entry.

Overview

Long documents need a map. The bounce sidebar is a plain list of links with one small dot beside the entry you are on, so the reader always knows where they are without a heavy highlight fighting the content.

When to use it

Reach for it on docs pages, changelogs and settings screens where the list is short enough to scan at a glance. For a dozen entries or more, group them under heading rows so the eye can jump between groups.

Why it exists

A selection that simply swaps colors is easy to miss. Movement draws the eye, and a marker that travels makes the change of section feel like a place you moved to rather than a state that flipped.

Motion

When the selection changes, the dot does not slide in a straight line. It bounces along a short arc, bowing out to the side and landing on the new entry, so every jump reads as a small, physical hop.

Arc strength

Short hops arc more and long hops arc less. The curve is scaled by the distance travelled, which keeps a jump across the whole list from swinging wide of the column.

Timing

Each hop takes a quarter of a second with an ease out, quick enough to keep up with a scrollspy while you scroll, and the first placement snaps into position without animating.

Anatomy

The component is an unordered list. Each entry is a button, or a link when you give it an href, and one absolutely positioned dot rides along the left edge of the list.

Heading rows

Pass an object with heading set to add a small uppercase label between groups. Headings take the dot color, are not selectable, and the marker hops straight over them.

Pixel snapping

The dot size and position are rounded to the device pixel grid, so it stays crisp on every screen instead of blurring between two rows of pixels.

Accessibility

Every entry is a real button or link, so Tab reaches each one and Enter or Space selects it. The active entry is marked with data-active for styling, and the dot itself is hidden from assistive technology.

Color

The dot is the only accent, so the entries keep the page text color and stay readable in both themes. Pass dotColor to match your brand; the heading rows pick it up too.

Related

The bounce sidebar is part of Wingo UI. The curved path comes from the arc helper in the motion library.

Further reading

See the hook sidebar and the proximity sidebar for two other takes on the same problem: showing where you are in a long page without taking over the layout.