Skip to content

Commit 73d352e

Browse files
author
Ahmed Mahmoud
committed
feat: add modern interactive demo showcasing v5.0 features
- React 19 + TypeScript demo with live scroll detection - Interactive controls and real-time scroll values - Beautiful UI showcasing custom scrollbar styling - Auto-hide functionality demonstration - Installation instructions and feature highlights
1 parent 1790022 commit 73d352e

File tree

5 files changed

+336
-0
lines changed

5 files changed

+336
-0
lines changed

examples/modern-demo/index.html

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>React Custom Scrollbars v5.0 - Modern Demo</title>
7+
<style>
8+
* {
9+
margin: 0;
10+
padding: 0;
11+
box-sizing: border-box;
12+
}
13+
14+
body {
15+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
16+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
17+
min-height: 100vh;
18+
}
19+
20+
#root {
21+
height: 100vh;
22+
padding: 20px;
23+
}
24+
</style>
25+
</head>
26+
<body>
27+
<div id="root"></div>
28+
<script type="module" src="/src/main.tsx"></script>
29+
</body>
30+
</html>

examples/modern-demo/package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "react-custom-scrollbars-modern-demo",
3+
"version": "1.0.0",
4+
"private": true,
5+
"scripts": {
6+
"dev": "vite",
7+
"build": "vite build",
8+
"preview": "vite preview"
9+
},
10+
"dependencies": {
11+
"react": "^19.0.0",
12+
"react-dom": "^19.0.0",
13+
"@dev-ahmed-mahmoud/react-custom-scrollbars": "^5.0.0"
14+
},
15+
"devDependencies": {
16+
"@vitejs/plugin-react": "^4.3.3",
17+
"vite": "^7.2.2"
18+
}
19+
}

examples/modern-demo/src/App.tsx

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
import React, { useState, useRef, useCallback } from 'react'
2+
import { Scrollbars, ScrollbarsRef, ScrollValues } from '@dev-ahmed-mahmoud/react-custom-scrollbars'
3+
4+
function App() {
5+
const [scrollValues, setScrollValues] = useState<ScrollValues | null>(null)
6+
const [isScrolling, setIsScrolling] = useState(false)
7+
const scrollbarsRef = useRef<ScrollbarsRef>(null)
8+
9+
const handleScrollFrame = useCallback((values: ScrollValues) => {
10+
setScrollValues(values)
11+
}, [])
12+
13+
const handleScrollStart = useCallback(() => {
14+
setIsScrolling(true)
15+
}, [])
16+
17+
const handleScrollStop = useCallback(() => {
18+
setIsScrolling(false)
19+
}, [])
20+
21+
const scrollToTop = () => scrollbarsRef.current?.scrollToTop()
22+
const scrollToBottom = () => scrollbarsRef.current?.scrollToBottom()
23+
24+
const customThumb = ({ style, ...props }: any) => (
25+
<div
26+
style={{
27+
...style,
28+
backgroundColor: isScrolling ? '#ff6b6b' : '#4ecdc4',
29+
borderRadius: '6px',
30+
transition: 'background-color 0.3s ease',
31+
cursor: 'grab',
32+
}}
33+
{...props}
34+
/>
35+
)
36+
37+
const customTrack = ({ style, ...props }: any) => (
38+
<div
39+
style={{
40+
...style,
41+
backgroundColor: 'rgba(255, 255, 255, 0.1)',
42+
borderRadius: '6px',
43+
}}
44+
{...props}
45+
/>
46+
)
47+
48+
return (
49+
<div style={{
50+
height: '100%',
51+
display: 'flex',
52+
flexDirection: 'column',
53+
gap: '20px',
54+
color: 'white'
55+
}}>
56+
{/* Header */}
57+
<div style={{ textAlign: 'center' }}>
58+
<h1 style={{ fontSize: '2.5rem', marginBottom: '10px', fontWeight: '700' }}>
59+
🚀 React Custom Scrollbars v5.0
60+
</h1>
61+
<p style={{ fontSize: '1.2rem', opacity: 0.9 }}>
62+
Modern TypeScript implementation with React 19 support
63+
</p>
64+
</div>
65+
66+
{/* Main Demo */}
67+
<div style={{
68+
flex: 1,
69+
display: 'grid',
70+
gridTemplateColumns: '1fr 300px',
71+
gap: '20px',
72+
minHeight: 0
73+
}}>
74+
{/* Scrollable Content */}
75+
<div style={{
76+
background: 'rgba(255, 255, 255, 0.1)',
77+
borderRadius: '12px',
78+
padding: '20px',
79+
backdropFilter: 'blur(10px)'
80+
}}>
81+
<h2 style={{ marginBottom: '15px', color: '#fff' }}>
82+
📜 Scrollable Content
83+
{isScrolling && (
84+
<span style={{
85+
marginLeft: '10px',
86+
color: '#ff6b6b',
87+
fontSize: '0.8em'
88+
}}>
89+
● SCROLLING
90+
</span>
91+
)}
92+
</h2>
93+
94+
<Scrollbars
95+
ref={scrollbarsRef}
96+
style={{ height: '100%' }}
97+
autoHide
98+
autoHideTimeout={1000}
99+
autoHideDuration={200}
100+
onScrollFrame={handleScrollFrame}
101+
onScrollStart={handleScrollStart}
102+
onScrollStop={handleScrollStop}
103+
renderThumbVertical={customThumb}
104+
renderTrackVertical={customTrack}
105+
renderThumbHorizontal={customThumb}
106+
renderTrackHorizontal={customTrack}
107+
>
108+
<div style={{ padding: '20px', fontSize: '16px', lineHeight: '1.6' }}>
109+
<h3 style={{ color: '#4ecdc4', marginBottom: '15px' }}>
110+
✨ New in v5.0.0
111+
</h3>
112+
113+
<div style={{ marginBottom: '20px' }}>
114+
<h4 style={{ color: '#fff', marginBottom: '10px' }}>🎯 Modern React Features</h4>
115+
<ul style={{ listStyle: 'none', paddingLeft: '0' }}>
116+
<li style={{ marginBottom: '8px' }}>✅ React 19 compatibility</li>
117+
<li style={{ marginBottom: '8px' }}>✅ TypeScript first approach</li>
118+
<li style={{ marginBottom: '8px' }}>✅ Hooks-based implementation</li>
119+
<li style={{ marginBottom: '8px' }}>✅ Zero runtime dependencies</li>
120+
</ul>
121+
</div>
122+
123+
<div style={{ marginBottom: '20px' }}>
124+
<h4 style={{ color: '#fff', marginBottom: '10px' }}>📦 Bundle Optimization</h4>
125+
<ul style={{ listStyle: 'none', paddingLeft: '0' }}>
126+
<li style={{ marginBottom: '8px' }}>📉 28% smaller bundle size</li>
127+
<li style={{ marginBottom: '8px' }}>⚡ Tree-shakable ES modules</li>
128+
<li style={{ marginBottom: '8px' }}>🛡️ Type-safe API</li>
129+
<li style={{ marginBottom: '8px' }}>🔧 Modern build tools (Vite)</li>
130+
</ul>
131+
</div>
132+
133+
<div style={{ marginBottom: '20px' }}>
134+
<h4 style={{ color: '#fff', marginBottom: '10px' }}>🎨 Enhanced Features</h4>
135+
<ul style={{ listStyle: 'none', paddingLeft: '0' }}>
136+
<li style={{ marginBottom: '8px' }}>🕐 autoHideTimeout prop restored</li>
137+
<li style={{ marginBottom: '8px' }}>📊 Improved scroll detection</li>
138+
<li style={{ marginBottom: '8px' }}>🎭 Custom render props support</li>
139+
<li style={{ marginBottom: '8px' }}>📱 Mobile-optimized scrolling</li>
140+
</ul>
141+
</div>
142+
143+
{/* Generate more content */}
144+
{Array.from({ length: 10 }, (_, i) => (
145+
<div key={i} style={{
146+
marginBottom: '20px',
147+
padding: '15px',
148+
background: 'rgba(255, 255, 255, 0.05)',
149+
borderRadius: '8px',
150+
border: '1px solid rgba(255, 255, 255, 0.1)'
151+
}}>
152+
<h5 style={{ color: '#4ecdc4', marginBottom: '10px' }}>
153+
📝 Demo Section {i + 1}
154+
</h5>
155+
<p>
156+
This is a demonstration of the scrollable content. The scrollbars
157+
are fully customizable and provide smooth, 60fps scrolling performance.
158+
Try scrolling to see the enhanced scroll detection in action!
159+
</p>
160+
<p style={{ marginTop: '10px', fontSize: '14px', opacity: 0.8 }}>
161+
Features like auto-hide, custom styling, and TypeScript support
162+
make this the perfect solution for modern React applications.
163+
</p>
164+
</div>
165+
))}
166+
</div>
167+
</Scrollbars>
168+
</div>
169+
170+
{/* Control Panel */}
171+
<div style={{
172+
background: 'rgba(255, 255, 255, 0.1)',
173+
borderRadius: '12px',
174+
padding: '20px',
175+
backdropFilter: 'blur(10px)',
176+
display: 'flex',
177+
flexDirection: 'column',
178+
gap: '15px'
179+
}}>
180+
<h3 style={{ color: '#fff', marginBottom: '10px' }}>🎛️ Controls</h3>
181+
182+
<button
183+
onClick={scrollToTop}
184+
style={{
185+
padding: '12px 16px',
186+
background: '#4ecdc4',
187+
border: 'none',
188+
borderRadius: '8px',
189+
color: 'white',
190+
fontWeight: '600',
191+
cursor: 'pointer',
192+
transition: 'background-color 0.2s ease',
193+
}}
194+
onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#45b7aa'}
195+
onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#4ecdc4'}
196+
>
197+
⬆️ Scroll to Top
198+
</button>
199+
200+
<button
201+
onClick={scrollToBottom}
202+
style={{
203+
padding: '12px 16px',
204+
background: '#ff6b6b',
205+
border: 'none',
206+
borderRadius: '8px',
207+
color: 'white',
208+
fontWeight: '600',
209+
cursor: 'pointer',
210+
transition: 'background-color 0.2s ease',
211+
}}
212+
onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#ff5252'}
213+
onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#ff6b6b'}
214+
>
215+
⬇️ Scroll to Bottom
216+
</button>
217+
218+
<div style={{
219+
marginTop: '20px',
220+
padding: '15px',
221+
background: 'rgba(0, 0, 0, 0.2)',
222+
borderRadius: '8px'
223+
}}>
224+
<h4 style={{ color: '#fff', marginBottom: '10px', fontSize: '14px' }}>
225+
📊 Scroll Values
226+
</h4>
227+
{scrollValues ? (
228+
<div style={{ fontSize: '12px', fontFamily: 'monospace' }}>
229+
<div>Top: {(scrollValues.top * 100).toFixed(1)}%</div>
230+
<div>Left: {(scrollValues.left * 100).toFixed(1)}%</div>
231+
<div>ScrollTop: {scrollValues.scrollTop}px</div>
232+
<div>ClientH: {scrollValues.clientHeight}px</div>
233+
<div>ScrollH: {scrollValues.scrollHeight}px</div>
234+
</div>
235+
) : (
236+
<div style={{ fontSize: '12px', opacity: 0.7 }}>
237+
Start scrolling to see values
238+
</div>
239+
)}
240+
</div>
241+
242+
<div style={{
243+
marginTop: 'auto',
244+
padding: '15px',
245+
background: 'rgba(0, 0, 0, 0.2)',
246+
borderRadius: '8px',
247+
fontSize: '12px',
248+
textAlign: 'center'
249+
}}>
250+
<div style={{ marginBottom: '8px' }}>
251+
<strong>Installation:</strong>
252+
</div>
253+
<code style={{
254+
background: 'rgba(0, 0, 0, 0.3)',
255+
padding: '4px 8px',
256+
borderRadius: '4px',
257+
fontSize: '11px'
258+
}}>
259+
npm install @dev-ahmed-mahmoud/react-custom-scrollbars
260+
</code>
261+
</div>
262+
</div>
263+
</div>
264+
</div>
265+
)
266+
}
267+
268+
export default App

examples/modern-demo/src/main.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from 'react'
2+
import ReactDOM from 'react-dom/client'
3+
import App from './App'
4+
5+
ReactDOM.createRoot(document.getElementById('root')!).render(
6+
<React.StrictMode>
7+
<App />
8+
</React.StrictMode>,
9+
)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { defineConfig } from 'vite'
2+
import react from '@vitejs/plugin-react'
3+
4+
export default defineConfig({
5+
plugins: [react()],
6+
server: {
7+
port: 3000,
8+
host: true
9+
}
10+
})

0 commit comments

Comments
 (0)