react-sway 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # react-sway
2
+
3
+ A React component for smooth, infinite, and interactive content scrolling. It duplicates content to create a seamless looping effect, controllable via touch, mouse drag, wheel, and keyboard.
4
+
5
+ ## What is `react-sway`?
6
+
7
+ React Sway takes your list of items and makes them scroll endlessly. It's designed to be easy to use and performant, with auto-scrolling that pauses when users interact.
8
+
9
+ It works by duplicating your content to create a seamless loop and uses CSS transforms for smooth animation. The duplicated content is wrapped in `<aside>` elements with `aria-hidden="true"` and `role="presentation"` to ensure good accessibility and helps search engines understand the content structure.
10
+
11
+ ### Core Features
12
+
13
+ * **Smooth Infinite Scroll:** Content loops continuously.
14
+ * **Auto-Scroll:** Scrolls automatically, with configurable speed.
15
+ * **User Friendly Interactions:**
16
+ * Click and drag to scroll.
17
+ * Swipe on touch devices.
18
+ * Mouse wheel support.
19
+ * Keyboard controls: Spacebar to pause/resume, ArrowUp/ArrowDown to scroll, Home/End to jump.
20
+ * **Responsive:** Adjusts to window resizing.
21
+ * **Lazy Loading Hook:** Add a `content-item` class to your child elements, and `react-sway` will add a `.visible` class when they enter the viewport. Handy for animations or loading content.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ npm install react-sway
27
+ # or
28
+ yarn add react-sway
29
+ # or
30
+ pnpm add react-sway
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ```tsx
36
+ import { ReactSway } from 'react-sway';
37
+ import './index.css'; // Your global styles
38
+
39
+ function SwayUsageExample() {
40
+ return (
41
+ <div className="scroller-container"> {/* Style this container to define ReactSway's area (e.g., full-page, or a specific height) */}
42
+ <ReactSway>
43
+ <div className="content-item" style={{ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }}>
44
+ <h2>Seamless Scrolling</h2>
45
+ <p>Experience buttery smooth infinite scrolling with no stutters or pauses.</p>
46
+ </div>
47
+
48
+ <div className="content-item" style={{ background: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)' }}>
49
+ <h2>Touch & Mouse Support</h2>
50
+ <p>Interact naturally with touch gestures, mouse wheel, or click-and-drag.</p>
51
+ </div>
52
+
53
+ <div className="content-item" style={{ background: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)' }}>
54
+ <h2>Momentum Scrolling</h2>
55
+ <p>Flick to scroll with realistic physics-based momentum and friction.</p>
56
+ </div>
57
+
58
+ <div className="content-item" style={{ background: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)' }}>
59
+ <h2>Performance Optimized</h2>
60
+ <p>Using requestAnimationFrame for 60+ FPS scrolling on all devices.</p>
61
+ </div>
62
+
63
+ <div className="content-item" style={{ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }}>
64
+ <h2>Responsive Design</h2>
65
+ <p>Adapts perfectly to any screen size and device orientation.</p>
66
+ </div>
67
+
68
+ <div className="content-item" style={{ background: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)' }}>
69
+ <h2>No Native Scroll</h2>
70
+ <p>Custom implementation avoids native scroll jank and inconsistencies.</p>
71
+ </div>
72
+
73
+ <div className="content-item" style={{ background: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)' }}>
74
+ <h2>Continuous Loop</h2>
75
+ <p>Content loops seamlessly without any visible seams or jumps.</p>
76
+ </div>
77
+ </ReactSway>
78
+ </div>
79
+ );
80
+ }
81
+
82
+ export default SwayUsageExample;
83
+ ```
84
+
85
+ ## License
86
+
87
+ This package is licensed under the [MIT License](../../LICENSE).
package/dist/index.cjs CHANGED
@@ -55,7 +55,6 @@ function ReactSway({ children }) {
55
55
  containerRef.current.offsetHeight;
56
56
  const currentContentHeight = containerRef.current.scrollHeight;
57
57
  const calculatedLoopPoint = currentContentHeight / 3;
58
- console.log("Calculating dimensions:", { currentContentHeight, calculatedLoopPoint });
59
58
  if (currentContentHeight > 0) {
60
59
  setContentHeight(currentContentHeight);
61
60
  setLoopPoint(calculatedLoopPoint);
@@ -314,18 +313,6 @@ function ReactSway({ children }) {
314
313
  observer.disconnect();
315
314
  };
316
315
  }, [children, contentHeight]);
317
- (0, import_react.useEffect)(() => {
318
- const originalBodyStyle = {
319
- touchAction: document.body.style.touchAction,
320
- overflow: document.body.style.overflow
321
- };
322
- document.body.style.touchAction = "none";
323
- document.body.style.overflow = "hidden";
324
- return () => {
325
- document.body.style.touchAction = originalBodyStyle.touchAction;
326
- document.body.style.overflow = originalBodyStyle.overflow;
327
- };
328
- }, []);
329
316
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
330
317
  "div",
331
318
  {
@@ -344,6 +331,8 @@ function ReactSway({ children }) {
344
331
  msUserSelect: "none",
345
332
  MozUserSelect: "none",
346
333
  overscrollBehavior: "contain",
334
+ overflow: "hidden",
335
+ // Prevent component's content from overflowing and causing page scroll
347
336
  // Ensure it's on top and can receive events
348
337
  pointerEvents: "auto",
349
338
  zIndex: 1
package/dist/index.js CHANGED
@@ -29,7 +29,6 @@ function ReactSway({ children }) {
29
29
  containerRef.current.offsetHeight;
30
30
  const currentContentHeight = containerRef.current.scrollHeight;
31
31
  const calculatedLoopPoint = currentContentHeight / 3;
32
- console.log("Calculating dimensions:", { currentContentHeight, calculatedLoopPoint });
33
32
  if (currentContentHeight > 0) {
34
33
  setContentHeight(currentContentHeight);
35
34
  setLoopPoint(calculatedLoopPoint);
@@ -288,18 +287,6 @@ function ReactSway({ children }) {
288
287
  observer.disconnect();
289
288
  };
290
289
  }, [children, contentHeight]);
291
- useEffect(() => {
292
- const originalBodyStyle = {
293
- touchAction: document.body.style.touchAction,
294
- overflow: document.body.style.overflow
295
- };
296
- document.body.style.touchAction = "none";
297
- document.body.style.overflow = "hidden";
298
- return () => {
299
- document.body.style.touchAction = originalBodyStyle.touchAction;
300
- document.body.style.overflow = originalBodyStyle.overflow;
301
- };
302
- }, []);
303
290
  return /* @__PURE__ */ jsxs(
304
291
  "div",
305
292
  {
@@ -318,6 +305,8 @@ function ReactSway({ children }) {
318
305
  msUserSelect: "none",
319
306
  MozUserSelect: "none",
320
307
  overscrollBehavior: "contain",
308
+ overflow: "hidden",
309
+ // Prevent component's content from overflowing and causing page scroll
321
310
  // Ensure it's on top and can receive events
322
311
  pointerEvents: "auto",
323
312
  zIndex: 1
package/package.json CHANGED
@@ -59,5 +59,5 @@
59
59
  },
60
60
  "type": "module",
61
61
  "types": "dist/index.d.ts",
62
- "version": "0.1.0"
62
+ "version": "0.1.1"
63
63
  }
package/src/ReactSway.tsx CHANGED
@@ -44,7 +44,7 @@ function ReactSway({ children }: ReactSwayProps) {
44
44
  const currentContentHeight = containerRef.current.scrollHeight;
45
45
  const calculatedLoopPoint = currentContentHeight / 3;
46
46
 
47
- console.log('Calculating dimensions:', { currentContentHeight, calculatedLoopPoint });
47
+ // console.log('Calculating dimensions:', { currentContentHeight, calculatedLoopPoint });
48
48
 
49
49
  if (currentContentHeight > 0) {
50
50
  setContentHeight(currentContentHeight);
@@ -354,24 +354,6 @@ function ReactSway({ children }: ReactSwayProps) {
354
354
  };
355
355
  }, [children, contentHeight]);
356
356
 
357
- // Apply styles to override conflicting CSS
358
- useEffect(() => {
359
- const originalBodyStyle = {
360
- touchAction: document.body.style.touchAction,
361
- overflow: document.body.style.overflow
362
- };
363
-
364
- // Override body styles that might conflict
365
- document.body.style.touchAction = 'none';
366
- document.body.style.overflow = 'hidden';
367
-
368
- return () => {
369
- // Restore original styles
370
- document.body.style.touchAction = originalBodyStyle.touchAction;
371
- document.body.style.overflow = originalBodyStyle.overflow;
372
- };
373
- }, []);
374
-
375
357
  return (
376
358
  <div
377
359
  className="react-sway-container scroller-content"
@@ -389,6 +371,7 @@ function ReactSway({ children }: ReactSwayProps) {
389
371
  msUserSelect: 'none',
390
372
  MozUserSelect: 'none',
391
373
  overscrollBehavior: 'contain',
374
+ overflow: 'hidden', // Prevent component's content from overflowing and causing page scroll
392
375
  // Ensure it's on top and can receive events
393
376
  pointerEvents: 'auto',
394
377
  zIndex: 1