A lightweight React library to synchronize a vertical navigation menu with scrollable content sections. Ideal for advanced catalogs, filter drawers, and any layout that needs a sticky nav that tracks the visible section and enables smooth scroll.
- π Sync state between a vertical nav and the currently visible content section
- π§ Programmatic scroll to a section when a menu item is selected
- β¨ Active item highlighting and nav auto-scroll to keep it in view
- π¨ Themable styles: override CSS variables to match your design
- π§ͺ Typed (TypeScript) & framework-agnostic CSS
pnpm add @dorixdev/react-dual-scroll-sync
# or
npm i @dorixdev/react-dual-scroll-syncImport the packaged CSS once in your app:
// e.g., main.tsx or App.tsx
import '@dorixdev/react-dual-scroll-sync/styles.css';import { DualScrollSync } from '@dorixdev/react-dual-scroll-sync';
const items = [
{ sectionKey: 's1', label: 'Section 1', children: <div>β¦</div> },
{ sectionKey: 's2', label: 'Section 2', children: <div>β¦</div> },
{ sectionKey: 's3', label: 'Section 3', children: <div>β¦</div> }
];
export default function Demo() {
return <DualScrollSync items={items} />;
}DualScrollSync can be used in two main ways: data-driven and declarative.
Define your sections in an array and let the component generate both nav items and content.
β Best for dynamic data (e.g. from CMS or API).
const items = [
{ sectionKey: 'intro', label: 'Introduction', children: <div>...</div> },
{ sectionKey: 'details', label: 'Details', children: <div>...</div> }
];
return <DualScrollSync items={items} onItemClick={handleClick} />;Write the structure directly in JSX using DualScrollSync.NavItem and DualScrollSync.ContentSection.
β Best for static pages where you want full control.
return (
<DualScrollSync onItemClick={handleClick}>
<DualScrollSync.Nav>
<DualScrollSync.NavItem sectionKey="intro">Introduction</DualScrollSync.NavItem>
<DualScrollSync.NavItem sectionKey="details">Details</DualScrollSync.NavItem>
</DualScrollSync.Nav>
<DualScrollSync.Content>
<DualScrollSync.ContentSection sectionKey="intro">
<DualScrollSync.Label>Introduction</DualScrollSync.Label>
<div>...</div>
</DualScrollSync.ContentSection>
<DualScrollSync.ContentSection sectionKey="details">
<DualScrollSync.Label>Details</DualScrollSync.Label>
<div>...</div>
</DualScrollSync.ContentSection>
</DualScrollSync.Content>
</DualScrollSync>
);β Long scrollable pages with sticky nav
β Catalog filters, docs sidebars, multi-section layouts
β Very short content (no scrolling needed)
β Complex nested navs (not supported)
Explore all props, variations, and usage guidelines in the Storybook docs.
This project is licensed under the MIT License.
