Skip to content

Commit 26e0982

Browse files
committed
Merge branch 'release/1.1.0'
2 parents 65291e6 + 6ef3fb1 commit 26e0982

18 files changed

Lines changed: 256 additions & 227 deletions

CHANGELOG.md

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,43 @@
1-
## [1.0.0](https://github.com/dorixdev/scroll-sync/compare/v0.0.0...v1.0.0) (2025-08-22)
1+
## [1.1.0](https://github.com/dorixdev/react-dual-scroll-sync/compare/v1.0.0...v1.1.0) (2025-08-25)
22

33
### ✨ Features
44

5-
- :label: add ScrollSync types for component props and structure ([6e61d98](https://github.com/dorixdev/scroll-sync/commit/6e61d9893eca66ffe9ef190fefa00bd26300694c))
6-
- :sparkles: add scrollToSectionView utility function for smooth scrolling ([17aeef9](https://github.com/dorixdev/scroll-sync/commit/17aeef9fb5a75306addecd62ca11cce54a090e44))
7-
- :sparkles: implement ScrollSync component with navigation and content sections ([7a95d63](https://github.com/dorixdev/scroll-sync/commit/7a95d63acfc1bececa19a2b327eab8737b2ad668))
8-
- :sparkles: implement useScrollSyncObserver hook for synchronized scrolling behavior ([30ec6db](https://github.com/dorixdev/scroll-sync/commit/30ec6dbcf564c81561ff98109a10390da0875287))
5+
- :sparkles: add types for DualScrollSync component ([f255dc0](https://github.com/dorixdev/react-dual-scroll-sync/commit/f255dc05612997a65ef9b4ea86b64112c66b0bab))
6+
- :sparkles: implement DualScrollSync component and update exports ([60f1fd7](https://github.com/dorixdev/react-dual-scroll-sync/commit/60f1fd732b06f1b740c7378e7670ed379b76c641))
7+
- :sparkles: rename useScrollSyncObserver to useDualScrollSyncObserver and update export ([da4e3f1](https://github.com/dorixdev/react-dual-scroll-sync/commit/da4e3f10f33ab81c7afa109a8a584b5e5d23a9c1))
98

109
### 📝 Documentation
1110

12-
- :memo: add documentation and stories for ScrollSync component ([79ace88](https://github.com/dorixdev/scroll-sync/commit/79ace888bbbdf6ed7d5c726d2a1793d0ea35d1c6))
13-
- :memo: add README.md with project description, features, installation, and usage examples ([f28b6e4](https://github.com/dorixdev/scroll-sync/commit/f28b6e40880f6a668fe926935ac1c7189135372e))
11+
- :sparkles: add documentation and stories for DualScrollSync component ([8044096](https://github.com/dorixdev/react-dual-scroll-sync/commit/8044096e60cb25a1a951c52cb2f569cbf3032cc2))
12+
13+
### ✅ Tests
14+
15+
- :white_check_mark: add tests for DualScrollSync component and its hooks ([6969b8d](https://github.com/dorixdev/react-dual-scroll-sync/commit/6969b8dc03e5aa390ef8e51301e87f0ce6360ea7))
16+
17+
## [1.0.0](https://github.com/dorixdev/react-dual-scroll-sync/compare/v0.0.0...v1.0.0) (2025-08-22)
18+
19+
### ✨ Features
20+
21+
- :label: add ScrollSync types for component props and structure ([6e61d98](https://github.com/dorixdev/react-dual-scroll-sync/commit/6e61d9893eca66ffe9ef190fefa00bd26300694c))
22+
- :sparkles: add scrollToSectionView utility function for smooth scrolling ([17aeef9](https://github.com/dorixdev/react-dual-scroll-sync/commit/17aeef9fb5a75306addecd62ca11cce54a090e44))
23+
- :sparkles: implement ScrollSync component with navigation and content sections ([7a95d63](https://github.com/dorixdev/react-dual-scroll-sync/commit/7a95d63acfc1bececa19a2b327eab8737b2ad668))
24+
- :sparkles: implement useScrollSyncObserver hook for synchronized scrolling behavior ([30ec6db](https://github.com/dorixdev/react-dual-scroll-sync/commit/30ec6dbcf564c81561ff98109a10390da0875287))
25+
26+
### 📝 Documentation
27+
28+
- :memo: add documentation and stories for ScrollSync component ([79ace88](https://github.com/dorixdev/react-dual-scroll-sync/commit/79ace888bbbdf6ed7d5c726d2a1793d0ea35d1c6))
29+
- :memo: add README.md with project description, features, installation, and usage examples ([f28b6e4](https://github.com/dorixdev/react-dual-scroll-sync/commit/f28b6e40880f6a668fe926935ac1c7189135372e))
1430

1531
### 🎨 Styles & Theming
1632

17-
- :lipstick: add SCSS styles and tokens for ScrollSync component ([a3fbd5a](https://github.com/dorixdev/scroll-sync/commit/a3fbd5acca700fb3f2d81d7c25d13a32f550bb99))
33+
- :lipstick: add SCSS styles and tokens for ScrollSync component ([a3fbd5a](https://github.com/dorixdev/react-dual-scroll-sync/commit/a3fbd5acca700fb3f2d81d7c25d13a32f550bb99))
1834

1935
### ✅ Tests
2036

21-
- :white_check_mark: add tests for ScrollSync component and utility functions ([5e503b0](https://github.com/dorixdev/scroll-sync/commit/5e503b00947951645a626e2311a7b30bf6c7c785))
37+
- :white_check_mark: add tests for ScrollSync component and utility functions ([5e503b0](https://github.com/dorixdev/react-dual-scroll-sync/commit/5e503b00947951645a626e2311a7b30bf6c7c785))
2238

23-
## [0.0.0](https://github.com/dorixdev/scroll-sync/compare/d84b180172c8f3d8343c7a9413694b5aec1da8d2...v0.0.0) (2025-08-22)
39+
## [0.0.0](https://github.com/dorixdev/react-dual-scroll-sync/compare/d84b180172c8f3d8343c7a9413694b5aec1da8d2...v0.0.0) (2025-08-22)
2440

2541
### ✨ Features
2642

27-
- :tada: add initial configuration files for TypeScript, Vite, and pnpm workspace ([d84b180](https://github.com/dorixdev/scroll-sync/commit/d84b180172c8f3d8343c7a9413694b5aec1da8d2))
43+
- :tada: add initial configuration files for TypeScript, Vite, and pnpm workspace ([d84b180](https://github.com/dorixdev/react-dual-scroll-sync/commit/d84b180172c8f3d8343c7a9413694b5aec1da8d2))

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# @dorixdev/scroll-sync
1+
# @dorixdev/react-dual-scroll-sync
22

33
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**.
44

55
<p align="center">
6-
<a href="https://www.npmjs.com/package/@dorixdev/scroll-sync"><img alt="npm" src="https://img.shields.io/npm/v/@dorixdev/scroll-sync.svg"></a>
7-
<a href="https://github.com/dorixdev/scroll-sync/actions"><img alt="CI" src="https://github.com/dorixdev/scroll-sync/workflows/Release%20to%20npm/badge.svg"></a>
6+
<a href="https://www.npmjs.com/package/@dorixdev/react-dual-scroll-sync"><img alt="npm" src="https://img.shields.io/npm/v/@dorixdev/react-dual-scroll-sync.svg"></a>
7+
<a href="https://github.com/dorixdev/react-dual-scroll-sync/actions"><img alt="CI" src="https://github.com/dorixdev/react-dual-scroll-sync/workflows/Release%20to%20npm/badge.svg"></a>
88
<a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
99
</p>
1010

@@ -21,9 +21,9 @@ A lightweight React library to synchronize a vertical navigation menu with scrol
2121
## 📦 Installation
2222

2323
```bash
24-
pnpm add @dorixdev/scroll-sync
24+
pnpm add @dorixdev/react-dual-scroll-sync
2525
# or
26-
npm i @dorixdev/scroll-sync
26+
npm i @dorixdev/react-dual-scroll-sync
2727
```
2828

2929
## 💄 Styles
@@ -32,13 +32,13 @@ Import the packaged CSS once in your app:
3232

3333
```ts
3434
// e.g., main.tsx or App.tsx
35-
import '@dorixdev/scroll-sync/styles.css';
35+
import '@dorixdev/react-dual-scroll-sync/styles.css';
3636
```
3737

3838
## 🚀 Quick start
3939

4040
```tsx
41-
import { ScrollSync } from '@dorixdev/scroll-sync';
41+
import { DualScrollSync } from '@dorixdev/react-dual-scroll-sync';
4242

4343
const items = [
4444
{ sectionKey: 's1', label: 'Section 1', children: <div>…</div> },
@@ -48,7 +48,7 @@ const items = [
4848

4949
export default function Demo() {
5050
return (
51-
<ScrollSync
51+
<DualScrollSync
5252
id="filters"
5353
items={items}
5454
maxVisibleItems={6}

lib/components/ScrollSync/ScrollSync.docs.mdx renamed to lib/components/DualScrollSync/DualScrollSync.docs.mdx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as ScrollSyncStories from './ScrollSync.stories.tsx';
1+
import * as DualScrollSyncStories from './DualScrollSync.stories.tsx';
22

33
import {
44
ArgTypes,
@@ -12,17 +12,17 @@ import {
1212
Title
1313
} from '@storybook/addon-docs/blocks';
1414

15-
<Meta of={ScrollSyncStories} />
15+
<Meta of={DualScrollSyncStories} />
1616

17-
<Title>ScrollSync - User guide</Title>
17+
<Title>DualScrollSync - User guide</Title>
1818
<Subtitle>Sync vertical navigation with scrollable content sections</Subtitle>
1919

20-
**ScrollSync** is a UI component that synchronizes a vertical navigation menu with scrollable content panels, ideal for advanced catalogs or complex filters.
20+
**DualScrollSync** is a UI component that synchronizes a vertical navigation menu with scrollable content panels, ideal for advanced catalogs or complex filters.
2121

2222
### 📦 Import
2323

2424
```tsx
25-
import { ScrollSync } from '@dorixdev/scroll-sync';
25+
import { DualScrollSync } from '@dorixdev/scroll-sync';
2626
```
2727

2828
### 💡 Features
@@ -33,7 +33,7 @@ import { ScrollSync } from '@dorixdev/scroll-sync';
3333

3434
### 🔧 Props
3535

36-
<ArgTypes of={ScrollSyncStories.Default} />
36+
<ArgTypes of={DualScrollSyncStories.Default} />
3737

3838
### 🧩 Events & Callbacks
3939

@@ -45,16 +45,16 @@ You can customize the styles by overriding the CSS variables defined in the pack
4545

4646
```css
4747
:root {
48-
--scroll-sync-border-radius: 16px;
49-
--scroll-sync-space-s: 8px;
50-
--scroll-sync-space-m: 16px;
51-
--scroll-sync-space-l: 24px;
52-
--scroll-sync-border-color: #e0e0e0;
53-
--scroll-sync-highlight-background-color: #e0e0e0;
54-
--scroll-sync-highlight-foreground-color: #f5f5f5;
55-
--scroll-sync-inactive-background-color: #6200ea;
56-
--scroll-sync-transition: all 0.3s ease;
57-
--scroll-sync-max-width-nav: 300px;
48+
--dual-scroll-sync-border-radius: 16px;
49+
--dual-scroll-sync-space-s: 8px;
50+
--dual-scroll-sync-space-m: 16px;
51+
--dual-scroll-sync-space-l: 24px;
52+
--dual-scroll-sync-border-color: #e0e0e0;
53+
--dual-scroll-sync-highlight-background-color: #e0e0e0;
54+
--dual-scroll-sync-highlight-foreground-color: #f5f5f5;
55+
--dual-scroll-sync-inactive-background-color: #6200ea;
56+
--dual-scroll-sync-transition: all 0.3s ease;
57+
--dual-scroll-sync-max-width-nav: 300px;
5858
}
5959
```
6060

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
@use '../../scss/tokens.scss' as *;
2+
3+
.scrollSync {
4+
overflow: hidden;
5+
display: flex;
6+
7+
height: 100%;
8+
border: 1px solid var(--dual-scroll-sync-border-color, #{$border-color});
9+
border-radius: var(--dual-scroll-sync-border-radius, #{$border-radius});
10+
11+
background-color: var(
12+
--dual-scroll-sync-highlight-background-color,
13+
#{$highlight-background-color}
14+
);
15+
16+
* {
17+
box-sizing: border-box;
18+
margin: 0;
19+
padding: 0;
20+
border: none;
21+
}
22+
}
23+
24+
.scrollSyncNav {
25+
overflow-y: auto;
26+
width: 100%;
27+
max-width: var(--dual-scroll-sync-max-width-nav, #{$max-width-nav});
28+
29+
&::-webkit-scrollbar {
30+
display: none;
31+
}
32+
}
33+
34+
.scrollSyncNavItem {
35+
cursor: pointer;
36+
37+
display: flex;
38+
align-items: center;
39+
40+
width: 100%;
41+
height: calc(100% / var(--menu-nav-visible-count));
42+
min-height: 56px;
43+
padding: var(--dual-scroll-sync-space-m, #{$space-m}) var(--dual-scroll-sync-space-s, #{$space-s});
44+
border-bottom: 1px solid var(--dual-scroll-sync-border-color, #{$border-color});
45+
46+
text-align: left;
47+
48+
background-color: var(--dual-scroll-sync-base-color, #{$inactive-background-color});
49+
50+
transition: var(--dual-scroll-sync-transition, #{$transition});
51+
52+
&:first-child {
53+
border-top-left-radius: var(--dual-scroll-sync-border-radius, #{$border-radius});
54+
}
55+
56+
&:last-child {
57+
border-bottom: none;
58+
border-bottom-left-radius: var(--dual-scroll-sync-border-radius, #{$border-radius});
59+
}
60+
}
61+
62+
.scrollSyncNavItemLabel,
63+
.scrollSyncContentSectionLabel {
64+
overflow: hidden;
65+
display: -webkit-box;
66+
-webkit-box-orient: vertical;
67+
-webkit-line-clamp: 2;
68+
line-clamp: 2;
69+
}
70+
71+
.scrollSyncNavItemLabel {
72+
display: flex;
73+
align-items: center;
74+
height: 100%;
75+
padding: 0 var(--dual-scroll-sync-space-m, #{$space-m});
76+
}
77+
78+
.scrollSyncContentSectionLabel {
79+
padding: var(--dual-scroll-sync-space-s, #{$space-s}) 0;
80+
font-weight: bold;
81+
}
82+
83+
.scrollSyncNavItemActive {
84+
background-color: var(--dual-scroll-sync-highlight-color, #{$highlight-background-color});
85+
86+
span {
87+
border-left: 3px solid
88+
var(--dual-scroll-sync-highlight-background-color, #{$highlight-foreground-color});
89+
font-weight: bold;
90+
color: var(--dual-scroll-sync-highlight-foreground-color, #{$highlight-foreground-color});
91+
}
92+
}
93+
94+
.scrollSyncContent {
95+
overflow-x: hidden;
96+
overflow-y: auto;
97+
flex: 1;
98+
gap: var(--dual-scroll-sync-space-m, #{$space-m});
99+
100+
height: 100%;
101+
padding: var(--dual-scroll-sync-space-s, #{$space-s});
102+
}
103+
104+
.scrollSyncContentSection {
105+
display: flex;
106+
flex-direction: column;
107+
gap: var(--dual-scroll-sync-space-l, #{$space-l});
108+
109+
height: auto;
110+
padding: var(--dual-scroll-sync-space-m, #{$space-m});
111+
border-radius: var(--dual-scroll-sync-border-radius, #{$border-radius});
112+
113+
transition: background-color 0.3s ease-in-out;
114+
}

lib/components/ScrollSync/ScrollSync.stories.tsx renamed to lib/components/DualScrollSync/DualScrollSync.stories.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import type { Meta, StoryObj } from '@storybook/react-vite';
22
import { action } from 'storybook/actions';
33

4-
import { ScrollSync } from './ScrollSync';
4+
import { DualScrollSync } from './DualScrollSync';
55

6-
const meta: Meta<typeof ScrollSync> = {
7-
title: 'ScrollSync',
8-
component: ScrollSync,
6+
const meta: Meta<typeof DualScrollSync> = {
7+
title: 'DualScrollSync',
8+
component: DualScrollSync,
99
tags: ['autodocs'],
1010
argTypes: {
1111
items: { control: { type: 'object', disable: true } },
@@ -22,7 +22,7 @@ const meta: Meta<typeof ScrollSync> = {
2222
{ sectionKey: 's7', label: 'Label 7', children: <MockContentSection /> },
2323
{ sectionKey: 's8', label: 'Label 8', children: <MockContentSection /> }
2424
],
25-
id: 'scroll-sync',
25+
id: 'dual-scroll-sync',
2626
onItemClick: action('onItemClick'),
2727
maxVisibleItems: 6
2828
},
@@ -33,7 +33,7 @@ const meta: Meta<typeof ScrollSync> = {
3333
</section>
3434
)
3535
]
36-
} satisfies Meta<typeof ScrollSync>;
36+
} satisfies Meta<typeof DualScrollSync>;
3737

3838
export default meta;
3939

lib/components/ScrollSync/ScrollSync.test.tsx renamed to lib/components/DualScrollSync/DualScrollSync.test.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { fireEvent, render, screen } from '@testing-library/react';
22
import { describe, expect, it, Mock, vi } from 'vitest';
33

44
import { type UseScrollSyncObserverReturn } from '../../hooks';
5-
import { ScrollSync } from './ScrollSync';
5+
import { DualScrollSync } from './DualScrollSync';
66

77
const scrollSyncInitialState: UseScrollSyncObserverReturn = {
88
activeKey: 's1',
@@ -17,11 +17,11 @@ const mockUseScrollSyncObserver: Mock<() => UseScrollSyncObserverReturn> = vi.fn
1717
() => scrollSyncInitialState
1818
);
1919

20-
vi.mock('../../hooks/useScrollSyncObserver', () => ({
20+
vi.mock('../../hooks/useDualScrollSyncObserver', () => ({
2121
useScrollSyncObserver: () => mockUseScrollSyncObserver()
2222
}));
2323

24-
describe('ScrollSync (with mocked hook)', () => {
24+
describe('DualScrollSync (with mocked hook)', () => {
2525
const items = [
2626
{ sectionKey: 's1', label: 'Section 1', children: <div>Content 1</div> },
2727
{ sectionKey: 's2', label: 'Section 2', children: <div>Content 2</div> },
@@ -36,14 +36,14 @@ describe('ScrollSync (with mocked hook)', () => {
3636
});
3737

3838
it('finds navItem and section by id and checks text', () => {
39-
render(<ScrollSync items={items} />);
39+
render(<DualScrollSync items={items} />);
4040

41-
const navItem = document.getElementById('scroll-sync-nav-item-s2');
41+
const navItem = document.getElementById('dual-scroll-sync-nav-item-s2');
4242

4343
expect(navItem).toBeInTheDocument();
4444
expect(navItem).toHaveTextContent('Section 2');
4545

46-
const section = document.getElementById('scroll-sync-content-section-s2');
46+
const section = document.getElementById('dual-scroll-sync-content-section-s2');
4747

4848
expect(section).toBeInTheDocument();
4949
expect(section).toHaveTextContent('Section 2');
@@ -56,7 +56,7 @@ describe('ScrollSync (with mocked hook)', () => {
5656
activeKey: 's2'
5757
});
5858

59-
render(<ScrollSync items={items} />);
59+
render(<DualScrollSync items={items} />);
6060

6161
const section = screen.getByRole('button', { name: 'Section 2' });
6262

@@ -72,7 +72,7 @@ describe('ScrollSync (with mocked hook)', () => {
7272
onMenuItemSelect: handleMenuClickMock
7373
});
7474

75-
render(<ScrollSync items={items} />);
75+
render(<DualScrollSync items={items} />);
7676

7777
const section2Btn = screen.getByRole('button', { name: 'Section 2' });
7878

@@ -84,15 +84,15 @@ describe('ScrollSync (with mocked hook)', () => {
8484
it('calls onSectionChange when an option is clicked', () => {
8585
const onSectionChangeMock = vi.fn();
8686

87-
render(<ScrollSync items={items} onItemClick={onSectionChangeMock} />);
87+
render(<DualScrollSync items={items} onItemClick={onSectionChangeMock} />);
8888
const section2Btn = screen.getByRole('button', { name: 'Section 2' });
8989
fireEvent.click(section2Btn);
9090

9191
expect(onSectionChangeMock).toHaveBeenCalledWith('s2');
9292
});
9393

9494
it('renders with default class names when no custom class names are provided', () => {
95-
render(<ScrollSync items={items} id="test" />);
95+
render(<DualScrollSync items={items} id="test" />);
9696

9797
const menu = document.getElementById('test');
9898
const menuNav = document.getElementById('test-nav');

0 commit comments

Comments
 (0)