@neveranyart/weaver 1.0.0

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/dist/hooks.mjs ADDED
@@ -0,0 +1,320 @@
1
+ // src/hooks/breakpoints.ts
2
+ import { useCallback, useState } from "react";
3
+
4
+ // src/hooks/screenCallback.ts
5
+ import { useLayoutEffect } from "react";
6
+ function useScreenCallback(callback, options) {
7
+ useLayoutEffect(() => {
8
+ const reportScreen = () => callback({
9
+ width: document.body.clientWidth,
10
+ height: document.documentElement.clientHeight
11
+ });
12
+ if (options?.initialCall) {
13
+ reportScreen();
14
+ }
15
+ window.addEventListener("resize", reportScreen, { passive: true });
16
+ return () => {
17
+ window.removeEventListener("resize", reportScreen);
18
+ };
19
+ }, [callback, options?.initialCall]);
20
+ }
21
+
22
+ // src/hooks/breakpoints.ts
23
+ function useBreakpoints(breakpoints) {
24
+ const getBreakpoint = useCallback(
25
+ (width) => {
26
+ const processingBreakpoints = !breakpoints ? [640, 768, 1024, 1280, 1536] : breakpoints;
27
+ if (!processingBreakpoints) {
28
+ throw Error("Uhhh... so you don't want a breakpoint? Just say it.");
29
+ }
30
+ let result = processingBreakpoints.length;
31
+ for (let index = 0; index < processingBreakpoints.length; index++) {
32
+ if (width < processingBreakpoints[index]) {
33
+ result = index;
34
+ break;
35
+ }
36
+ }
37
+ return result;
38
+ },
39
+ [breakpoints]
40
+ );
41
+ const [breakAt, setBreakAt] = useState(
42
+ getBreakpoint(document.body.clientWidth)
43
+ );
44
+ const breakpointCheck = useCallback(
45
+ (latest) => {
46
+ const result = getBreakpoint(latest.width);
47
+ if (result !== breakAt) {
48
+ setBreakAt(result);
49
+ }
50
+ },
51
+ [breakAt, getBreakpoint]
52
+ );
53
+ useScreenCallback(breakpointCheck);
54
+ return breakAt;
55
+ }
56
+
57
+ // src/hooks/effectOnce.ts
58
+ import { useEffect, useLayoutEffect as useLayoutEffect2 } from "react";
59
+ function useEffectOnce(callback) {
60
+ useEffect(callback, []);
61
+ }
62
+ function useLayoutEffectOnce(callback) {
63
+ useLayoutEffect2(callback, []);
64
+ }
65
+
66
+ // src/hooks/lenisCallback.ts
67
+ import { useCallback as useCallback2, useLayoutEffect as useLayoutEffect4, useMemo } from "react";
68
+
69
+ // src/index.ts
70
+ var lenisInstance = void 0;
71
+
72
+ // src/hooks/orbit.ts
73
+ import { useLayoutEffect as useLayoutEffect3 } from "react";
74
+ function useOrbit(options) {
75
+ const { onResize, onIntersect } = options.events;
76
+ const { rootMargin = "25% 0px 25% 0px" } = options;
77
+ useLayoutEffect3(() => {
78
+ if (!options.target) return;
79
+ if (!options.target.current) return;
80
+ let orbitResize = void 0;
81
+ if (onResize) {
82
+ orbitResize = new ResizeObserver((entries) => onResize(entries[0]));
83
+ orbitResize.observe(options.target.current);
84
+ }
85
+ let orbitIntersect = void 0;
86
+ if (onIntersect) {
87
+ orbitIntersect = new IntersectionObserver(
88
+ (entries) => onIntersect(entries[0]),
89
+ { rootMargin }
90
+ );
91
+ orbitIntersect.observe(options.target.current);
92
+ }
93
+ return () => {
94
+ orbitResize?.disconnect();
95
+ orbitIntersect?.disconnect();
96
+ };
97
+ }, [onIntersect, onResize, rootMargin, options.target]);
98
+ }
99
+
100
+ // src/hooks/lenisCallback.ts
101
+ var scrollCallbackReason = {
102
+ Resize: "resize",
103
+ Scroll: "scroll",
104
+ Initialize: "initialize"
105
+ };
106
+ function useLenisCallback(callback, options) {
107
+ const callbackWrapScroll = useCallback2(
108
+ () => callback(lenisInstance.actualScroll, scrollCallbackReason.Scroll),
109
+ [callback]
110
+ );
111
+ const callbackWrapResize = useCallback2(
112
+ () => callback(lenisInstance.actualScroll, scrollCallbackReason.Resize),
113
+ [callback]
114
+ );
115
+ const intersectOn = useMemo(
116
+ () => options?.intersectOn,
117
+ [options?.intersectOn]
118
+ );
119
+ const initialCall = useMemo(
120
+ () => options?.initialCall,
121
+ [options?.initialCall]
122
+ );
123
+ useOrbit({
124
+ target: intersectOn,
125
+ events: {
126
+ onIntersect(entry) {
127
+ if (entry.isIntersecting) {
128
+ lenisInstance.on("scroll", callbackWrapScroll);
129
+ window.addEventListener("resize", callbackWrapResize);
130
+ } else {
131
+ lenisInstance.off("scroll", callbackWrapScroll);
132
+ window.removeEventListener("resize", callbackWrapResize);
133
+ }
134
+ }
135
+ },
136
+ rootMargin: "50% 0px 50% 0px"
137
+ });
138
+ useLayoutEffect4(() => {
139
+ if (!intersectOn) {
140
+ lenisInstance.on("scroll", callbackWrapScroll);
141
+ window.addEventListener("resize", callbackWrapResize);
142
+ }
143
+ if (initialCall) {
144
+ callback(lenisInstance.actualScroll, scrollCallbackReason.Initialize);
145
+ }
146
+ return () => {
147
+ lenisInstance.off("scroll", callbackWrapScroll);
148
+ window.removeEventListener("resize", callbackWrapResize);
149
+ };
150
+ }, [
151
+ callback,
152
+ callbackWrapResize,
153
+ callbackWrapScroll,
154
+ initialCall,
155
+ intersectOn
156
+ ]);
157
+ }
158
+
159
+ // src/hooks/mouseCallback.ts
160
+ import { useId, useLayoutEffect as useLayoutEffect5 } from "react";
161
+ var MouseEventDistributor = class {
162
+ callbacks = /* @__PURE__ */ new Map();
163
+ eventRegistered = false;
164
+ constructor() {
165
+ if (this.eventRegistered) return;
166
+ window.addEventListener("pointermove", this.callbackLoop.bind(this), {
167
+ passive: true
168
+ });
169
+ this.eventRegistered = true;
170
+ }
171
+ addCallbackLoop(id, callback, options) {
172
+ this.callbacks.set(id, { callback, options });
173
+ }
174
+ removeCallbackLoop(id) {
175
+ this.callbacks.delete(id);
176
+ }
177
+ processEvent(event) {
178
+ const mouse = {
179
+ x: event.clientX,
180
+ y: event.clientY
181
+ };
182
+ const mouseNormalized = {
183
+ x: mouse.x / (document.body.clientWidth / 2) - 1,
184
+ y: mouse.y / (document.documentElement.clientHeight / 2) - 1
185
+ };
186
+ return [mouse, mouseNormalized];
187
+ }
188
+ callbackLoop(event) {
189
+ if (event.pointerType !== "mouse") return;
190
+ const callbacks = this.callbacks.entries();
191
+ const [mouse, mouseNormalized] = this.processEvent(event);
192
+ let inspecting = callbacks.next().value;
193
+ while (inspecting) {
194
+ if (inspecting[1].options.normalized) {
195
+ inspecting[1].callback(mouseNormalized);
196
+ } else {
197
+ inspecting[1].callback(mouse);
198
+ }
199
+ inspecting = callbacks.next().value;
200
+ }
201
+ }
202
+ };
203
+ var distributor = new MouseEventDistributor();
204
+ function useMouseCallback(callback, options = {
205
+ normalized: true
206
+ }) {
207
+ const id = useId();
208
+ useLayoutEffect5(() => {
209
+ distributor.addCallbackLoop(id, callback, options);
210
+ return () => {
211
+ distributor.removeCallbackLoop(id);
212
+ };
213
+ }, [callback, id, options]);
214
+ }
215
+
216
+ // src/hooks/navigateAnchor.ts
217
+ import { useCallback as useCallback3 } from "react";
218
+ import { useNavigate } from "react-router";
219
+ function useNavigateAnchor(onNavigate) {
220
+ const navigate = useNavigate();
221
+ return useCallback3(
222
+ (event) => {
223
+ event.preventDefault();
224
+ const href = event.currentTarget.getAttribute("href");
225
+ if (href) {
226
+ if (onNavigate) {
227
+ onNavigate();
228
+ }
229
+ if (href !== window.location.pathname) {
230
+ navigate(event.currentTarget.getAttribute("href") ?? "");
231
+ } else {
232
+ lenisInstance.scrollTo(0, { duration: 2 });
233
+ }
234
+ }
235
+ },
236
+ [onNavigate, navigate]
237
+ );
238
+ }
239
+
240
+ // src/hooks/rawParams.ts
241
+ import { useLocation } from "react-router";
242
+ function useRawParams(prefix, limit) {
243
+ const { pathname } = useLocation();
244
+ const prefixedPath = pathname.replace(new RegExp(prefix), "");
245
+ if (prefixedPath === pathname) {
246
+ return [];
247
+ }
248
+ return prefixedPath.split("/").filter((param) => param !== "").slice(limit);
249
+ }
250
+
251
+ // src/hooks/routeNormalizer.ts
252
+ import { useCallback as useCallback4, useLayoutEffect as useLayoutEffect6 } from "react";
253
+ import { useLocation as useLocation2, useNavigate as useNavigate2 } from "react-router";
254
+ function useRouteNormalizer(options) {
255
+ const { pathname } = useLocation2();
256
+ const navigate = useNavigate2();
257
+ const normalizer = useCallback4(
258
+ (input) => input.replace(/\/+\//g, () => "/"),
259
+ []
260
+ );
261
+ useLayoutEffect6(() => {
262
+ const result = normalizer(pathname);
263
+ if (options.autoReplace && result !== pathname) {
264
+ window.location.replace(result);
265
+ }
266
+ }, [options.autoReplace, pathname, navigate, normalizer]);
267
+ return {
268
+ pathname,
269
+ normalizer
270
+ };
271
+ }
272
+
273
+ // src/hooks/screen.ts
274
+ import { useCallback as useCallback5, useLayoutEffect as useLayoutEffect7, useState as useState2 } from "react";
275
+ function useScreen() {
276
+ const [width, setWidth] = useState2(document.body.clientWidth);
277
+ const [height, setHeight] = useState2(document.documentElement.clientHeight);
278
+ const setScreen = useCallback5(() => {
279
+ setWidth(document.body.clientWidth);
280
+ setHeight(document.documentElement.clientHeight);
281
+ }, []);
282
+ useLayoutEffect7(() => {
283
+ window.addEventListener("resize", setScreen, { passive: true });
284
+ return () => {
285
+ window.removeEventListener("resize", setScreen);
286
+ };
287
+ }, [setScreen]);
288
+ return { width, height };
289
+ }
290
+
291
+ // src/hooks/viewport.ts
292
+ import { useThree } from "@react-three/fiber";
293
+ import { useCallback as useCallback6, useState as useState3 } from "react";
294
+ function useViewport(customCamera) {
295
+ const { viewport, camera } = useThree();
296
+ const [width, setWidth] = useState3(viewport.getCurrentViewport().width);
297
+ const [height, setHeight] = useState3(viewport.getCurrentViewport().height);
298
+ const viewportUpdate = useCallback6(() => {
299
+ const actualViewport = viewport.getCurrentViewport(customCamera ?? camera);
300
+ setWidth(actualViewport.width);
301
+ setHeight(actualViewport.height);
302
+ }, [camera, customCamera, viewport]);
303
+ useScreenCallback(viewportUpdate);
304
+ return { width, height };
305
+ }
306
+ export {
307
+ useBreakpoints,
308
+ useEffectOnce,
309
+ useLayoutEffectOnce,
310
+ useLenisCallback,
311
+ useMouseCallback,
312
+ useNavigateAnchor,
313
+ useOrbit,
314
+ useRawParams,
315
+ useRouteNormalizer,
316
+ useScreen,
317
+ useScreenCallback,
318
+ useViewport
319
+ };
320
+ //# sourceMappingURL=hooks.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/breakpoints.ts","../src/hooks/screenCallback.ts","../src/hooks/effectOnce.ts","../src/hooks/lenisCallback.ts","../src/index.ts","../src/hooks/orbit.ts","../src/hooks/mouseCallback.ts","../src/hooks/navigateAnchor.ts","../src/hooks/rawParams.ts","../src/hooks/routeNormalizer.ts","../src/hooks/screen.ts","../src/hooks/viewport.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { useScreenCallback } from './screenCallback';\n\nexport function useBreakpoints(breakpoints?: number[] | null) {\n const getBreakpoint = useCallback(\n (width: number) => {\n const processingBreakpoints = !breakpoints\n ? [640, 768, 1024, 1280, 1536]\n : breakpoints;\n\n if (!processingBreakpoints) {\n throw Error(\"Uhhh... so you don't want a breakpoint? Just say it.\");\n }\n\n let result = processingBreakpoints!.length;\n for (let index = 0; index < processingBreakpoints!.length; index++) {\n if (width < processingBreakpoints![index]) {\n result = index;\n break;\n }\n }\n\n return result;\n },\n [breakpoints]\n );\n\n const [breakAt, setBreakAt] = useState<number>(\n getBreakpoint(document.body.clientWidth)\n );\n\n const breakpointCheck = useCallback(\n (latest: { width: number; height: number }) => {\n const result = getBreakpoint(latest.width);\n if (result !== breakAt) {\n setBreakAt(result);\n }\n },\n [breakAt, getBreakpoint]\n );\n useScreenCallback(breakpointCheck);\n\n return breakAt;\n}\n","import { useLayoutEffect } from 'react';\n\nexport interface ScreenCallbackValues {\n width: number;\n height: number;\n}\n\ntype Callback = (props: ScreenCallbackValues) => void;\n\nexport function useScreenCallback(\n callback: Callback,\n options?: { initialCall?: boolean }\n) {\n useLayoutEffect(() => {\n const reportScreen = () =>\n callback({\n width: document.body.clientWidth,\n height: document.documentElement.clientHeight,\n });\n\n // Call it first time when the hook was initialized.\n if (options?.initialCall) {\n reportScreen();\n }\n\n window.addEventListener('resize', reportScreen, { passive: true });\n\n return () => {\n window.removeEventListener('resize', reportScreen);\n };\n }, [callback, options?.initialCall]);\n}\n","import { useEffect, useLayoutEffect } from 'react';\n\nexport function useEffectOnce(callback: React.EffectCallback) {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(callback, []);\n}\n\nexport function useLayoutEffectOnce(callback: React.EffectCallback) {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(callback, []);\n}\n","import { type RefObject, useCallback, useLayoutEffect, useMemo } from 'react';\nimport { lenisInstance } from '..';\nimport { useOrbit } from './orbit';\n\ninterface HookOptions {\n /**\n * Hook will report when first initialized without waiting for scroll event to actually happens.\n */\n initialCall?: boolean;\n /**\n * Set an element to only call when the element is actually entering the viewport (with 25% `rootMargin`).\n */\n intersectOn?: RefObject<HTMLOrSVGElement | null>;\n}\n\nexport const scrollCallbackReason = {\n Resize: 'resize',\n Scroll: 'scroll',\n Initialize: 'initialize',\n} as const;\nexport type ScrollCallbackReason =\n (typeof scrollCallbackReason)[keyof typeof scrollCallbackReason];\n\ntype Callback = (latest: number, reason: ScrollCallbackReason) => void;\n\nexport function useLenisCallback(callback: Callback, options?: HookOptions) {\n const callbackWrapScroll = useCallback(\n () => callback(lenisInstance!.actualScroll, scrollCallbackReason.Scroll),\n [callback]\n );\n const callbackWrapResize = useCallback(\n () => callback(lenisInstance!.actualScroll, scrollCallbackReason.Resize),\n [callback]\n );\n\n const intersectOn = useMemo(\n () => options?.intersectOn,\n [options?.intersectOn]\n );\n const initialCall = useMemo(\n () => options?.initialCall,\n [options?.initialCall]\n );\n\n useOrbit({\n target: intersectOn as RefObject<HTMLElement | null> | undefined,\n events: {\n onIntersect(entry) {\n if (entry.isIntersecting) {\n lenisInstance!.on('scroll', callbackWrapScroll);\n window.addEventListener('resize', callbackWrapResize);\n } else {\n lenisInstance!.off('scroll', callbackWrapScroll);\n window.removeEventListener('resize', callbackWrapResize);\n }\n },\n },\n rootMargin: '50% 0px 50% 0px',\n });\n\n useLayoutEffect(() => {\n if (!intersectOn) {\n lenisInstance!.on('scroll', callbackWrapScroll);\n window.addEventListener('resize', callbackWrapResize);\n }\n\n if (initialCall) {\n callback(lenisInstance!.actualScroll, scrollCallbackReason.Initialize);\n }\n\n return () => {\n lenisInstance!.off('scroll', callbackWrapScroll);\n window.removeEventListener('resize', callbackWrapResize);\n };\n }, [\n callback,\n callbackWrapResize,\n callbackWrapScroll,\n initialCall,\n intersectOn,\n ]);\n}\n","import Lenis from 'lenis';\nimport { ReactNode } from 'react';\n\nexport let lenisInstance: Lenis | undefined = undefined;\n\nexport type BasicTunnelIn = ({ children }: { children: ReactNode }) => null;\nexport let Default3DTunnelIn: BasicTunnelIn | undefined = undefined;\n\nexport const weaverSetup = {\n setLenisInstance(instance: Lenis) {\n lenisInstance = instance;\n },\n set3DTunnel(tunnelIn: BasicTunnelIn) {\n Default3DTunnelIn = tunnelIn;\n },\n};\n","import { type RefObject, useLayoutEffect } from 'react';\n\n/**\n * A simple Orbit hook.\n *\n * @param target HTML element ref to attach to.\n * @param events Specify which events should the orbit tracks.\n */\nexport function useOrbit(options: {\n target?: RefObject<HTMLElement | null>;\n events: {\n onResize?: (entry: ResizeObserverEntry) => void;\n onIntersect?: (entry: IntersectionObserverEntry) => void;\n };\n rootMargin?: string;\n}) {\n const { onResize, onIntersect } = options.events;\n const { rootMargin = '25% 0px 25% 0px' } = options;\n\n useLayoutEffect(() => {\n if (!options.target) return;\n if (!options.target.current) return;\n\n let orbitResize = undefined;\n if (onResize) {\n orbitResize = new ResizeObserver((entries) => onResize(entries[0]));\n orbitResize.observe(options.target.current);\n }\n let orbitIntersect = undefined;\n if (onIntersect) {\n orbitIntersect = new IntersectionObserver(\n (entries) => onIntersect(entries[0]),\n { rootMargin }\n );\n orbitIntersect.observe(options.target.current);\n }\n\n return () => {\n orbitResize?.disconnect();\n orbitIntersect?.disconnect();\n };\n }, [onIntersect, onResize, rootMargin, options.target]);\n}\n","import { useId, useLayoutEffect } from 'react';\n\nexport interface MousePositionValues {\n x: number;\n y: number;\n}\n\ninterface MouseCallback {\n callback: (latest: MousePositionValues) => void;\n options: HookOptions;\n}\n\ninterface HookOptions {\n normalized?: boolean;\n}\n\ntype Callback = (latest: MousePositionValues) => void;\n\nclass MouseEventDistributor {\n private callbacks = new Map<string, MouseCallback>();\n private eventRegistered = false;\n\n constructor() {\n if (this.eventRegistered) return;\n\n window.addEventListener('pointermove', this.callbackLoop.bind(this), {\n passive: true,\n });\n\n this.eventRegistered = true;\n }\n\n addCallbackLoop(\n id: string,\n callback: (latest: MousePositionValues) => void,\n options: HookOptions\n ) {\n this.callbacks.set(id, { callback, options });\n }\n\n removeCallbackLoop(id: string) {\n this.callbacks.delete(id);\n }\n\n private processEvent(event: PointerEvent) {\n const mouse = {\n x: event.clientX,\n y: event.clientY,\n };\n const mouseNormalized = {\n x: mouse.x / (document.body.clientWidth / 2) - 1,\n y: mouse.y / (document.documentElement.clientHeight / 2) - 1,\n };\n\n return [mouse, mouseNormalized];\n }\n\n private callbackLoop(event: PointerEvent) {\n if (event.pointerType !== 'mouse') return;\n\n const callbacks = this.callbacks.entries();\n const [mouse, mouseNormalized] = this.processEvent(event);\n\n let inspecting = callbacks.next().value;\n while (inspecting) {\n if (inspecting[1].options.normalized) {\n inspecting[1].callback(mouseNormalized);\n } else {\n inspecting[1].callback(mouse);\n }\n\n inspecting = callbacks.next().value;\n }\n }\n}\n\nconst distributor = new MouseEventDistributor();\n\nexport function useMouseCallback(\n callback: Callback,\n options: HookOptions = {\n normalized: true,\n }\n) {\n const id = useId();\n\n useLayoutEffect(() => {\n distributor.addCallbackLoop(id, callback, options);\n\n return () => {\n distributor.removeCallbackLoop(id);\n };\n }, [callback, id, options]);\n}\n","import { useCallback } from 'react';\nimport { useNavigate } from 'react-router';\nimport { lenisInstance } from '..';\n\nexport function useNavigateAnchor(onNavigate?: () => void) {\n const navigate = useNavigate();\n\n return useCallback(\n (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {\n event.preventDefault();\n const href = event.currentTarget.getAttribute('href');\n if (href) {\n if (onNavigate) {\n onNavigate();\n }\n\n if (href !== window.location.pathname) {\n navigate(event.currentTarget.getAttribute('href') ?? '');\n } else {\n lenisInstance!.scrollTo(0, { duration: 2 });\n }\n }\n },\n [onNavigate, navigate]\n );\n}\n","import { useLocation } from 'react-router';\n\nexport function useRawParams(\n prefix: string,\n limit?: number\n): (string | undefined)[] {\n const { pathname } = useLocation();\n\n const prefixedPath = pathname.replace(new RegExp(prefix), '');\n if (prefixedPath === pathname) {\n return [];\n }\n\n return prefixedPath\n .split('/')\n .filter((param) => param !== '')\n .slice(limit);\n}\n","import { useCallback, useLayoutEffect } from 'react';\nimport { useLocation, useNavigate } from 'react-router';\n\nexport function useRouteNormalizer(options: { autoReplace: boolean }) {\n const { pathname } = useLocation();\n const navigate = useNavigate();\n\n const normalizer = useCallback(\n (input: string) => input.replace(/\\/+\\//g, () => '/'),\n []\n );\n\n useLayoutEffect(() => {\n const result = normalizer(pathname);\n if (options.autoReplace && result !== pathname) {\n window.location.replace(result);\n }\n }, [options.autoReplace, pathname, navigate, normalizer]);\n\n return {\n pathname,\n normalizer,\n };\n}\n","import { useCallback, useLayoutEffect, useState } from 'react';\n\nexport function useScreen() {\n const [width, setWidth] = useState(document.body.clientWidth);\n const [height, setHeight] = useState(document.documentElement.clientHeight);\n\n const setScreen = useCallback(() => {\n setWidth(document.body.clientWidth);\n setHeight(document.documentElement.clientHeight);\n }, []);\n\n useLayoutEffect(() => {\n window.addEventListener('resize', setScreen, { passive: true });\n\n return () => {\n window.removeEventListener('resize', setScreen);\n };\n }, [setScreen]);\n\n return { width: width, height: height };\n}\n","import { useThree } from '@react-three/fiber';\nimport { useCallback, useState } from 'react';\nimport { OrthographicCamera, PerspectiveCamera } from 'three';\nimport { useScreenCallback } from './screenCallback';\n\nexport function useViewport(\n customCamera?: OrthographicCamera | PerspectiveCamera\n) {\n const { viewport, camera } = useThree();\n\n const [width, setWidth] = useState(viewport.getCurrentViewport().width);\n const [height, setHeight] = useState(viewport.getCurrentViewport().height);\n\n const viewportUpdate = useCallback(() => {\n const actualViewport = viewport.getCurrentViewport(customCamera ?? camera);\n setWidth(actualViewport.width);\n setHeight(actualViewport.height);\n }, [camera, customCamera, viewport]);\n useScreenCallback(viewportUpdate);\n\n return { width: width, height: height };\n}\n"],"mappings":"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","names":["useLayoutEffect","useCallback","useLayoutEffect","useLayoutEffect","useCallback","useLayoutEffect","useLayoutEffect","useCallback","useCallback","useCallback","useLayoutEffect","useLocation","useNavigate","useCallback","useLayoutEffect","useState","useCallback","useState","useState","useCallback"]}
@@ -0,0 +1,14 @@
1
+ import Lenis from 'lenis';
2
+ import { ReactNode } from 'react';
3
+
4
+ declare let lenisInstance: Lenis | undefined;
5
+ type BasicTunnelIn = ({ children }: {
6
+ children: ReactNode;
7
+ }) => null;
8
+ declare let Default3DTunnelIn: BasicTunnelIn | undefined;
9
+ declare const weaverSetup: {
10
+ setLenisInstance(instance: Lenis): void;
11
+ set3DTunnel(tunnelIn: BasicTunnelIn): void;
12
+ };
13
+
14
+ export { type BasicTunnelIn, Default3DTunnelIn, lenisInstance, weaverSetup };
@@ -0,0 +1,14 @@
1
+ import Lenis from 'lenis';
2
+ import { ReactNode } from 'react';
3
+
4
+ declare let lenisInstance: Lenis | undefined;
5
+ type BasicTunnelIn = ({ children }: {
6
+ children: ReactNode;
7
+ }) => null;
8
+ declare let Default3DTunnelIn: BasicTunnelIn | undefined;
9
+ declare const weaverSetup: {
10
+ setLenisInstance(instance: Lenis): void;
11
+ set3DTunnel(tunnelIn: BasicTunnelIn): void;
12
+ };
13
+
14
+ export { type BasicTunnelIn, Default3DTunnelIn, lenisInstance, weaverSetup };
package/dist/index.js ADDED
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ Default3DTunnelIn: () => Default3DTunnelIn,
24
+ lenisInstance: () => lenisInstance,
25
+ weaverSetup: () => weaverSetup
26
+ });
27
+ module.exports = __toCommonJS(src_exports);
28
+ var lenisInstance = void 0;
29
+ var Default3DTunnelIn = void 0;
30
+ var weaverSetup = {
31
+ setLenisInstance(instance) {
32
+ lenisInstance = instance;
33
+ },
34
+ set3DTunnel(tunnelIn) {
35
+ Default3DTunnelIn = tunnelIn;
36
+ }
37
+ };
38
+ // Annotate the CommonJS export names for ESM import in node:
39
+ 0 && (module.exports = {
40
+ Default3DTunnelIn,
41
+ lenisInstance,
42
+ weaverSetup
43
+ });
44
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import Lenis from 'lenis';\nimport { ReactNode } from 'react';\n\nexport let lenisInstance: Lenis | undefined = undefined;\n\nexport type BasicTunnelIn = ({ children }: { children: ReactNode }) => null;\nexport let Default3DTunnelIn: BasicTunnelIn | undefined = undefined;\n\nexport const weaverSetup = {\n setLenisInstance(instance: Lenis) {\n lenisInstance = instance;\n },\n set3DTunnel(tunnelIn: BasicTunnelIn) {\n Default3DTunnelIn = tunnelIn;\n },\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,IAAI,gBAAmC;AAGvC,IAAI,oBAA+C;AAEnD,IAAM,cAAc;AAAA,EACzB,iBAAiB,UAAiB;AAChC,oBAAgB;AAAA,EAClB;AAAA,EACA,YAAY,UAAyB;AACnC,wBAAoB;AAAA,EACtB;AACF;","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,17 @@
1
+ // src/index.ts
2
+ var lenisInstance = void 0;
3
+ var Default3DTunnelIn = void 0;
4
+ var weaverSetup = {
5
+ setLenisInstance(instance) {
6
+ lenisInstance = instance;
7
+ },
8
+ set3DTunnel(tunnelIn) {
9
+ Default3DTunnelIn = tunnelIn;
10
+ }
11
+ };
12
+ export {
13
+ Default3DTunnelIn,
14
+ lenisInstance,
15
+ weaverSetup
16
+ };
17
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import Lenis from 'lenis';\nimport { ReactNode } from 'react';\n\nexport let lenisInstance: Lenis | undefined = undefined;\n\nexport type BasicTunnelIn = ({ children }: { children: ReactNode }) => null;\nexport let Default3DTunnelIn: BasicTunnelIn | undefined = undefined;\n\nexport const weaverSetup = {\n setLenisInstance(instance: Lenis) {\n lenisInstance = instance;\n },\n set3DTunnel(tunnelIn: BasicTunnelIn) {\n Default3DTunnelIn = tunnelIn;\n },\n};\n"],"mappings":";AAGO,IAAI,gBAAmC;AAGvC,IAAI,oBAA+C;AAEnD,IAAM,cAAc;AAAA,EACzB,iBAAiB,UAAiB;AAChC,oBAAgB;AAAA,EAClB;AAAA,EACA,YAAY,UAAyB;AACnC,wBAAoB;AAAA,EACtB;AACF;","names":[]}
@@ -0,0 +1,88 @@
1
+ import React, { ReactNode } from 'react';
2
+
3
+ interface WeaverContextGetter {
4
+ /**
5
+ * Current active parent, **AFTER** Pipeline has finished rendering, so the `activeParent`
6
+ * will be delayed. Example: "/", "/works",...
7
+ */
8
+ activeParent: string;
9
+ /**
10
+ * Current active Pipeline. Example: "/", "/works",...
11
+ *
12
+ * This is **not based on URL**, it's based on which `Pipeline` has access to the the site.
13
+ */
14
+ activePipeline: string;
15
+ /**
16
+ * `DelayedOutlet` special variable, indicating if the route is current transitioning to a new route or not.
17
+ */
18
+ navigating: boolean;
19
+ /**
20
+ * When the page is rendered, it will turns this to true,
21
+ * any parent page navigation will causes this to goes false, set to false in `DelayedOulet`.
22
+ *
23
+ * It's set to `false` right after `navigating` is set to `true`. `true` statement will be handled by `Pipeline`.
24
+ */
25
+ pageRendered: boolean;
26
+ }
27
+
28
+ /**
29
+ * A core part of an in-house tool called `weaver`.
30
+ *
31
+ * Delaying the routing process from `react-router`, handles gracefully between `Pipeline`s
32
+ * while allowing any loading fallback component to listen and react with event changes.
33
+ */
34
+ declare function DelayedOutlet(props: {
35
+ delay: number;
36
+ }): ReactNode;
37
+
38
+ interface PipelineProps {
39
+ children?: ReactNode;
40
+ /**
41
+ * A state switch to notifies `Pipeline` that the content and elements of the page is ready to be displayed.
42
+ *
43
+ * Usually, you will need to preload some other external sources, or initialize 3D scene, this state
44
+ * make sure that the loading fallback doesn't mess up and show initializing stuff.
45
+ *
46
+ * Using `BakeScene`, you can ensure that the scene is loaded via its callback, you can then pass the state value that
47
+ * `BakeScene` changes to this variable to hide all the lags behind loading screen.
48
+ */
49
+ contentReady?: boolean;
50
+ /**
51
+ * Title for the page.
52
+ */
53
+ title: string;
54
+ /**
55
+ * By default, `Pipeline` will log the current phase to console.
56
+ */
57
+ debugName: string;
58
+ /**
59
+ * This is crucial for different `Pipeline`s to differentiate each other and avoiding conflict.
60
+ *
61
+ * Example for parent path: `/`, `/about`, `/projects`,...
62
+ */
63
+ parentPath: string;
64
+ /**
65
+ * By default, this value is `true`
66
+ *
67
+ * When navigating off of a previous `Pipeline`. It will stop lenis as a clean up.
68
+ *
69
+ * So when a new `Pipeline` takes in, it will enable lenis immediately when `contentReady` is switched to `true`.
70
+ *
71
+ * Set to `false` to gain manual control over when lenis will start. This does not affect to stop mechanism,
72
+ * you don't have to clean up yourself.
73
+ */
74
+ autoStartLenis?: boolean;
75
+ }
76
+ /**
77
+ * A core part of an in-house tool called `weaver`.
78
+ *
79
+ * `Pipeline`: Notifies & reflect changes to/from `LoadingFallback`
80
+ * and `DelayedOutlet` about its page loading status.
81
+ *
82
+ * All parent routes must have `Pipeline` in order to work and sync with `DelayedOutlet`.
83
+ */
84
+ declare function Pipeline(props: PipelineProps): React.JSX.Element;
85
+
86
+ declare const useWeaverState: (givenState: keyof WeaverContextGetter) => string | boolean;
87
+
88
+ export { DelayedOutlet, Pipeline, useWeaverState };
@@ -0,0 +1,88 @@
1
+ import React, { ReactNode } from 'react';
2
+
3
+ interface WeaverContextGetter {
4
+ /**
5
+ * Current active parent, **AFTER** Pipeline has finished rendering, so the `activeParent`
6
+ * will be delayed. Example: "/", "/works",...
7
+ */
8
+ activeParent: string;
9
+ /**
10
+ * Current active Pipeline. Example: "/", "/works",...
11
+ *
12
+ * This is **not based on URL**, it's based on which `Pipeline` has access to the the site.
13
+ */
14
+ activePipeline: string;
15
+ /**
16
+ * `DelayedOutlet` special variable, indicating if the route is current transitioning to a new route or not.
17
+ */
18
+ navigating: boolean;
19
+ /**
20
+ * When the page is rendered, it will turns this to true,
21
+ * any parent page navigation will causes this to goes false, set to false in `DelayedOulet`.
22
+ *
23
+ * It's set to `false` right after `navigating` is set to `true`. `true` statement will be handled by `Pipeline`.
24
+ */
25
+ pageRendered: boolean;
26
+ }
27
+
28
+ /**
29
+ * A core part of an in-house tool called `weaver`.
30
+ *
31
+ * Delaying the routing process from `react-router`, handles gracefully between `Pipeline`s
32
+ * while allowing any loading fallback component to listen and react with event changes.
33
+ */
34
+ declare function DelayedOutlet(props: {
35
+ delay: number;
36
+ }): ReactNode;
37
+
38
+ interface PipelineProps {
39
+ children?: ReactNode;
40
+ /**
41
+ * A state switch to notifies `Pipeline` that the content and elements of the page is ready to be displayed.
42
+ *
43
+ * Usually, you will need to preload some other external sources, or initialize 3D scene, this state
44
+ * make sure that the loading fallback doesn't mess up and show initializing stuff.
45
+ *
46
+ * Using `BakeScene`, you can ensure that the scene is loaded via its callback, you can then pass the state value that
47
+ * `BakeScene` changes to this variable to hide all the lags behind loading screen.
48
+ */
49
+ contentReady?: boolean;
50
+ /**
51
+ * Title for the page.
52
+ */
53
+ title: string;
54
+ /**
55
+ * By default, `Pipeline` will log the current phase to console.
56
+ */
57
+ debugName: string;
58
+ /**
59
+ * This is crucial for different `Pipeline`s to differentiate each other and avoiding conflict.
60
+ *
61
+ * Example for parent path: `/`, `/about`, `/projects`,...
62
+ */
63
+ parentPath: string;
64
+ /**
65
+ * By default, this value is `true`
66
+ *
67
+ * When navigating off of a previous `Pipeline`. It will stop lenis as a clean up.
68
+ *
69
+ * So when a new `Pipeline` takes in, it will enable lenis immediately when `contentReady` is switched to `true`.
70
+ *
71
+ * Set to `false` to gain manual control over when lenis will start. This does not affect to stop mechanism,
72
+ * you don't have to clean up yourself.
73
+ */
74
+ autoStartLenis?: boolean;
75
+ }
76
+ /**
77
+ * A core part of an in-house tool called `weaver`.
78
+ *
79
+ * `Pipeline`: Notifies & reflect changes to/from `LoadingFallback`
80
+ * and `DelayedOutlet` about its page loading status.
81
+ *
82
+ * All parent routes must have `Pipeline` in order to work and sync with `DelayedOutlet`.
83
+ */
84
+ declare function Pipeline(props: PipelineProps): React.JSX.Element;
85
+
86
+ declare const useWeaverState: (givenState: keyof WeaverContextGetter) => string | boolean;
87
+
88
+ export { DelayedOutlet, Pipeline, useWeaverState };