react-abohook-fullpage 1.1.5

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,199 @@
1
+ # 🚀 react-abohook-fullpage
2
+
3
+ [![npm version](https://img.shields.io/npm/v/react-abohook-fullpage.svg)](https://www.npmjs.com/package/react-abohook-fullpage)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
5
+ [![GitHub](https://img.shields.io/badge/GitHub-mostafa0x-181717?logo=github)](https://github.com/mostafa0x)
6
+
7
+ Lightweight & Modern React FullPage Scrolling Library
8
+ Smooth Transitions • Touch Ready • Keyboard Support • ~5KB gzip
9
+
10
+ <p align="center">
11
+ <img src="https://i.makeagif.com/media/2-28-2026/oL8iYS.gif" alt="React Abohook FullPage Demo" />
12
+ </p>
13
+
14
+ ---
15
+
16
+ ## ✨ Features
17
+
18
+ - 🖥 Smooth full-page section transitions
19
+ - 🖱 Mouse wheel navigation
20
+ - ⌨ Keyboard arrow navigation
21
+ - 📱 Touch & swipe support (mobile optimized)
22
+ - 🧭 Programmatic section control
23
+ - 🦶 Optional footer support
24
+ - 🔒 Built-in animation lock (prevents scroll spam)
25
+ - ⚡ Lightweight (~5KB gzip)
26
+ - 📦 No external animation libraries
27
+
28
+ ---
29
+
30
+ ## 🎯 Perfect For
31
+
32
+ - Landing pages
33
+ - Product showcases
34
+ - Portfolio websites
35
+ - Agency websites
36
+ - One-page applications
37
+
38
+ ---
39
+
40
+ ## 📦 Installation
41
+
42
+ ```bash
43
+ npm install react-abohook-fullpage
44
+ ```
45
+
46
+ or
47
+
48
+ ```bash
49
+ yarn add react-abohook-fullpage
50
+ ```
51
+
52
+ ---
53
+
54
+ ## 🛠 Basic Usage
55
+
56
+ ```jsx
57
+ import { FullPage } from "react-abohook-fullpage";
58
+
59
+ export default function App() {
60
+ return (
61
+ <div
62
+ style={{
63
+ display: "flex",
64
+ flexDirection: "column",
65
+ backgroundColor: "black",
66
+ }}
67
+ >
68
+ <FullPage directionDots="right" duration={700}>
69
+ <FullPage.Section>
70
+ <div
71
+ style={{
72
+ backgroundColor: "deeppink",
73
+ display: "flex",
74
+ flexDirection: "column",
75
+ justifyContent: "center",
76
+ alignItems: "center",
77
+ width: "100%",
78
+ height: "100%",
79
+ }}
80
+ >
81
+ <h1 style={{ fontSize: 24, color: "white" }}>
82
+ @abohook/fullpage Example
83
+ </h1>
84
+ <a
85
+ target="_blank"
86
+ rel="noreferrer"
87
+ style={{ fontSize: 22, color: "white" }}
88
+ href="https://github.com/mostafa0x"
89
+ >
90
+ By Mostafa Ahmed
91
+ </a>
92
+ </div>
93
+ </FullPage.Section>
94
+ <FullPage.Section>
95
+ <div
96
+ style={{
97
+ backgroundColor: "orange",
98
+ display: "flex",
99
+ flexDirection: "column",
100
+ justifyContent: "center",
101
+ alignItems: "center",
102
+ width: "100%",
103
+ height: "100%",
104
+ }}
105
+ >
106
+ <h1 style={{ fontSize: 24, color: "white" }}>Section 1</h1>
107
+ </div>
108
+ </FullPage.Section>
109
+ <FullPage.Section>
110
+ <div
111
+ style={{
112
+ backgroundColor: "blue",
113
+ display: "flex",
114
+ flexDirection: "column",
115
+ justifyContent: "center",
116
+ alignItems: "center",
117
+ width: "100%",
118
+ height: "100%",
119
+ }}
120
+ >
121
+ <h1 style={{ fontSize: 24, color: "white" }}>Section 2</h1>
122
+ </div>
123
+ </FullPage.Section>
124
+ <FullPage.Footer>
125
+ <div
126
+ style={{
127
+ display: "flex",
128
+ justifyContent: "center",
129
+ alignItems: "center",
130
+ height: "100%",
131
+ }}
132
+ >
133
+ <h2>Footer</h2>
134
+ </div>
135
+ </FullPage.Footer>
136
+ </FullPage>
137
+ </div>
138
+ );
139
+ }
140
+ ```
141
+
142
+ ---
143
+
144
+ ## ⚙️ API Overview
145
+
146
+ ### `<FullPage />`
147
+
148
+ | Prop | Type | Default | Description |
149
+ | ------------------- | ------------------------------- | ----------- | ----------------------------------- |
150
+ | `onChange` | `(index: number) => void` | `undefined` | Triggered when section changes |
151
+ | `duration` | `number` | `700` | Transition duration in milliseconds |
152
+ | `directionDots` | `"left" \| "right" \| "bottom"` | `"right"` | Position of navigation dots |
153
+ | `enableContextMenu` | `boolean` | `false` | Enable right-click context menu |
154
+ | `closeOutside` | `boolean` | `false` | Close When click outside |
155
+
156
+ ---
157
+
158
+ ### `<FullPage.Section />`
159
+
160
+ Wrap each full screen section.
161
+
162
+ ---
163
+
164
+ ### `<FullPage.Footer />`
165
+
166
+ Optional footer that appears after the last section.
167
+
168
+ ---
169
+
170
+ ## ⚡ Why react-abohook-fullpage?
171
+
172
+ Unlike heavy animation-based fullpage libraries:
173
+
174
+ - ❌ No framer-motion required
175
+ - ❌ No GSAP required
176
+ - ❌ No large dependencies
177
+ - ✅ Pure lightweight logic
178
+ - ✅ Optimized for performance
179
+ - ✅ Clean developer API
180
+ - ✅ Production-ready
181
+
182
+ ---
183
+
184
+ ## 📱 Cross-Platform Ready
185
+
186
+ Works seamlessly across:
187
+
188
+ - Desktop browsers
189
+ - Mobile devices
190
+ - Touch screens
191
+ - Keyboard navigation
192
+
193
+ Built for real-world production environments.
194
+
195
+ ---
196
+
197
+ ## 📄 License
198
+
199
+ MIT © Mostafa Ahmed
@@ -0,0 +1,6 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react");var C={exports:{}},O={};var H;function oe(){if(H)return O;H=1;var r=Symbol.for("react.transitional.element"),n=Symbol.for("react.fragment");function l(d,s,o){var a=null;if(o!==void 0&&(a=""+o),s.key!==void 0&&(a=""+s.key),"key"in s){o={};for(var m in s)m!=="key"&&(o[m]=s[m])}else o=s;return s=o.ref,{$$typeof:r,type:d,key:a,ref:s!==void 0?s:null,props:o}}return O.Fragment=n,O.jsx=l,O.jsxs=l,O}var j={};var X;function ae(){return X||(X=1,process.env.NODE_ENV!=="production"&&(function(){function r(e){if(e==null)return null;if(typeof e=="function")return e.$$typeof===te?null:e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case p:return"Fragment";case v:return"Profiler";case h:return"StrictMode";case N:return"Suspense";case E:return"SuspenseList";case ee:return"Activity"}if(typeof e=="object")switch(typeof e.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case P:return"Portal";case T:return e.displayName||"Context";case y:return(e._context.displayName||"Context")+".Consumer";case F:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case K:return t=e.displayName||null,t!==null?t:r(e.type)||"Memo";case Y:t=e._payload,e=e._init;try{return r(e(t))}catch{}}return null}function n(e){return""+e}function l(e){try{n(e);var t=!1}catch{t=!0}if(t){t=console;var i=t.error,c=typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return i.call(t,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",c),n(e)}}function d(e){if(e===p)return"<>";if(typeof e=="object"&&e!==null&&e.$$typeof===Y)return"<...>";try{var t=r(e);return t?"<"+t+">":"<...>"}catch{return"<...>"}}function s(){var e=I.A;return e===null?null:e.getOwner()}function o(){return Error("react-stack-top-frame")}function a(e){if(W.call(e,"key")){var t=Object.getOwnPropertyDescriptor(e,"key").get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function m(e,t){function i(){z||(z=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}i.isReactWarning=!0,Object.defineProperty(e,"key",{get:i,configurable:!0})}function g(){var e=r(this.type);return G[e]||(G[e]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),e=this.props.ref,e!==void 0?e:null}function b(e,t,i,c,L,D){var f=i.ref;return e={$$typeof:x,type:e,key:t,props:i,_owner:c},(f!==void 0?f:null)!==null?Object.defineProperty(e,"ref",{enumerable:!1,get:g}):Object.defineProperty(e,"ref",{enumerable:!1,value:null}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:L}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:D}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function w(e,t,i,c,L,D){var f=t.children;if(f!==void 0)if(c)if(re(f)){for(c=0;c<f.length;c++)S(f[c]);Object.freeze&&Object.freeze(f)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else S(f);if(W.call(t,"key")){f=r(e);var A=Object.keys(t).filter(function(ne){return ne!=="key"});c=0<A.length?"{key: someKey, "+A.join(": ..., ")+": ...}":"{key: someKey}",J[f+c]||(A=0<A.length?"{"+A.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
2
+ let props = %s;
3
+ <%s {...props} />
4
+ React keys must be passed directly to JSX without using spread:
5
+ let props = %s;
6
+ <%s key={someKey} {...props} />`,c,f,A,f),J[f+c]=!0)}if(f=null,i!==void 0&&(l(i),f=""+i),a(t)&&(l(t.key),f=""+t.key),"key"in t){i={};for(var M in t)M!=="key"&&(i[M]=t[M])}else i=t;return f&&m(i,typeof e=="function"?e.displayName||e.name||"Unknown":e),b(e,f,i,s(),L,D)}function S(e){k(e)?e._store&&(e._store.validated=1):typeof e=="object"&&e!==null&&e.$$typeof===Y&&(e._payload.status==="fulfilled"?k(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function k(e){return typeof e=="object"&&e!==null&&e.$$typeof===x}var R=u,x=Symbol.for("react.transitional.element"),P=Symbol.for("react.portal"),p=Symbol.for("react.fragment"),h=Symbol.for("react.strict_mode"),v=Symbol.for("react.profiler"),y=Symbol.for("react.consumer"),T=Symbol.for("react.context"),F=Symbol.for("react.forward_ref"),N=Symbol.for("react.suspense"),E=Symbol.for("react.suspense_list"),K=Symbol.for("react.memo"),Y=Symbol.for("react.lazy"),ee=Symbol.for("react.activity"),te=Symbol.for("react.client.reference"),I=R.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,W=Object.prototype.hasOwnProperty,re=Array.isArray,$=console.createTask?console.createTask:function(){return null};R={react_stack_bottom_frame:function(e){return e()}};var z,G={},V=R.react_stack_bottom_frame.bind(R,o)(),q=$(d(o)),J={};j.Fragment=p,j.jsx=function(e,t,i){var c=1e4>I.recentlyCreatedOwnerStacks++;return w(e,t,i,!1,c?Error("react-stack-top-frame"):V,c?$(d(e)):q)},j.jsxs=function(e,t,i){var c=1e4>I.recentlyCreatedOwnerStacks++;return w(e,t,i,!0,c?Error("react-stack-top-frame"):V,c?$(d(e)):q)}})()),j}var B;function se(){return B||(B=1,process.env.NODE_ENV==="production"?C.exports=oe():C.exports=ae()),C.exports}var _=se();const ie=50,le=(r,n,l,d=700,s)=>{const[o,a]=u.useState(0),[m,g]=u.useState(!0),b=u.useRef(!1),[w,S]=u.useState(0),k=n&&o+1===r,R=u.useRef(0),x=u.useRef(0),P=u.useRef(!1),p=u.useRef(null),h=(v,y)=>{if(v<0||v>=r||b.current)return;const T=y===2;b.current=!0,S(o),a(v),k?v===3||o===r-1?a(T?w:v):a(w):a(v),n&&r===v+1?g(!1):g(!0),setTimeout(()=>{b.current=!1},d)};return u.useEffect(()=>{l&&l(o);const v=E=>{if(b.current)return E.preventDefault();E.deltaY>0?h(o+1,2):h(o-1,2)},y=E=>{b.current||(E.key==="ArrowDown"&&h(o+1,2),E.key==="ArrowUp"&&h(o-1,2))},T=E=>{R.current=E.touches[0].clientY,P.current=!1},F=E=>{x.current=E.touches[0].clientY,P.current=!0},N=()=>{if(!P.current)return;const E=R.current-x.current;Math.abs(E)>=ie&&(E>0?h(o+1,2):h(o-1,2))};return window.addEventListener("wheel",v,{passive:!1}),window.addEventListener("keydown",y),window.addEventListener("touchstart",T,{passive:!0}),window.addEventListener("touchmove",F,{passive:!0}),window.addEventListener("touchend",N),()=>{window.removeEventListener("wheel",v),window.removeEventListener("keydown",y),window.removeEventListener("touchstart",T),window.removeEventListener("touchmove",F),window.removeEventListener("touchend",N)}},[o,r,n,l]),u.useEffect(()=>{if(!s)return;const v=y=>{if(b.current&&m)return;const T=y.target;p.current&&!p.current.contains(T)&&!m&&(a(w),g(!0))};return setTimeout(()=>{document.addEventListener("click",v)},300),()=>{document.removeEventListener("click",v)}},[w,m,s]),{active:o,goToSection:h,isHiddenFooter:m,footerRef:p}},ue=(r=!1)=>{u.useEffect(()=>{if(r)return;const n=l=>l.preventDefault();return window.addEventListener("contextmenu",n),()=>{window.removeEventListener("contextmenu",n)}},[r])};function ce({children:r,index:n,active:l,isHiddenFooter:d}){return _.jsx("section",{style:{position:"relative",width:"100%",height:"100vh",overflow:"hidden",filter:n===l||d?"blur(0px)":"blur(6px)"},children:r})}const fe=u.memo(ce);function de({sectionsLen:r,active:n,goToSection:l,direction:d="right"}){const s=d==="bottom";return _.jsx("div",{style:{position:"fixed",right:d==="right"?24:d==="bottom"?"50%":void 0,left:d==="left"?24:void 0,top:s?void 0:"50%",bottom:s?"5%":void 0,transform:"translateY(-50%)",display:"flex",flexDirection:s?"row":"column",gap:"16px",zIndex:50},children:Array.from({length:r}).map((o,a)=>_.jsx("button",{disabled:a===n,"aria-label":"navigation dot",onClick:()=>l(a,1),style:{width:"16px",height:"16px",display:"flex",alignItems:"center",justifyContent:"center",padding:0,border:"none",background:"none",cursor:"pointer",userSelect:"none"},children:_.jsx("span",{style:{width:"10px",height:"10px",borderRadius:"50%",backgroundColor:n===a?"white":"rgba(255,255,255,0.4)",transform:n===a?"scale(1.25)":"scale(1)",transition:"all 0.3s ease"}})},a))})}const me=u.memo(de);function ve({children:r}){return _.jsx("div",{style:{position:"relative",width:"100%",height:"100vh",overflow:"hidden",background:"transparent"},children:r})}const Z=u.memo(ve);Z.__FULLPAGE_SECTION__=!0;function Ee({children:r,styles:n,height:l="30%",backgroundColor:d="yellow",footerRef:s}){return _.jsx("div",{ref:s,style:{position:"absolute",width:"100%",height:l,backgroundColor:d,bottom:0,zIndex:50,...n},children:r},"fullpage-footer")}const Q=u.memo(Ee);Q.__FULLPAGE_FOOTER__=!0;function _e(r){process.env.NODE_ENV!=="production"&&r.forEach(n=>{if(u.isValidElement(n)&&!n.type.__FULLPAGE_SECTION__)throw console.warn("[FullPage] You must wrap content inside <FullPage.Section />"),new Error("[FullPage] You must wrap content inside <FullPage.Section />")})}function pe({children:r,isHiddenFooter:n}){const l=n?2500:600;return _.jsx("div",{style:{position:"absolute",left:0,bottom:0,width:"100%",height:"100vh",zIndex:50,transform:n?"translateY(100%)":"translateY(0)",transition:`transform ${l}ms cubic-bezier(0.22,1,0.36,1)`,willChange:"transform",pointerEvents:n?"none":"auto"},children:r})}const he=u.memo(pe);function U({children:r,onChange:n,directionDots:l="right",enableContextMenu:d=!1,duration:s=700,closeOutside:o=!1}){const a=u.Children.toArray(r),m=a.filter(p=>p.type.__FULLPAGE_SECTION__),g=a.find(p=>p.type.__FULLPAGE_FOOTER__);ue(d),u.useEffect(()=>(_e(m),()=>{}),[m]);const b=!!g,w=m.length+(b?1:0),{active:S,goToSection:k,isHiddenFooter:R,footerRef:x}=le(w,b,n,s,o),P=g?u.cloneElement(g,{footerRef:x}):null;return _.jsxs(_.Fragment,{children:[_.jsxs("div",{style:{position:"relative",height:"100vh",width:"100%",overflow:"hidden"},children:[_.jsx("div",{style:{height:`${m.length*100}vh`,transform:R?`translateY(-${S*100}vh)`:`translateY(-${m.length-100}vh)`,transition:"transform 700ms cubic-bezier(0.22,1,0.36,1)"},children:m.map((p,h)=>_.jsx(fe,{index:h,active:S,isHiddenFooter:R,children:p},h))}),g&&_.jsx(he,{isHiddenFooter:R,children:P})]}),_.jsx(me,{sectionsLen:w,active:S,goToSection:k,direction:l})]})}U.Section=Z;U.Footer=Q;exports.FullPage=U;
@@ -0,0 +1,34 @@
1
+ import { default as default_2 } from 'react';
2
+ import { JSX as JSX_2 } from 'react/jsx-runtime';
3
+
4
+ declare type DirectionDotsType = "left" | "right" | "bottom";
5
+
6
+ export declare function FullPage({ children, onChange, directionDots, enableContextMenu, duration, closeOutside, }: FullPageProps): JSX_2.Element;
7
+
8
+ export declare namespace FullPage {
9
+ var Section: default_2.FC<FullPageSectionProps>;
10
+ var Footer: default_2.FC<FullPageFooterProps>;
11
+ }
12
+
13
+ declare interface FullPageFooterProps {
14
+ children: React.ReactNode;
15
+ styles?: React.CSSProperties;
16
+ height?: number | string;
17
+ backgroundColor?: string;
18
+ footerRef?: React.RefObject<HTMLDivElement | null>;
19
+ }
20
+
21
+ declare interface FullPageProps {
22
+ children: React.ReactNode;
23
+ onChange?: (currentSection: number) => void;
24
+ directionDots?: DirectionDotsType;
25
+ closeOutside?: boolean;
26
+ enableContextMenu?: boolean;
27
+ duration: number;
28
+ }
29
+
30
+ declare interface FullPageSectionProps {
31
+ children: React.ReactNode;
32
+ }
33
+
34
+ export { }
@@ -0,0 +1,540 @@
1
+ import I, { useEffect as $, useState as G, useRef as A, memo as N } from "react";
2
+ var Y = { exports: {} }, O = {};
3
+ var Z;
4
+ function le() {
5
+ if (Z) return O;
6
+ Z = 1;
7
+ var r = /* @__PURE__ */ Symbol.for("react.transitional.element"), n = /* @__PURE__ */ Symbol.for("react.fragment");
8
+ function l(f, s, o) {
9
+ var a = null;
10
+ if (o !== void 0 && (a = "" + o), s.key !== void 0 && (a = "" + s.key), "key" in s) {
11
+ o = {};
12
+ for (var d in s)
13
+ d !== "key" && (o[d] = s[d]);
14
+ } else o = s;
15
+ return s = o.ref, {
16
+ $$typeof: r,
17
+ type: f,
18
+ key: a,
19
+ ref: s !== void 0 ? s : null,
20
+ props: o
21
+ };
22
+ }
23
+ return O.Fragment = n, O.jsx = l, O.jsxs = l, O;
24
+ }
25
+ var j = {};
26
+ var Q;
27
+ function ue() {
28
+ return Q || (Q = 1, process.env.NODE_ENV !== "production" && (function() {
29
+ function r(e) {
30
+ if (e == null) return null;
31
+ if (typeof e == "function")
32
+ return e.$$typeof === ae ? null : e.displayName || e.name || null;
33
+ if (typeof e == "string") return e;
34
+ switch (e) {
35
+ case _:
36
+ return "Fragment";
37
+ case m:
38
+ return "Profiler";
39
+ case p:
40
+ return "StrictMode";
41
+ case L:
42
+ return "Suspense";
43
+ case v:
44
+ return "SuspenseList";
45
+ case oe:
46
+ return "Activity";
47
+ }
48
+ if (typeof e == "object")
49
+ switch (typeof e.tag == "number" && console.error(
50
+ "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
51
+ ), e.$$typeof) {
52
+ case S:
53
+ return "Portal";
54
+ case g:
55
+ return e.displayName || "Context";
56
+ case x:
57
+ return (e._context.displayName || "Context") + ".Consumer";
58
+ case F:
59
+ var t = e.render;
60
+ return e = e.displayName, e || (e = t.displayName || t.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e;
61
+ case ne:
62
+ return t = e.displayName || null, t !== null ? t : r(e.type) || "Memo";
63
+ case D:
64
+ t = e._payload, e = e._init;
65
+ try {
66
+ return r(e(t));
67
+ } catch {
68
+ }
69
+ }
70
+ return null;
71
+ }
72
+ function n(e) {
73
+ return "" + e;
74
+ }
75
+ function l(e) {
76
+ try {
77
+ n(e);
78
+ var t = !1;
79
+ } catch {
80
+ t = !0;
81
+ }
82
+ if (t) {
83
+ t = console;
84
+ var i = t.error, u = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object";
85
+ return i.call(
86
+ t,
87
+ "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
88
+ u
89
+ ), n(e);
90
+ }
91
+ }
92
+ function f(e) {
93
+ if (e === _) return "<>";
94
+ if (typeof e == "object" && e !== null && e.$$typeof === D)
95
+ return "<...>";
96
+ try {
97
+ var t = r(e);
98
+ return t ? "<" + t + ">" : "<...>";
99
+ } catch {
100
+ return "<...>";
101
+ }
102
+ }
103
+ function s() {
104
+ var e = M.A;
105
+ return e === null ? null : e.getOwner();
106
+ }
107
+ function o() {
108
+ return Error("react-stack-top-frame");
109
+ }
110
+ function a(e) {
111
+ if (V.call(e, "key")) {
112
+ var t = Object.getOwnPropertyDescriptor(e, "key").get;
113
+ if (t && t.isReactWarning) return !1;
114
+ }
115
+ return e.key !== void 0;
116
+ }
117
+ function d(e, t) {
118
+ function i() {
119
+ J || (J = !0, console.error(
120
+ "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
121
+ t
122
+ ));
123
+ }
124
+ i.isReactWarning = !0, Object.defineProperty(e, "key", {
125
+ get: i,
126
+ configurable: !0
127
+ });
128
+ }
129
+ function R() {
130
+ var e = r(this.type);
131
+ return q[e] || (q[e] = !0, console.error(
132
+ "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
133
+ )), e = this.props.ref, e !== void 0 ? e : null;
134
+ }
135
+ function h(e, t, i, u, C, W) {
136
+ var c = i.ref;
137
+ return e = {
138
+ $$typeof: y,
139
+ type: e,
140
+ key: t,
141
+ props: i,
142
+ _owner: u
143
+ }, (c !== void 0 ? c : null) !== null ? Object.defineProperty(e, "ref", {
144
+ enumerable: !1,
145
+ get: R
146
+ }) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", {
147
+ configurable: !1,
148
+ enumerable: !1,
149
+ writable: !0,
150
+ value: 0
151
+ }), Object.defineProperty(e, "_debugInfo", {
152
+ configurable: !1,
153
+ enumerable: !1,
154
+ writable: !0,
155
+ value: null
156
+ }), Object.defineProperty(e, "_debugStack", {
157
+ configurable: !1,
158
+ enumerable: !1,
159
+ writable: !0,
160
+ value: C
161
+ }), Object.defineProperty(e, "_debugTask", {
162
+ configurable: !1,
163
+ enumerable: !1,
164
+ writable: !0,
165
+ value: W
166
+ }), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e;
167
+ }
168
+ function b(e, t, i, u, C, W) {
169
+ var c = t.children;
170
+ if (c !== void 0)
171
+ if (u)
172
+ if (se(c)) {
173
+ for (u = 0; u < c.length; u++)
174
+ T(c[u]);
175
+ Object.freeze && Object.freeze(c);
176
+ } else
177
+ console.error(
178
+ "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
179
+ );
180
+ else T(c);
181
+ if (V.call(t, "key")) {
182
+ c = r(e);
183
+ var P = Object.keys(t).filter(function(ie) {
184
+ return ie !== "key";
185
+ });
186
+ u = 0 < P.length ? "{key: someKey, " + P.join(": ..., ") + ": ...}" : "{key: someKey}", B[c + u] || (P = 0 < P.length ? "{" + P.join(": ..., ") + ": ...}" : "{}", console.error(
187
+ `A props object containing a "key" prop is being spread into JSX:
188
+ let props = %s;
189
+ <%s {...props} />
190
+ React keys must be passed directly to JSX without using spread:
191
+ let props = %s;
192
+ <%s key={someKey} {...props} />`,
193
+ u,
194
+ c,
195
+ P,
196
+ c
197
+ ), B[c + u] = !0);
198
+ }
199
+ if (c = null, i !== void 0 && (l(i), c = "" + i), a(t) && (l(t.key), c = "" + t.key), "key" in t) {
200
+ i = {};
201
+ for (var z in t)
202
+ z !== "key" && (i[z] = t[z]);
203
+ } else i = t;
204
+ return c && d(
205
+ i,
206
+ typeof e == "function" ? e.displayName || e.name || "Unknown" : e
207
+ ), h(
208
+ e,
209
+ c,
210
+ i,
211
+ s(),
212
+ C,
213
+ W
214
+ );
215
+ }
216
+ function T(e) {
217
+ k(e) ? e._store && (e._store.validated = 1) : typeof e == "object" && e !== null && e.$$typeof === D && (e._payload.status === "fulfilled" ? k(e._payload.value) && e._payload.value._store && (e._payload.value._store.validated = 1) : e._store && (e._store.validated = 1));
218
+ }
219
+ function k(e) {
220
+ return typeof e == "object" && e !== null && e.$$typeof === y;
221
+ }
222
+ var w = I, y = /* @__PURE__ */ Symbol.for("react.transitional.element"), S = /* @__PURE__ */ Symbol.for("react.portal"), _ = /* @__PURE__ */ Symbol.for("react.fragment"), p = /* @__PURE__ */ Symbol.for("react.strict_mode"), m = /* @__PURE__ */ Symbol.for("react.profiler"), x = /* @__PURE__ */ Symbol.for("react.consumer"), g = /* @__PURE__ */ Symbol.for("react.context"), F = /* @__PURE__ */ Symbol.for("react.forward_ref"), L = /* @__PURE__ */ Symbol.for("react.suspense"), v = /* @__PURE__ */ Symbol.for("react.suspense_list"), ne = /* @__PURE__ */ Symbol.for("react.memo"), D = /* @__PURE__ */ Symbol.for("react.lazy"), oe = /* @__PURE__ */ Symbol.for("react.activity"), ae = /* @__PURE__ */ Symbol.for("react.client.reference"), M = w.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, V = Object.prototype.hasOwnProperty, se = Array.isArray, U = console.createTask ? console.createTask : function() {
223
+ return null;
224
+ };
225
+ w = {
226
+ react_stack_bottom_frame: function(e) {
227
+ return e();
228
+ }
229
+ };
230
+ var J, q = {}, H = w.react_stack_bottom_frame.bind(
231
+ w,
232
+ o
233
+ )(), X = U(f(o)), B = {};
234
+ j.Fragment = _, j.jsx = function(e, t, i) {
235
+ var u = 1e4 > M.recentlyCreatedOwnerStacks++;
236
+ return b(
237
+ e,
238
+ t,
239
+ i,
240
+ !1,
241
+ u ? Error("react-stack-top-frame") : H,
242
+ u ? U(f(e)) : X
243
+ );
244
+ }, j.jsxs = function(e, t, i) {
245
+ var u = 1e4 > M.recentlyCreatedOwnerStacks++;
246
+ return b(
247
+ e,
248
+ t,
249
+ i,
250
+ !0,
251
+ u ? Error("react-stack-top-frame") : H,
252
+ u ? U(f(e)) : X
253
+ );
254
+ };
255
+ })()), j;
256
+ }
257
+ var K;
258
+ function ce() {
259
+ return K || (K = 1, process.env.NODE_ENV === "production" ? Y.exports = le() : Y.exports = ue()), Y.exports;
260
+ }
261
+ var E = ce();
262
+ const fe = 50, de = (r, n, l, f = 700, s) => {
263
+ const [o, a] = G(0), [d, R] = G(!0), h = A(!1), [b, T] = G(0), k = n && o + 1 === r, w = A(0), y = A(0), S = A(!1), _ = A(null), p = (m, x) => {
264
+ if (m < 0 || m >= r || h.current) return;
265
+ const g = x === 2;
266
+ h.current = !0, T(o), a(m), k ? m === 3 || o === r - 1 ? a(g ? b : m) : a(b) : a(m), n && r === m + 1 ? R(!1) : R(!0), setTimeout(() => {
267
+ h.current = !1;
268
+ }, f);
269
+ };
270
+ return $(() => {
271
+ l && l(o);
272
+ const m = (v) => {
273
+ if (h.current) return v.preventDefault();
274
+ v.deltaY > 0 ? p(o + 1, 2) : p(o - 1, 2);
275
+ }, x = (v) => {
276
+ h.current || (v.key === "ArrowDown" && p(o + 1, 2), v.key === "ArrowUp" && p(o - 1, 2));
277
+ }, g = (v) => {
278
+ w.current = v.touches[0].clientY, S.current = !1;
279
+ }, F = (v) => {
280
+ y.current = v.touches[0].clientY, S.current = !0;
281
+ }, L = () => {
282
+ if (!S.current) return;
283
+ const v = w.current - y.current;
284
+ Math.abs(v) >= fe && (v > 0 ? p(o + 1, 2) : p(o - 1, 2));
285
+ };
286
+ return window.addEventListener("wheel", m, { passive: !1 }), window.addEventListener("keydown", x), window.addEventListener("touchstart", g, { passive: !0 }), window.addEventListener("touchmove", F, { passive: !0 }), window.addEventListener("touchend", L), () => {
287
+ window.removeEventListener("wheel", m), window.removeEventListener("keydown", x), window.removeEventListener("touchstart", g), window.removeEventListener("touchmove", F), window.removeEventListener("touchend", L);
288
+ };
289
+ }, [o, r, n, l]), $(() => {
290
+ if (!s) return;
291
+ const m = (x) => {
292
+ if (h.current && d) return;
293
+ const g = x.target;
294
+ _.current && !_.current.contains(g) && !d && (a(b), R(!0));
295
+ };
296
+ return setTimeout(() => {
297
+ document.addEventListener("click", m);
298
+ }, 300), () => {
299
+ document.removeEventListener("click", m);
300
+ };
301
+ }, [b, d, s]), { active: o, goToSection: p, isHiddenFooter: d, footerRef: _ };
302
+ }, me = (r = !1) => {
303
+ $(() => {
304
+ if (r) return;
305
+ const n = (l) => l.preventDefault();
306
+ return window.addEventListener("contextmenu", n), () => {
307
+ window.removeEventListener("contextmenu", n);
308
+ };
309
+ }, [r]);
310
+ };
311
+ function ve({
312
+ children: r,
313
+ index: n,
314
+ active: l,
315
+ isHiddenFooter: f
316
+ }) {
317
+ return /* @__PURE__ */ E.jsx(
318
+ "section",
319
+ {
320
+ style: {
321
+ position: "relative",
322
+ width: "100%",
323
+ height: "100vh",
324
+ overflow: "hidden",
325
+ filter: n === l || f ? "blur(0px)" : "blur(6px)"
326
+ },
327
+ children: r
328
+ }
329
+ );
330
+ }
331
+ const Ee = N(ve);
332
+ function _e({
333
+ sectionsLen: r,
334
+ active: n,
335
+ goToSection: l,
336
+ direction: f = "right"
337
+ }) {
338
+ const s = f === "bottom";
339
+ return /* @__PURE__ */ E.jsx(
340
+ "div",
341
+ {
342
+ style: {
343
+ position: "fixed",
344
+ right: f === "right" ? 24 : f === "bottom" ? "50%" : void 0,
345
+ left: f === "left" ? 24 : void 0,
346
+ top: s ? void 0 : "50%",
347
+ bottom: s ? "5%" : void 0,
348
+ transform: "translateY(-50%)",
349
+ display: "flex",
350
+ flexDirection: s ? "row" : "column",
351
+ gap: "16px",
352
+ zIndex: 50
353
+ },
354
+ children: Array.from({ length: r }).map((o, a) => /* @__PURE__ */ E.jsx(
355
+ "button",
356
+ {
357
+ disabled: a === n,
358
+ "aria-label": "navigation dot",
359
+ onClick: () => l(a, 1),
360
+ style: {
361
+ width: "16px",
362
+ height: "16px",
363
+ display: "flex",
364
+ alignItems: "center",
365
+ justifyContent: "center",
366
+ padding: 0,
367
+ border: "none",
368
+ background: "none",
369
+ cursor: "pointer",
370
+ userSelect: "none"
371
+ },
372
+ children: /* @__PURE__ */ E.jsx(
373
+ "span",
374
+ {
375
+ style: {
376
+ width: "10px",
377
+ height: "10px",
378
+ borderRadius: "50%",
379
+ backgroundColor: n === a ? "white" : "rgba(255,255,255,0.4)",
380
+ transform: n === a ? "scale(1.25)" : "scale(1)",
381
+ transition: "all 0.3s ease"
382
+ }
383
+ }
384
+ )
385
+ },
386
+ a
387
+ ))
388
+ }
389
+ );
390
+ }
391
+ const pe = N(_e);
392
+ function he({ children: r }) {
393
+ return /* @__PURE__ */ E.jsx(
394
+ "div",
395
+ {
396
+ style: {
397
+ position: "relative",
398
+ width: "100%",
399
+ height: "100vh",
400
+ overflow: "hidden",
401
+ background: "transparent"
402
+ },
403
+ children: r
404
+ }
405
+ );
406
+ }
407
+ const ee = N(he);
408
+ ee.__FULLPAGE_SECTION__ = !0;
409
+ function be({
410
+ children: r,
411
+ styles: n,
412
+ height: l = "30%",
413
+ backgroundColor: f = "yellow",
414
+ footerRef: s
415
+ }) {
416
+ return /* @__PURE__ */ E.jsx(
417
+ "div",
418
+ {
419
+ ref: s,
420
+ style: {
421
+ position: "absolute",
422
+ width: "100%",
423
+ height: l,
424
+ backgroundColor: f,
425
+ bottom: 0,
426
+ zIndex: 50,
427
+ ...n
428
+ },
429
+ children: r
430
+ },
431
+ "fullpage-footer"
432
+ );
433
+ }
434
+ const te = N(be);
435
+ te.__FULLPAGE_FOOTER__ = !0;
436
+ function we(r) {
437
+ process.env.NODE_ENV !== "production" && r.forEach((n) => {
438
+ if (I.isValidElement(n) && !n.type.__FULLPAGE_SECTION__)
439
+ throw console.warn(
440
+ "[FullPage] You must wrap content inside <FullPage.Section />"
441
+ ), new Error(
442
+ "[FullPage] You must wrap content inside <FullPage.Section />"
443
+ );
444
+ });
445
+ }
446
+ function Re({ children: r, isHiddenFooter: n }) {
447
+ const l = n ? 2500 : 600;
448
+ return /* @__PURE__ */ E.jsx(
449
+ "div",
450
+ {
451
+ style: {
452
+ position: "absolute",
453
+ left: 0,
454
+ bottom: 0,
455
+ width: "100%",
456
+ height: "100vh",
457
+ zIndex: 50,
458
+ transform: n ? "translateY(100%)" : "translateY(0)",
459
+ transition: `transform ${l}ms cubic-bezier(0.22,1,0.36,1)`,
460
+ willChange: "transform",
461
+ pointerEvents: n ? "none" : "auto"
462
+ },
463
+ children: r
464
+ }
465
+ );
466
+ }
467
+ const ge = N(Re);
468
+ function re({
469
+ children: r,
470
+ onChange: n,
471
+ directionDots: l = "right",
472
+ enableContextMenu: f = !1,
473
+ duration: s = 700,
474
+ closeOutside: o = !1
475
+ }) {
476
+ const a = I.Children.toArray(r), d = a.filter(
477
+ (_) => _.type.__FULLPAGE_SECTION__
478
+ ), R = a.find(
479
+ (_) => _.type.__FULLPAGE_FOOTER__
480
+ );
481
+ me(f), $(() => (we(d), () => {
482
+ }), [d]);
483
+ const h = !!R, b = d.length + (h ? 1 : 0), { active: T, goToSection: k, isHiddenFooter: w, footerRef: y } = de(
484
+ b,
485
+ h,
486
+ n,
487
+ s,
488
+ o
489
+ ), S = R ? I.cloneElement(R, { footerRef: y }) : null;
490
+ return /* @__PURE__ */ E.jsxs(E.Fragment, { children: [
491
+ /* @__PURE__ */ E.jsxs(
492
+ "div",
493
+ {
494
+ style: {
495
+ position: "relative",
496
+ height: "100vh",
497
+ width: "100%",
498
+ overflow: "hidden"
499
+ },
500
+ children: [
501
+ /* @__PURE__ */ E.jsx(
502
+ "div",
503
+ {
504
+ style: {
505
+ height: `${d.length * 100}vh`,
506
+ transform: w ? `translateY(-${T * 100}vh)` : `translateY(-${d.length - 100}vh)`,
507
+ transition: "transform 700ms cubic-bezier(0.22,1,0.36,1)"
508
+ },
509
+ children: d.map((_, p) => /* @__PURE__ */ E.jsx(
510
+ Ee,
511
+ {
512
+ index: p,
513
+ active: T,
514
+ isHiddenFooter: w,
515
+ children: _
516
+ },
517
+ p
518
+ ))
519
+ }
520
+ ),
521
+ R && /* @__PURE__ */ E.jsx(ge, { isHiddenFooter: w, children: S })
522
+ ]
523
+ }
524
+ ),
525
+ /* @__PURE__ */ E.jsx(
526
+ pe,
527
+ {
528
+ sectionsLen: b,
529
+ active: T,
530
+ goToSection: k,
531
+ direction: l
532
+ }
533
+ )
534
+ ] });
535
+ }
536
+ re.Section = ee;
537
+ re.Footer = te;
538
+ export {
539
+ re as FullPage
540
+ };
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "react-abohook-fullpage",
3
+ "version": "1.1.5",
4
+ "description": "React FullPage scroll component with parallax and navigation dots",
5
+ "author": "Mostafa Ahmed",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "dist/index.cjs.js",
9
+ "module": "dist/index.es.js",
10
+ "types": "dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.es.js",
15
+ "require": "./dist/index.cjs.js"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc && vite build "
23
+ },
24
+ "peerDependencies": {
25
+ "react": ">=18",
26
+ "react-dom": ">=18"
27
+ },
28
+ "sideEffects": false,
29
+ "keywords": [
30
+ "react",
31
+ "fullpage",
32
+ "parallax",
33
+ "scroll",
34
+ "one page scroll",
35
+ "css transitions"
36
+ ],
37
+ "devDependencies": {
38
+ "@types/node": "^25",
39
+ "@types/react": "^18",
40
+ "@types/react-dom": "^18",
41
+ "@vitejs/plugin-react": "^5",
42
+ "typescript": "^5",
43
+ "vite": "^7",
44
+ "vite-plugin-dts": "^4.5.4"
45
+ }
46
+ }