@walrosproject/ui 0.2.2 → 0.3.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/README.md +80 -0
- package/dist/index.d.ts +20 -3
- package/dist/index.js +156 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -151,3 +151,83 @@ El hook aplica por defecto la clase `dark` en `document.documentElement`,
|
|
|
151
151
|
guarda el valor en `localStorage` con la clave `walros-theme` y conserva los
|
|
152
152
|
tiempos oficiales de WalrOS Forum: cambio a los 220 ms y final a los 720 ms.
|
|
153
153
|
|
|
154
|
+
|
|
155
|
+
## Modos del glitch de tema
|
|
156
|
+
|
|
157
|
+
### `body`: comportamiento original de WalrOS Forum
|
|
158
|
+
|
|
159
|
+
Para páginas normales, sin escenas fijadas ni parallax complejo:
|
|
160
|
+
|
|
161
|
+
```tsx
|
|
162
|
+
const {
|
|
163
|
+
theme,
|
|
164
|
+
glitching,
|
|
165
|
+
toggleTheme,
|
|
166
|
+
} = useWalrosTheme({
|
|
167
|
+
mode: "body",
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
El paquete aplica el shake al `body`, mantiene los tiempos oficiales y cada
|
|
172
|
+
producto sigue diseñando su propio botón.
|
|
173
|
+
|
|
174
|
+
### `viewport`: páginas con parallax, sticky o GSAP ScrollTrigger
|
|
175
|
+
|
|
176
|
+
Usa una capa estable que cubra la escena visible. No apuntes a un elemento que
|
|
177
|
+
GSAP esté transformando directamente; utiliza preferiblemente un wrapper.
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
import { useRef } from "react";
|
|
181
|
+
import {
|
|
182
|
+
WalrosThemeGlitch,
|
|
183
|
+
useWalrosTheme,
|
|
184
|
+
} from "@walrosproject/ui";
|
|
185
|
+
|
|
186
|
+
export function Hero() {
|
|
187
|
+
const sceneRef = useRef<HTMLDivElement>(null);
|
|
188
|
+
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
189
|
+
|
|
190
|
+
const {
|
|
191
|
+
theme,
|
|
192
|
+
glitching,
|
|
193
|
+
toggleTheme,
|
|
194
|
+
} = useWalrosTheme({
|
|
195
|
+
mode: "viewport",
|
|
196
|
+
shakeTargets: [sceneRef, buttonRef],
|
|
197
|
+
onAfterUnlock: () => {
|
|
198
|
+
// Opcional: ScrollTrigger.update();
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
return (
|
|
203
|
+
<section className="relative overflow-hidden">
|
|
204
|
+
<div ref={sceneRef} className="absolute inset-0">
|
|
205
|
+
{/* escena visible */}
|
|
206
|
+
</div>
|
|
207
|
+
|
|
208
|
+
<button
|
|
209
|
+
ref={buttonRef}
|
|
210
|
+
type="button"
|
|
211
|
+
onClick={toggleTheme}
|
|
212
|
+
disabled={glitching}
|
|
213
|
+
>
|
|
214
|
+
Tema: {theme}
|
|
215
|
+
</button>
|
|
216
|
+
|
|
217
|
+
<WalrosThemeGlitch active={glitching} />
|
|
218
|
+
</section>
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
En este modo el paquete:
|
|
224
|
+
|
|
225
|
+
- guarda la posición actual del scroll;
|
|
226
|
+
- la mantiene estable con `requestAnimationFrame` y `window.scrollTo`;
|
|
227
|
+
- no usa `position: fixed` ni transforma el `body`;
|
|
228
|
+
- aplica el shake solamente a `shakeTargets`;
|
|
229
|
+
- restaura `overflow` y la posición al terminar;
|
|
230
|
+
- ejecuta `onAfterUnlock` para actualizar GSAP u otra librería.
|
|
231
|
+
|
|
232
|
+
Los tiempos predeterminados siguen siendo 220 ms para cambiar el tema y
|
|
233
|
+
720 ms para terminar la transición.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ImgHTMLAttributes, CSSProperties } from 'react';
|
|
2
|
+
import { ImgHTMLAttributes, CSSProperties, RefObject } from 'react';
|
|
3
3
|
|
|
4
4
|
type WalrosPortalTransitionProps = {
|
|
5
5
|
duration?: number;
|
|
@@ -34,6 +34,8 @@ type WalrosThemeGlitchProps = {
|
|
|
34
34
|
declare function WalrosThemeGlitch({ active, zIndex, className, style, }: WalrosThemeGlitchProps): react.JSX.Element;
|
|
35
35
|
|
|
36
36
|
type WalrosTheme = "light" | "dark";
|
|
37
|
+
type WalrosThemeMode = "body" | "viewport";
|
|
38
|
+
type WalrosThemeShakeTarget = HTMLElement | RefObject<HTMLElement | null> | null | undefined;
|
|
37
39
|
type UseWalrosThemeOptions = {
|
|
38
40
|
storageKey?: string;
|
|
39
41
|
defaultTheme?: WalrosTheme;
|
|
@@ -41,6 +43,21 @@ type UseWalrosThemeOptions = {
|
|
|
41
43
|
swapDelay?: number;
|
|
42
44
|
totalDuration?: number;
|
|
43
45
|
applyTheme?: (theme: WalrosTheme) => void;
|
|
46
|
+
/**
|
|
47
|
+
* `body` reproduce el comportamiento original de WalrOS Forum.
|
|
48
|
+
* `viewport` bloquea el scroll y sacude solo los elementos indicados,
|
|
49
|
+
* recomendado para parallax, sticky y GSAP ScrollTrigger.
|
|
50
|
+
*/
|
|
51
|
+
mode?: WalrosThemeMode;
|
|
52
|
+
/** Elementos que recibirán el shake cuando mode="viewport". */
|
|
53
|
+
shakeTargets?: readonly WalrosThemeShakeTarget[];
|
|
54
|
+
/**
|
|
55
|
+
* En modo viewport se activa por defecto. Mantiene scrollX/scrollY estables
|
|
56
|
+
* con requestAnimationFrame sin usar position: fixed en el body.
|
|
57
|
+
*/
|
|
58
|
+
lockScroll?: boolean;
|
|
59
|
+
/** Se ejecuta después de restaurar el scroll; útil para ScrollTrigger.update(). */
|
|
60
|
+
onAfterUnlock?: () => void;
|
|
44
61
|
};
|
|
45
62
|
type UseWalrosThemeResult = {
|
|
46
63
|
theme: WalrosTheme;
|
|
@@ -50,6 +67,6 @@ type UseWalrosThemeResult = {
|
|
|
50
67
|
toggleTheme: () => void;
|
|
51
68
|
setTheme: (theme: WalrosTheme) => void;
|
|
52
69
|
};
|
|
53
|
-
declare function useWalrosTheme({ storageKey, defaultTheme, useSystemPreference, swapDelay, totalDuration, applyTheme, }?: UseWalrosThemeOptions): UseWalrosThemeResult;
|
|
70
|
+
declare function useWalrosTheme({ storageKey, defaultTheme, useSystemPreference, swapDelay, totalDuration, applyTheme, mode, shakeTargets, lockScroll, onAfterUnlock, }?: UseWalrosThemeOptions): UseWalrosThemeResult;
|
|
54
71
|
|
|
55
|
-
export { type UseWalrosThemeOptions, type UseWalrosThemeResult, WalrosLogo, type WalrosLogoProps, WalrosPortalTransition, type WalrosPortalTransitionProps, type WalrosTheme, WalrosThemeGlitch, type WalrosThemeGlitchProps, WalrosWordmark, type WalrosWordmarkProps, useWalrosTheme, walrosLogoChromeUrl, walrosPortalSilhouetteUrl, walrosWordmarkDarkUrl, walrosWordmarkLightUrl };
|
|
72
|
+
export { type UseWalrosThemeOptions, type UseWalrosThemeResult, WalrosLogo, type WalrosLogoProps, WalrosPortalTransition, type WalrosPortalTransitionProps, type WalrosTheme, WalrosThemeGlitch, type WalrosThemeGlitchProps, type WalrosThemeMode, type WalrosThemeShakeTarget, WalrosWordmark, type WalrosWordmarkProps, useWalrosTheme, walrosLogoChromeUrl, walrosPortalSilhouetteUrl, walrosWordmarkDarkUrl, walrosWordmarkLightUrl };
|
package/dist/index.js
CHANGED
|
@@ -452,47 +452,64 @@ var GLITCH_STYLES = `
|
|
|
452
452
|
}
|
|
453
453
|
|
|
454
454
|
@keyframes walros-glitch-scan {
|
|
455
|
-
0% { transform: translate(0,0); opacity: 1; }
|
|
455
|
+
0% { transform: translate(0, 0); opacity: 1; }
|
|
456
456
|
15% { transform: translate(-10px, 6px); opacity: 0.9; }
|
|
457
457
|
30% { transform: translate(8px, -4px); opacity: 1; }
|
|
458
458
|
45% { transform: translate(-6px, 3px); opacity: 0.85; }
|
|
459
459
|
60% { transform: translate(4px, -8px); opacity: 1; }
|
|
460
460
|
80% { transform: translate(-3px, 4px); opacity: 0.6; }
|
|
461
|
-
100% { transform: translate(0,0); opacity: 0; }
|
|
461
|
+
100% { transform: translate(0, 0); opacity: 0; }
|
|
462
462
|
}
|
|
463
463
|
|
|
464
464
|
@keyframes walros-glitch-slice {
|
|
465
|
-
0% { clip-path: inset(0 0 0 0); transform: translate(0,0); opacity: 1; }
|
|
465
|
+
0% { clip-path: inset(0 0 0 0); transform: translate(0, 0); opacity: 1; }
|
|
466
466
|
15% { clip-path: inset(20% 0 55% 0); transform: translate(-12px, 0); }
|
|
467
467
|
30% { clip-path: inset(60% 0 12% 0); transform: translate(14px, 0); }
|
|
468
468
|
45% { clip-path: inset(35% 0 40% 0); transform: translate(-10px, 0); }
|
|
469
469
|
60% { clip-path: inset(10% 0 75% 0); transform: translate(8px, 0); }
|
|
470
470
|
75% { clip-path: inset(72% 0 5% 0); transform: translate(-6px, 0); }
|
|
471
471
|
90% { clip-path: inset(25% 0 60% 0); transform: translate(4px, 0); opacity: 0.7; }
|
|
472
|
-
100% { clip-path: inset(0 0 100% 0); transform: translate(0,0); opacity: 0; }
|
|
472
|
+
100% { clip-path: inset(0 0 100% 0); transform: translate(0, 0); opacity: 0; }
|
|
473
473
|
}
|
|
474
474
|
|
|
475
|
-
/*
|
|
476
|
-
* Sacudida de WalrOS Forum aplicada al body.
|
|
477
|
-
* El scale crea un peque\xF1o margen de seguridad para que los translate
|
|
478
|
-
* no descubran el fondo del elemento html en los bordes.
|
|
479
|
-
*/
|
|
480
475
|
.walros-theme-glitch-lock {
|
|
481
|
-
|
|
476
|
+
overscroll-behavior: none;
|
|
482
477
|
}
|
|
483
478
|
|
|
484
479
|
.walros-theme-glitch-page {
|
|
485
|
-
transform-origin: center center;
|
|
486
480
|
will-change: transform, filter;
|
|
487
|
-
animation: walros-glitch-page 500ms steps(8) both;
|
|
488
481
|
}
|
|
489
482
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
483
|
+
/* Comportamiento original de WalrOS Forum para p\xE1ginas normales. */
|
|
484
|
+
.walros-theme-glitch-page--body {
|
|
485
|
+
animation: walros-glitch-page-body 500ms steps(8) both;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
@keyframes walros-glitch-page-body {
|
|
489
|
+
0% { transform: translate(0, 0); filter: none; }
|
|
490
|
+
20% { transform: translate(-4px, 2px); filter: hue-rotate(40deg) contrast(1.15); }
|
|
491
|
+
40% { transform: translate(5px, -3px); filter: hue-rotate(-30deg) saturate(1.4); }
|
|
492
|
+
60% { transform: translate(-3px, 4px); filter: hue-rotate(90deg) contrast(1.1); }
|
|
493
|
+
80% { transform: translate(2px, -2px); filter: hue-rotate(-60deg) saturate(1.2); }
|
|
494
|
+
100% { transform: translate(0, 0); filter: none; }
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/*
|
|
498
|
+
* Modo seguro para parallax/sticky/ScrollTrigger.
|
|
499
|
+
* El shake se aplica a una capa estable del viewport, nunca al scroll real.
|
|
500
|
+
* El peque\xF1o overscan evita descubrir bordes al desplazar la escena.
|
|
501
|
+
*/
|
|
502
|
+
.walros-theme-glitch-page--viewport {
|
|
503
|
+
transform-origin: 50% var(--walros-glitch-origin-y, 50%);
|
|
504
|
+
animation: walros-glitch-page-viewport 500ms steps(8) both;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
@keyframes walros-glitch-page-viewport {
|
|
508
|
+
0% { transform: translate3d(0, 0, 0) scale(1.012); filter: none; }
|
|
509
|
+
20% { transform: translate3d(-4px, 2px, 0) scale(1.012); filter: hue-rotate(40deg) contrast(1.15); }
|
|
510
|
+
40% { transform: translate3d(5px, -3px, 0) scale(1.012); filter: hue-rotate(-30deg) saturate(1.4); }
|
|
511
|
+
60% { transform: translate3d(-3px, 4px, 0) scale(1.012); filter: hue-rotate(90deg) contrast(1.1); }
|
|
512
|
+
80% { transform: translate3d(2px, -2px, 0) scale(1.012); filter: hue-rotate(-60deg) saturate(1.2); }
|
|
496
513
|
100% { transform: translate3d(0, 0, 0) scale(1); filter: none; }
|
|
497
514
|
}
|
|
498
515
|
|
|
@@ -501,9 +518,12 @@ var GLITCH_STYLES = `
|
|
|
501
518
|
.walros-theme-glitch-root::after {
|
|
502
519
|
animation: walros-glitch-reduced 150ms ease-out forwards;
|
|
503
520
|
}
|
|
504
|
-
|
|
521
|
+
|
|
522
|
+
.walros-theme-glitch-page--body,
|
|
523
|
+
.walros-theme-glitch-page--viewport {
|
|
505
524
|
animation: none;
|
|
506
525
|
}
|
|
526
|
+
|
|
507
527
|
@keyframes walros-glitch-reduced {
|
|
508
528
|
from { opacity: 0.35; }
|
|
509
529
|
to { opacity: 0; }
|
|
@@ -528,6 +548,10 @@ function WalrosThemeGlitch({
|
|
|
528
548
|
) : null
|
|
529
549
|
] });
|
|
530
550
|
}
|
|
551
|
+
var GLITCH_BASE_CLASS = "walros-theme-glitch-page";
|
|
552
|
+
var GLITCH_BODY_CLASS = "walros-theme-glitch-page--body";
|
|
553
|
+
var GLITCH_VIEWPORT_CLASS = "walros-theme-glitch-page--viewport";
|
|
554
|
+
var GLITCH_LOCK_CLASS = "walros-theme-glitch-lock";
|
|
531
555
|
function defaultApplyTheme(theme) {
|
|
532
556
|
if (typeof document === "undefined") return;
|
|
533
557
|
const root = document.documentElement;
|
|
@@ -546,13 +570,26 @@ function readInitialTheme(storageKey, defaultTheme, useSystemPreference) {
|
|
|
546
570
|
}
|
|
547
571
|
return defaultTheme;
|
|
548
572
|
}
|
|
573
|
+
function resolveShakeTargets(targets) {
|
|
574
|
+
const resolved = /* @__PURE__ */ new Set();
|
|
575
|
+
for (const target of targets) {
|
|
576
|
+
if (!target) continue;
|
|
577
|
+
const element = typeof target === "object" && "current" in target ? target.current : target;
|
|
578
|
+
if (element) resolved.add(element);
|
|
579
|
+
}
|
|
580
|
+
return [...resolved];
|
|
581
|
+
}
|
|
549
582
|
function useWalrosTheme({
|
|
550
583
|
storageKey = "walros-theme",
|
|
551
584
|
defaultTheme = "light",
|
|
552
585
|
useSystemPreference = false,
|
|
553
586
|
swapDelay = 220,
|
|
554
587
|
totalDuration = 720,
|
|
555
|
-
applyTheme = defaultApplyTheme
|
|
588
|
+
applyTheme = defaultApplyTheme,
|
|
589
|
+
mode = "body",
|
|
590
|
+
shakeTargets = [],
|
|
591
|
+
lockScroll,
|
|
592
|
+
onAfterUnlock
|
|
556
593
|
} = {}) {
|
|
557
594
|
const [theme, setThemeState] = useState(
|
|
558
595
|
() => readInitialTheme(storageKey, defaultTheme, useSystemPreference)
|
|
@@ -564,8 +601,18 @@ function useWalrosTheme({
|
|
|
564
601
|
const swapTimerRef = useRef(null);
|
|
565
602
|
const cleanupTimerRef = useRef(null);
|
|
566
603
|
const applyThemeRef = useRef(applyTheme);
|
|
604
|
+
const modeRef = useRef(mode);
|
|
605
|
+
const shakeTargetsRef = useRef(shakeTargets);
|
|
606
|
+
const lockScrollRef = useRef(lockScroll);
|
|
607
|
+
const onAfterUnlockRef = useRef(onAfterUnlock);
|
|
608
|
+
const activeTargetsRef = useRef([]);
|
|
609
|
+
const viewportLockRef = useRef(null);
|
|
567
610
|
themeRef.current = theme;
|
|
568
611
|
applyThemeRef.current = applyTheme;
|
|
612
|
+
modeRef.current = mode;
|
|
613
|
+
shakeTargetsRef.current = shakeTargets;
|
|
614
|
+
lockScrollRef.current = lockScroll;
|
|
615
|
+
onAfterUnlockRef.current = onAfterUnlock;
|
|
569
616
|
const persistTheme = useCallback(
|
|
570
617
|
(nextTheme) => {
|
|
571
618
|
applyThemeRef.current(nextTheme);
|
|
@@ -599,14 +646,72 @@ function useWalrosTheme({
|
|
|
599
646
|
cleanupTimerRef.current = null;
|
|
600
647
|
}
|
|
601
648
|
}, []);
|
|
602
|
-
const
|
|
603
|
-
if (typeof document
|
|
604
|
-
|
|
605
|
-
document.documentElement.classList.remove("walros-theme-glitch-lock");
|
|
649
|
+
const lockViewport = useCallback(() => {
|
|
650
|
+
if (typeof window === "undefined" || typeof document === "undefined" || viewportLockRef.current) {
|
|
651
|
+
return;
|
|
606
652
|
}
|
|
653
|
+
const body = document.body;
|
|
654
|
+
const html = document.documentElement;
|
|
655
|
+
const lockState = {
|
|
656
|
+
scrollX: window.scrollX,
|
|
657
|
+
scrollY: window.scrollY,
|
|
658
|
+
rafId: 0,
|
|
659
|
+
active: true,
|
|
660
|
+
bodyOverflow: body.style.overflow,
|
|
661
|
+
htmlOverflow: html.style.overflow,
|
|
662
|
+
htmlOverscrollBehavior: html.style.overscrollBehavior
|
|
663
|
+
};
|
|
664
|
+
viewportLockRef.current = lockState;
|
|
665
|
+
const keepScrollStable = () => {
|
|
666
|
+
if (!lockState.active) return;
|
|
667
|
+
window.scrollTo(lockState.scrollX, lockState.scrollY);
|
|
668
|
+
lockState.rafId = window.requestAnimationFrame(keepScrollStable);
|
|
669
|
+
};
|
|
670
|
+
html.classList.add(GLITCH_LOCK_CLASS);
|
|
671
|
+
html.style.overflow = "hidden";
|
|
672
|
+
html.style.overscrollBehavior = "none";
|
|
673
|
+
body.style.overflow = "hidden";
|
|
674
|
+
lockState.rafId = window.requestAnimationFrame(keepScrollStable);
|
|
675
|
+
}, []);
|
|
676
|
+
const unlockViewport = useCallback((runCallback) => {
|
|
677
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
const lockState = viewportLockRef.current;
|
|
681
|
+
if (!lockState) return;
|
|
682
|
+
lockState.active = false;
|
|
683
|
+
window.cancelAnimationFrame(lockState.rafId);
|
|
684
|
+
const body = document.body;
|
|
685
|
+
const html = document.documentElement;
|
|
686
|
+
body.style.overflow = lockState.bodyOverflow;
|
|
687
|
+
html.style.overflow = lockState.htmlOverflow;
|
|
688
|
+
html.style.overscrollBehavior = lockState.htmlOverscrollBehavior;
|
|
689
|
+
html.classList.remove(GLITCH_LOCK_CLASS);
|
|
690
|
+
viewportLockRef.current = null;
|
|
691
|
+
window.scrollTo(lockState.scrollX, lockState.scrollY);
|
|
692
|
+
if (runCallback) {
|
|
693
|
+
window.requestAnimationFrame(() => {
|
|
694
|
+
onAfterUnlockRef.current?.();
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
}, []);
|
|
698
|
+
const removeShakeClasses = useCallback(() => {
|
|
699
|
+
for (const target of activeTargetsRef.current) {
|
|
700
|
+
target.classList.remove(
|
|
701
|
+
GLITCH_BASE_CLASS,
|
|
702
|
+
GLITCH_BODY_CLASS,
|
|
703
|
+
GLITCH_VIEWPORT_CLASS
|
|
704
|
+
);
|
|
705
|
+
target.style.removeProperty("--walros-glitch-origin-y");
|
|
706
|
+
}
|
|
707
|
+
activeTargetsRef.current = [];
|
|
708
|
+
}, []);
|
|
709
|
+
const finishGlitch = useCallback(() => {
|
|
710
|
+
removeShakeClasses();
|
|
711
|
+
unlockViewport(true);
|
|
607
712
|
glitchingRef.current = false;
|
|
608
713
|
setGlitching(false);
|
|
609
|
-
}, []);
|
|
714
|
+
}, [removeShakeClasses, unlockViewport]);
|
|
610
715
|
const setTheme = useCallback(
|
|
611
716
|
(nextTheme) => {
|
|
612
717
|
if (glitchingRef.current) return;
|
|
@@ -615,33 +720,48 @@ function useWalrosTheme({
|
|
|
615
720
|
[persistTheme]
|
|
616
721
|
);
|
|
617
722
|
const toggleTheme = useCallback(() => {
|
|
618
|
-
if (typeof window === "undefined" || glitchingRef.current)
|
|
723
|
+
if (typeof window === "undefined" || typeof document === "undefined" || glitchingRef.current) {
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
const currentMode = modeRef.current;
|
|
727
|
+
const shouldLockScroll = lockScrollRef.current ?? currentMode === "viewport";
|
|
728
|
+
if (currentMode === "viewport" && shouldLockScroll) {
|
|
729
|
+
lockViewport();
|
|
730
|
+
}
|
|
731
|
+
const targets = currentMode === "body" ? [document.body] : resolveShakeTargets(shakeTargetsRef.current);
|
|
732
|
+
const modeClass = currentMode === "body" ? GLITCH_BODY_CLASS : GLITCH_VIEWPORT_CLASS;
|
|
733
|
+
for (const target of targets) {
|
|
734
|
+
target.style.setProperty(
|
|
735
|
+
"--walros-glitch-origin-y",
|
|
736
|
+
currentMode === "body" ? `${window.scrollY + window.innerHeight / 2}px` : "50%"
|
|
737
|
+
);
|
|
738
|
+
target.classList.add(GLITCH_BASE_CLASS, modeClass);
|
|
739
|
+
}
|
|
740
|
+
activeTargetsRef.current = targets;
|
|
619
741
|
glitchingRef.current = true;
|
|
620
742
|
setGlitching(true);
|
|
621
|
-
document.documentElement.classList.add("walros-theme-glitch-lock");
|
|
622
|
-
document.body.classList.add("walros-theme-glitch-page");
|
|
623
743
|
const reducedMotion = window.matchMedia?.(
|
|
624
744
|
"(prefers-reduced-motion: reduce)"
|
|
625
745
|
).matches;
|
|
626
746
|
const nextTheme = themeRef.current === "dark" ? "light" : "dark";
|
|
747
|
+
const effectiveSwapDelay = reducedMotion ? 75 : Math.max(0, swapDelay);
|
|
748
|
+
const effectiveDuration = reducedMotion ? 150 : Math.max(effectiveSwapDelay, totalDuration);
|
|
627
749
|
swapTimerRef.current = window.setTimeout(() => {
|
|
628
750
|
persistTheme(nextTheme);
|
|
629
751
|
swapTimerRef.current = null;
|
|
630
|
-
},
|
|
752
|
+
}, effectiveSwapDelay);
|
|
631
753
|
cleanupTimerRef.current = window.setTimeout(() => {
|
|
632
754
|
cleanupTimerRef.current = null;
|
|
633
755
|
finishGlitch();
|
|
634
|
-
},
|
|
635
|
-
}, [finishGlitch, persistTheme, swapDelay, totalDuration]);
|
|
756
|
+
}, effectiveDuration);
|
|
757
|
+
}, [finishGlitch, lockViewport, persistTheme, swapDelay, totalDuration]);
|
|
636
758
|
useEffect(() => {
|
|
637
759
|
return () => {
|
|
638
760
|
clearTimers();
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
document.documentElement.classList.remove("walros-theme-glitch-lock");
|
|
642
|
-
}
|
|
761
|
+
removeShakeClasses();
|
|
762
|
+
unlockViewport(false);
|
|
643
763
|
};
|
|
644
|
-
}, [clearTimers]);
|
|
764
|
+
}, [clearTimers, removeShakeClasses, unlockViewport]);
|
|
645
765
|
return {
|
|
646
766
|
theme,
|
|
647
767
|
isDark: theme === "dark",
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/assets.ts","../src/components/WalrosPortalTransition.tsx","../src/components/WalrosLogo.tsx","../src/components/WalrosWordmark.tsx","../src/components/WalrosThemeGlitch.tsx","../src/hooks/useWalrosTheme.ts"],"names":["initialPixels","initialScale","jsx","jsxs","useState","useRef","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["export const walrosPortalSilhouetteUrl = new URL(\n \"./assets/walros-portal-silhouette.svg\",\n import.meta.url,\n).href;\n\nexport const walrosLogoChromeUrl = new URL(\n \"./assets/walros-logo-chrome.png\",\n import.meta.url,\n).href;\n\nexport const walrosWordmarkLightUrl = new URL(\n \"./assets/walros-wordmark-light.png\",\n import.meta.url,\n).href;\n\nexport const walrosWordmarkDarkUrl = new URL(\n \"./assets/walros-wordmark-dark.png\",\n import.meta.url,\n).href;\n","import {\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { gsap } from \"gsap\";\nimport { walrosPortalSilhouetteUrl } from \"../assets\";\n\nexport type WalrosPortalTransitionProps = {\n duration?: number;\n onComplete?: () => void;\n backgroundColor?: string;\n enabled?: boolean;\n storageMode?: \"always\" | \"session\" | \"once\";\n storageKey?: string;\n zIndex?: number;\n};\n\nconst SILHOUETTE_VIEWBOX = 1254;\nconst FOCUS_X = 626;\nconst FOCUS_Y = 333;\nconst PORTAL_RADIUS = 190;\n\nfunction getStorage(mode: \"session\" | \"once\"): Storage | null {\n if (typeof window === \"undefined\") return null;\n\n try {\n const storage =\n mode === \"session\"\n ? window.sessionStorage\n : window.localStorage;\n const testKey = \"__walros_portal_test__\";\n storage.setItem(testKey, \"1\");\n storage.removeItem(testKey);\n return storage;\n } catch {\n return null;\n }\n}\n\nfunction shouldRunTransition(\n enabled: boolean,\n storageMode: \"always\" | \"session\" | \"once\",\n storageKey: string,\n): boolean {\n if (!enabled) return false;\n if (storageMode === \"always\") return true;\n if (typeof window === \"undefined\") return false;\n\n const storage = getStorage(storageMode);\n if (!storage) return true;\n\n try {\n return storage.getItem(storageKey) == null;\n } catch {\n return true;\n }\n}\n\nexport function WalrosPortalTransition({\n duration = 750,\n onComplete,\n backgroundColor = \"#02050b\",\n enabled = true,\n storageMode = \"always\",\n storageKey = \"walros-portal-seen\",\n zIndex = 9999,\n}: WalrosPortalTransitionProps) {\n const [shouldRun] = useState(() =>\n shouldRunTransition(enabled, storageMode, storageKey),\n );\n const [visible, setVisible] = useState(shouldRun);\n const [size, setSize] = useState({ w: 0, h: 0 });\n\n const overlayRef = useRef<HTMLDivElement | null>(null);\n const maskScaleRef = useRef<SVGGElement | null>(null);\n const glowScaleRef = useRef<SVGGElement | null>(null);\n const completedRef = useRef(false);\n const startedRef = useRef(false);\n const rafRef = useRef<number | null>(null);\n const timelineRef = useRef<gsap.core.Timeline | null>(null);\n const previousOverflowRef = useRef(\"\");\n\n const uid = useId().replace(/[:]/g, \"_\");\n const maskId = `walros-portal-mask-${uid}`;\n const glowFilterId = `walros-portal-glow-${uid}`;\n\n useEffect(() => {\n if (!visible) return;\n\n const element = overlayRef.current;\n if (!element) return;\n\n const measure = () => {\n const rect = element.getBoundingClientRect();\n setSize((previous) =>\n previous.w === rect.width && previous.h === rect.height\n ? previous\n : { w: rect.width, h: rect.height },\n );\n };\n\n measure();\n\n const observer =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(measure)\n : null;\n\n observer?.observe(element);\n window.addEventListener(\"resize\", measure);\n\n return () => {\n observer?.disconnect();\n window.removeEventListener(\"resize\", measure);\n };\n }, [visible]);\n\n useLayoutEffect(() => {\n if (!enabled) {\n setVisible(false);\n return;\n }\n\n if (!visible) return;\n if (completedRef.current || startedRef.current) return;\n if (size.w <= 0 || size.h <= 0) return;\n\n const overlay = overlayRef.current;\n const maskScale = maskScaleRef.current;\n const glowScale = glowScaleRef.current;\n\n if (!overlay || !maskScale) return;\n\n startedRef.current = true;\n previousOverflowRef.current = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n\n const finish = () => {\n if (completedRef.current) return;\n\n completedRef.current = true;\n document.body.style.overflow = previousOverflowRef.current;\n\n if (storageMode !== \"always\") {\n const storage = getStorage(storageMode);\n try {\n storage?.setItem(storageKey, \"1\");\n } catch {\n // El modo privado o una cuota llena no deben romper la web.\n }\n }\n\n setVisible(false);\n onComplete?.();\n };\n\n const reducedMotion = window.matchMedia(\n \"(prefers-reduced-motion: reduce)\",\n ).matches;\n\n if (reducedMotion) {\n const timeline = gsap.timeline({ onComplete: finish });\n timelineRef.current = timeline;\n timeline.to(overlay, {\n opacity: 0,\n duration: 0.15,\n ease: \"power1.out\",\n });\n return;\n }\n\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = null;\n\n const halfDiagonal =\n Math.sqrt(size.w * size.w + size.h * size.h) / 2;\n const initialPixels = Math.min(\n 180,\n Math.max(120, size.w * 0.12),\n );\n const initialScale =\n initialPixels / SILHOUETTE_VIEWBOX;\n const finalScale =\n ((halfDiagonal + 80) / PORTAL_RADIUS) * 1.15;\n\n gsap.set(maskScale, {\n svgOrigin: \"0 0\",\n scale: initialScale,\n });\n\n if (glowScale) {\n gsap.set(glowScale, {\n svgOrigin: \"0 0\",\n scale: initialScale,\n opacity: 0.85,\n });\n }\n\n gsap.set(overlay, { opacity: 1 });\n\n const totalSeconds = duration / 1000;\n const timeline = gsap.timeline({ onComplete: finish });\n timelineRef.current = timeline;\n\n timeline.to(\n maskScale,\n {\n scale: initialScale * 1.4,\n duration: totalSeconds * 0.15,\n ease: \"power2.out\",\n },\n 0,\n );\n\n if (glowScale) {\n timeline.to(\n glowScale,\n {\n scale: initialScale * 1.4,\n opacity: 1,\n duration: totalSeconds * 0.15,\n ease: \"power2.out\",\n },\n 0,\n );\n }\n\n timeline.to(\n maskScale,\n {\n scale: finalScale,\n duration: totalSeconds * 0.85,\n ease: \"power2.in\",\n },\n totalSeconds * 0.15,\n );\n\n if (glowScale) {\n timeline.to(\n glowScale,\n {\n scale: finalScale * 0.9,\n opacity: 0,\n duration: totalSeconds * 0.4,\n ease: \"power2.in\",\n },\n totalSeconds * 0.45,\n );\n }\n\n timeline.to(\n overlay,\n {\n opacity: 0,\n duration: totalSeconds * 0.1,\n ease: \"power2.out\",\n },\n totalSeconds * 0.9,\n );\n });\n }, [\n duration,\n enabled,\n onComplete,\n size,\n storageKey,\n storageMode,\n visible,\n ]);\n\n useEffect(() => {\n return () => {\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current);\n }\n\n timelineRef.current?.kill();\n\n if (startedRef.current && !completedRef.current) {\n document.body.style.overflow =\n previousOverflowRef.current;\n }\n };\n }, []);\n\n if (!shouldRun || !visible) return null;\n\n const { w, h } = size;\n const ready = w > 0 && h > 0;\n\n const viewportCenterX = w / 2;\n const viewportCenterY = h / 2;\n const initialPixels = Math.min(\n 180,\n Math.max(120, w * 0.12),\n );\n const initialScale =\n initialPixels / SILHOUETTE_VIEWBOX;\n const visualCenter = SILHOUETTE_VIEWBOX / 2;\n const initialOffsetX =\n (visualCenter - FOCUS_X) * initialScale;\n const initialOffsetY =\n (visualCenter - FOCUS_Y) * initialScale;\n const portalCenterX =\n viewportCenterX - initialOffsetX;\n const portalCenterY =\n viewportCenterY - initialOffsetY;\n\n return (\n <div\n ref={overlayRef}\n aria-hidden=\"true\"\n style={{\n position: \"fixed\",\n inset: 0,\n width: \"100vw\",\n height: \"100dvh\",\n zIndex,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n backgroundColor: ready\n ? \"transparent\"\n : backgroundColor,\n }}\n >\n {ready && (\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox={`0 0 ${w} ${h}`}\n preserveAspectRatio=\"none\"\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"block\",\n }}\n >\n <defs>\n <filter\n id={glowFilterId}\n x=\"-50%\"\n y=\"-50%\"\n width=\"200%\"\n height=\"200%\"\n >\n <feGaussianBlur stdDeviation=\"28\" />\n </filter>\n\n <mask\n id={maskId}\n maskUnits=\"userSpaceOnUse\"\n x=\"0\"\n y=\"0\"\n width={w}\n height={h}\n >\n <rect\n x=\"0\"\n y=\"0\"\n width={w}\n height={h}\n fill=\"white\"\n />\n\n <g\n transform={`translate(${portalCenterX} ${portalCenterY})`}\n >\n <g\n ref={maskScaleRef}\n transform={`scale(${initialScale})`}\n >\n <image\n href={walrosPortalSilhouetteUrl}\n x={-FOCUS_X}\n y={-FOCUS_Y}\n width={SILHOUETTE_VIEWBOX}\n height={SILHOUETTE_VIEWBOX}\n />\n </g>\n </g>\n </mask>\n </defs>\n\n <rect\n x=\"0\"\n y=\"0\"\n width={w}\n height={h}\n fill={backgroundColor}\n mask={`url(#${maskId})`}\n />\n\n <g\n transform={`translate(${portalCenterX} ${portalCenterY})`}\n style={{\n mixBlendMode: \"screen\",\n pointerEvents: \"none\",\n }}\n >\n <g\n ref={glowScaleRef}\n transform={`scale(${initialScale})`}\n opacity=\"0.85\"\n >\n <g filter={`url(#${glowFilterId})`}>\n <image\n href={walrosPortalSilhouetteUrl}\n x={-FOCUS_X}\n y={-FOCUS_Y}\n width={SILHOUETTE_VIEWBOX}\n height={SILHOUETTE_VIEWBOX}\n style={{\n filter:\n \"brightness(0) saturate(100%) invert(58%) sepia(94%) saturate(1352%) hue-rotate(182deg)\",\n opacity: 0.6,\n }}\n />\n </g>\n </g>\n </g>\n </svg>\n )}\n </div>\n );\n}\n\nexport default WalrosPortalTransition;\n","import type { ImgHTMLAttributes } from \"react\";\nimport { walrosLogoChromeUrl } from \"../assets\";\n\nexport type WalrosLogoProps = Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n \"src\"\n>;\n\nexport function WalrosLogo({\n alt = \"WalrOS\",\n draggable = false,\n ...props\n}: WalrosLogoProps) {\n return (\n <img\n src={walrosLogoChromeUrl}\n alt={alt}\n draggable={draggable}\n {...props}\n />\n );\n}\n\nexport default WalrosLogo;\n","import type { ImgHTMLAttributes } from \"react\";\nimport {\n walrosWordmarkDarkUrl,\n walrosWordmarkLightUrl,\n} from \"../assets\";\n\nexport type WalrosWordmarkProps = Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n \"src\"\n> & {\n variant?: \"light\" | \"dark\";\n};\n\nexport function WalrosWordmark({\n variant = \"light\",\n alt = \"WalrOS\",\n draggable = false,\n ...props\n}: WalrosWordmarkProps) {\n const src =\n variant === \"dark\"\n ? walrosWordmarkDarkUrl\n : walrosWordmarkLightUrl;\n\n return (\n <img\n src={src}\n alt={alt}\n draggable={draggable}\n {...props}\n />\n );\n}\n\nexport default WalrosWordmark;\n","import type { CSSProperties } from \"react\";\n\nexport type WalrosThemeGlitchProps = {\n active: boolean;\n zIndex?: number;\n className?: string;\n style?: CSSProperties;\n};\n\nconst GLITCH_STYLES = `\n.walros-theme-glitch-root {\n position: fixed;\n inset: 0;\n pointer-events: none;\n overflow: hidden;\n}\n.walros-theme-glitch-root::before,\n.walros-theme-glitch-root::after {\n content: \"\";\n position: absolute;\n inset: 0;\n mix-blend-mode: screen;\n}\n.walros-theme-glitch-root::before {\n background:\n repeating-linear-gradient(\n 0deg,\n transparent 0 2px,\n rgba(59, 130, 246, 0.35) 2px 3px,\n transparent 3px 5px,\n rgba(236, 72, 153, 0.28) 5px 6px\n );\n animation: walros-glitch-scan 700ms steps(14) forwards;\n}\n.walros-theme-glitch-root::after {\n background:\n linear-gradient(\n 90deg,\n rgba(6, 182, 212, 0.5),\n transparent 40%,\n transparent 60%,\n rgba(236, 72, 153, 0.5)\n );\n animation: walros-glitch-slice 700ms steps(10) forwards;\n}\n\n@keyframes walros-glitch-scan {\n 0% { transform: translate(0,0); opacity: 1; }\n 15% { transform: translate(-10px, 6px); opacity: 0.9; }\n 30% { transform: translate(8px, -4px); opacity: 1; }\n 45% { transform: translate(-6px, 3px); opacity: 0.85; }\n 60% { transform: translate(4px, -8px); opacity: 1; }\n 80% { transform: translate(-3px, 4px); opacity: 0.6; }\n 100% { transform: translate(0,0); opacity: 0; }\n}\n\n@keyframes walros-glitch-slice {\n 0% { clip-path: inset(0 0 0 0); transform: translate(0,0); opacity: 1; }\n 15% { clip-path: inset(20% 0 55% 0); transform: translate(-12px, 0); }\n 30% { clip-path: inset(60% 0 12% 0); transform: translate(14px, 0); }\n 45% { clip-path: inset(35% 0 40% 0); transform: translate(-10px, 0); }\n 60% { clip-path: inset(10% 0 75% 0); transform: translate(8px, 0); }\n 75% { clip-path: inset(72% 0 5% 0); transform: translate(-6px, 0); }\n 90% { clip-path: inset(25% 0 60% 0); transform: translate(4px, 0); opacity: 0.7; }\n 100% { clip-path: inset(0 0 100% 0); transform: translate(0,0); opacity: 0; }\n}\n\n/*\n * Sacudida de WalrOS Forum aplicada al body.\n * El scale crea un pequeño margen de seguridad para que los translate\n * no descubran el fondo del elemento html en los bordes.\n */\n.walros-theme-glitch-lock {\n overflow: hidden !important;\n}\n\n.walros-theme-glitch-page {\n transform-origin: center center;\n will-change: transform, filter;\n animation: walros-glitch-page 500ms steps(8) both;\n}\n\n@keyframes walros-glitch-page {\n 0% { transform: translate3d(0, 0, 0) scale(1.035); filter: none; }\n 20% { transform: translate3d(-4px, 2px, 0) scale(1.035); filter: hue-rotate(40deg) contrast(1.15); }\n 40% { transform: translate3d(5px, -3px, 0) scale(1.035); filter: hue-rotate(-30deg) saturate(1.4); }\n 60% { transform: translate3d(-3px, 4px, 0) scale(1.035); filter: hue-rotate(90deg) contrast(1.1); }\n 80% { transform: translate3d(2px, -2px, 0) scale(1.035); filter: hue-rotate(-60deg) saturate(1.2); }\n 100% { transform: translate3d(0, 0, 0) scale(1); filter: none; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .walros-theme-glitch-root::before,\n .walros-theme-glitch-root::after {\n animation: walros-glitch-reduced 150ms ease-out forwards;\n }\n .walros-theme-glitch-page {\n animation: none;\n }\n @keyframes walros-glitch-reduced {\n from { opacity: 0.35; }\n to { opacity: 0; }\n }\n}\n`;\n\nexport function WalrosThemeGlitch({\n active,\n zIndex = 9998,\n className,\n style,\n}: WalrosThemeGlitchProps) {\n return (\n <>\n <style>{GLITCH_STYLES}</style>\n {active ? (\n <div\n className={[\"walros-theme-glitch-root\", className]\n .filter(Boolean)\n .join(\" \")}\n style={{ zIndex, ...style }}\n aria-hidden=\"true\"\n />\n ) : null}\n </>\n );\n}\n\nexport default WalrosThemeGlitch;\n","import {\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\n\nexport type WalrosTheme = \"light\" | \"dark\";\n\nexport type UseWalrosThemeOptions = {\n storageKey?: string;\n defaultTheme?: WalrosTheme;\n useSystemPreference?: boolean;\n swapDelay?: number;\n totalDuration?: number;\n applyTheme?: (theme: WalrosTheme) => void;\n};\n\nexport type UseWalrosThemeResult = {\n theme: WalrosTheme;\n isDark: boolean;\n mounted: boolean;\n glitching: boolean;\n toggleTheme: () => void;\n setTheme: (theme: WalrosTheme) => void;\n};\n\nfunction defaultApplyTheme(theme: WalrosTheme) {\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n root.classList.toggle(\"dark\", theme === \"dark\");\n root.style.colorScheme = theme;\n}\n\nfunction readInitialTheme(\n storageKey: string,\n defaultTheme: WalrosTheme,\n useSystemPreference: boolean,\n): WalrosTheme {\n if (typeof window === \"undefined\") return defaultTheme;\n\n try {\n const stored = window.localStorage.getItem(storageKey);\n if (stored === \"light\" || stored === \"dark\") return stored;\n } catch {\n // localStorage puede estar bloqueado en modo privado.\n }\n\n if (\n useSystemPreference &&\n window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches\n ) {\n return \"dark\";\n }\n\n return defaultTheme;\n}\n\nexport function useWalrosTheme({\n storageKey = \"walros-theme\",\n defaultTheme = \"light\",\n useSystemPreference = false,\n swapDelay = 220,\n totalDuration = 720,\n applyTheme = defaultApplyTheme,\n}: UseWalrosThemeOptions = {}): UseWalrosThemeResult {\n const [theme, setThemeState] = useState<WalrosTheme>(() =>\n readInitialTheme(storageKey, defaultTheme, useSystemPreference),\n );\n const [mounted, setMounted] = useState(false);\n const [glitching, setGlitching] = useState(false);\n\n const themeRef = useRef(theme);\n const glitchingRef = useRef(false);\n const swapTimerRef = useRef<number | null>(null);\n const cleanupTimerRef = useRef<number | null>(null);\n const applyThemeRef = useRef(applyTheme);\n\n themeRef.current = theme;\n applyThemeRef.current = applyTheme;\n\n const persistTheme = useCallback(\n (nextTheme: WalrosTheme) => {\n applyThemeRef.current(nextTheme);\n setThemeState(nextTheme);\n themeRef.current = nextTheme;\n\n try {\n window.localStorage.setItem(storageKey, nextTheme);\n } catch {\n // El cambio debe funcionar aunque localStorage falle.\n }\n },\n [storageKey],\n );\n\n useEffect(() => {\n const initialTheme = readInitialTheme(\n storageKey,\n defaultTheme,\n useSystemPreference,\n );\n themeRef.current = initialTheme;\n setThemeState(initialTheme);\n applyThemeRef.current(initialTheme);\n setMounted(true);\n }, [defaultTheme, storageKey, useSystemPreference]);\n\n const clearTimers = useCallback(() => {\n if (swapTimerRef.current !== null) {\n window.clearTimeout(swapTimerRef.current);\n swapTimerRef.current = null;\n }\n if (cleanupTimerRef.current !== null) {\n window.clearTimeout(cleanupTimerRef.current);\n cleanupTimerRef.current = null;\n }\n }, []);\n\n const finishGlitch = useCallback(() => {\n if (typeof document !== \"undefined\") {\n document.body.classList.remove(\"walros-theme-glitch-page\");\n document.documentElement.classList.remove(\"walros-theme-glitch-lock\");\n }\n glitchingRef.current = false;\n setGlitching(false);\n }, []);\n\n const setTheme = useCallback(\n (nextTheme: WalrosTheme) => {\n if (glitchingRef.current) return;\n persistTheme(nextTheme);\n },\n [persistTheme],\n );\n\n const toggleTheme = useCallback(() => {\n if (typeof window === \"undefined\" || glitchingRef.current) return;\n\n glitchingRef.current = true;\n setGlitching(true);\n\n // Comportamiento exacto de WalrOS Forum:\n // la clase se aplica al body para sacudir el contenido completo.\n document.documentElement.classList.add(\"walros-theme-glitch-lock\");\n document.body.classList.add(\"walros-theme-glitch-page\");\n\n const reducedMotion = window.matchMedia?.(\n \"(prefers-reduced-motion: reduce)\",\n ).matches;\n\n const nextTheme: WalrosTheme =\n themeRef.current === \"dark\" ? \"light\" : \"dark\";\n\n swapTimerRef.current = window.setTimeout(() => {\n persistTheme(nextTheme);\n swapTimerRef.current = null;\n }, reducedMotion ? 75 : swapDelay);\n\n cleanupTimerRef.current = window.setTimeout(() => {\n cleanupTimerRef.current = null;\n finishGlitch();\n }, reducedMotion ? 150 : totalDuration);\n }, [finishGlitch, persistTheme, swapDelay, totalDuration]);\n\n useEffect(() => {\n return () => {\n clearTimers();\n if (typeof document !== \"undefined\") {\n document.body.classList.remove(\"walros-theme-glitch-page\");\n document.documentElement.classList.remove(\"walros-theme-glitch-lock\");\n }\n };\n }, [clearTimers]);\n\n return {\n theme,\n isDark: theme === \"dark\",\n mounted,\n glitching,\n toggleTheme,\n setTheme,\n };\n}\n\nexport default useWalrosTheme;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/assets.ts","../src/components/WalrosPortalTransition.tsx","../src/components/WalrosLogo.tsx","../src/components/WalrosWordmark.tsx","../src/components/WalrosThemeGlitch.tsx","../src/hooks/useWalrosTheme.ts"],"names":["initialPixels","initialScale","jsx","jsxs","useState","useRef","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["export const walrosPortalSilhouetteUrl = new URL(\n \"./assets/walros-portal-silhouette.svg\",\n import.meta.url,\n).href;\n\nexport const walrosLogoChromeUrl = new URL(\n \"./assets/walros-logo-chrome.png\",\n import.meta.url,\n).href;\n\nexport const walrosWordmarkLightUrl = new URL(\n \"./assets/walros-wordmark-light.png\",\n import.meta.url,\n).href;\n\nexport const walrosWordmarkDarkUrl = new URL(\n \"./assets/walros-wordmark-dark.png\",\n import.meta.url,\n).href;\n","import {\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n} from \"react\";\nimport { gsap } from \"gsap\";\nimport { walrosPortalSilhouetteUrl } from \"../assets\";\n\nexport type WalrosPortalTransitionProps = {\n duration?: number;\n onComplete?: () => void;\n backgroundColor?: string;\n enabled?: boolean;\n storageMode?: \"always\" | \"session\" | \"once\";\n storageKey?: string;\n zIndex?: number;\n};\n\nconst SILHOUETTE_VIEWBOX = 1254;\nconst FOCUS_X = 626;\nconst FOCUS_Y = 333;\nconst PORTAL_RADIUS = 190;\n\nfunction getStorage(mode: \"session\" | \"once\"): Storage | null {\n if (typeof window === \"undefined\") return null;\n\n try {\n const storage =\n mode === \"session\"\n ? window.sessionStorage\n : window.localStorage;\n const testKey = \"__walros_portal_test__\";\n storage.setItem(testKey, \"1\");\n storage.removeItem(testKey);\n return storage;\n } catch {\n return null;\n }\n}\n\nfunction shouldRunTransition(\n enabled: boolean,\n storageMode: \"always\" | \"session\" | \"once\",\n storageKey: string,\n): boolean {\n if (!enabled) return false;\n if (storageMode === \"always\") return true;\n if (typeof window === \"undefined\") return false;\n\n const storage = getStorage(storageMode);\n if (!storage) return true;\n\n try {\n return storage.getItem(storageKey) == null;\n } catch {\n return true;\n }\n}\n\nexport function WalrosPortalTransition({\n duration = 750,\n onComplete,\n backgroundColor = \"#02050b\",\n enabled = true,\n storageMode = \"always\",\n storageKey = \"walros-portal-seen\",\n zIndex = 9999,\n}: WalrosPortalTransitionProps) {\n const [shouldRun] = useState(() =>\n shouldRunTransition(enabled, storageMode, storageKey),\n );\n const [visible, setVisible] = useState(shouldRun);\n const [size, setSize] = useState({ w: 0, h: 0 });\n\n const overlayRef = useRef<HTMLDivElement | null>(null);\n const maskScaleRef = useRef<SVGGElement | null>(null);\n const glowScaleRef = useRef<SVGGElement | null>(null);\n const completedRef = useRef(false);\n const startedRef = useRef(false);\n const rafRef = useRef<number | null>(null);\n const timelineRef = useRef<gsap.core.Timeline | null>(null);\n const previousOverflowRef = useRef(\"\");\n\n const uid = useId().replace(/[:]/g, \"_\");\n const maskId = `walros-portal-mask-${uid}`;\n const glowFilterId = `walros-portal-glow-${uid}`;\n\n useEffect(() => {\n if (!visible) return;\n\n const element = overlayRef.current;\n if (!element) return;\n\n const measure = () => {\n const rect = element.getBoundingClientRect();\n setSize((previous) =>\n previous.w === rect.width && previous.h === rect.height\n ? previous\n : { w: rect.width, h: rect.height },\n );\n };\n\n measure();\n\n const observer =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(measure)\n : null;\n\n observer?.observe(element);\n window.addEventListener(\"resize\", measure);\n\n return () => {\n observer?.disconnect();\n window.removeEventListener(\"resize\", measure);\n };\n }, [visible]);\n\n useLayoutEffect(() => {\n if (!enabled) {\n setVisible(false);\n return;\n }\n\n if (!visible) return;\n if (completedRef.current || startedRef.current) return;\n if (size.w <= 0 || size.h <= 0) return;\n\n const overlay = overlayRef.current;\n const maskScale = maskScaleRef.current;\n const glowScale = glowScaleRef.current;\n\n if (!overlay || !maskScale) return;\n\n startedRef.current = true;\n previousOverflowRef.current = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n\n const finish = () => {\n if (completedRef.current) return;\n\n completedRef.current = true;\n document.body.style.overflow = previousOverflowRef.current;\n\n if (storageMode !== \"always\") {\n const storage = getStorage(storageMode);\n try {\n storage?.setItem(storageKey, \"1\");\n } catch {\n // El modo privado o una cuota llena no deben romper la web.\n }\n }\n\n setVisible(false);\n onComplete?.();\n };\n\n const reducedMotion = window.matchMedia(\n \"(prefers-reduced-motion: reduce)\",\n ).matches;\n\n if (reducedMotion) {\n const timeline = gsap.timeline({ onComplete: finish });\n timelineRef.current = timeline;\n timeline.to(overlay, {\n opacity: 0,\n duration: 0.15,\n ease: \"power1.out\",\n });\n return;\n }\n\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = null;\n\n const halfDiagonal =\n Math.sqrt(size.w * size.w + size.h * size.h) / 2;\n const initialPixels = Math.min(\n 180,\n Math.max(120, size.w * 0.12),\n );\n const initialScale =\n initialPixels / SILHOUETTE_VIEWBOX;\n const finalScale =\n ((halfDiagonal + 80) / PORTAL_RADIUS) * 1.15;\n\n gsap.set(maskScale, {\n svgOrigin: \"0 0\",\n scale: initialScale,\n });\n\n if (glowScale) {\n gsap.set(glowScale, {\n svgOrigin: \"0 0\",\n scale: initialScale,\n opacity: 0.85,\n });\n }\n\n gsap.set(overlay, { opacity: 1 });\n\n const totalSeconds = duration / 1000;\n const timeline = gsap.timeline({ onComplete: finish });\n timelineRef.current = timeline;\n\n timeline.to(\n maskScale,\n {\n scale: initialScale * 1.4,\n duration: totalSeconds * 0.15,\n ease: \"power2.out\",\n },\n 0,\n );\n\n if (glowScale) {\n timeline.to(\n glowScale,\n {\n scale: initialScale * 1.4,\n opacity: 1,\n duration: totalSeconds * 0.15,\n ease: \"power2.out\",\n },\n 0,\n );\n }\n\n timeline.to(\n maskScale,\n {\n scale: finalScale,\n duration: totalSeconds * 0.85,\n ease: \"power2.in\",\n },\n totalSeconds * 0.15,\n );\n\n if (glowScale) {\n timeline.to(\n glowScale,\n {\n scale: finalScale * 0.9,\n opacity: 0,\n duration: totalSeconds * 0.4,\n ease: \"power2.in\",\n },\n totalSeconds * 0.45,\n );\n }\n\n timeline.to(\n overlay,\n {\n opacity: 0,\n duration: totalSeconds * 0.1,\n ease: \"power2.out\",\n },\n totalSeconds * 0.9,\n );\n });\n }, [\n duration,\n enabled,\n onComplete,\n size,\n storageKey,\n storageMode,\n visible,\n ]);\n\n useEffect(() => {\n return () => {\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current);\n }\n\n timelineRef.current?.kill();\n\n if (startedRef.current && !completedRef.current) {\n document.body.style.overflow =\n previousOverflowRef.current;\n }\n };\n }, []);\n\n if (!shouldRun || !visible) return null;\n\n const { w, h } = size;\n const ready = w > 0 && h > 0;\n\n const viewportCenterX = w / 2;\n const viewportCenterY = h / 2;\n const initialPixels = Math.min(\n 180,\n Math.max(120, w * 0.12),\n );\n const initialScale =\n initialPixels / SILHOUETTE_VIEWBOX;\n const visualCenter = SILHOUETTE_VIEWBOX / 2;\n const initialOffsetX =\n (visualCenter - FOCUS_X) * initialScale;\n const initialOffsetY =\n (visualCenter - FOCUS_Y) * initialScale;\n const portalCenterX =\n viewportCenterX - initialOffsetX;\n const portalCenterY =\n viewportCenterY - initialOffsetY;\n\n return (\n <div\n ref={overlayRef}\n aria-hidden=\"true\"\n style={{\n position: \"fixed\",\n inset: 0,\n width: \"100vw\",\n height: \"100dvh\",\n zIndex,\n pointerEvents: \"none\",\n overflow: \"hidden\",\n backgroundColor: ready\n ? \"transparent\"\n : backgroundColor,\n }}\n >\n {ready && (\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox={`0 0 ${w} ${h}`}\n preserveAspectRatio=\"none\"\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"block\",\n }}\n >\n <defs>\n <filter\n id={glowFilterId}\n x=\"-50%\"\n y=\"-50%\"\n width=\"200%\"\n height=\"200%\"\n >\n <feGaussianBlur stdDeviation=\"28\" />\n </filter>\n\n <mask\n id={maskId}\n maskUnits=\"userSpaceOnUse\"\n x=\"0\"\n y=\"0\"\n width={w}\n height={h}\n >\n <rect\n x=\"0\"\n y=\"0\"\n width={w}\n height={h}\n fill=\"white\"\n />\n\n <g\n transform={`translate(${portalCenterX} ${portalCenterY})`}\n >\n <g\n ref={maskScaleRef}\n transform={`scale(${initialScale})`}\n >\n <image\n href={walrosPortalSilhouetteUrl}\n x={-FOCUS_X}\n y={-FOCUS_Y}\n width={SILHOUETTE_VIEWBOX}\n height={SILHOUETTE_VIEWBOX}\n />\n </g>\n </g>\n </mask>\n </defs>\n\n <rect\n x=\"0\"\n y=\"0\"\n width={w}\n height={h}\n fill={backgroundColor}\n mask={`url(#${maskId})`}\n />\n\n <g\n transform={`translate(${portalCenterX} ${portalCenterY})`}\n style={{\n mixBlendMode: \"screen\",\n pointerEvents: \"none\",\n }}\n >\n <g\n ref={glowScaleRef}\n transform={`scale(${initialScale})`}\n opacity=\"0.85\"\n >\n <g filter={`url(#${glowFilterId})`}>\n <image\n href={walrosPortalSilhouetteUrl}\n x={-FOCUS_X}\n y={-FOCUS_Y}\n width={SILHOUETTE_VIEWBOX}\n height={SILHOUETTE_VIEWBOX}\n style={{\n filter:\n \"brightness(0) saturate(100%) invert(58%) sepia(94%) saturate(1352%) hue-rotate(182deg)\",\n opacity: 0.6,\n }}\n />\n </g>\n </g>\n </g>\n </svg>\n )}\n </div>\n );\n}\n\nexport default WalrosPortalTransition;\n","import type { ImgHTMLAttributes } from \"react\";\nimport { walrosLogoChromeUrl } from \"../assets\";\n\nexport type WalrosLogoProps = Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n \"src\"\n>;\n\nexport function WalrosLogo({\n alt = \"WalrOS\",\n draggable = false,\n ...props\n}: WalrosLogoProps) {\n return (\n <img\n src={walrosLogoChromeUrl}\n alt={alt}\n draggable={draggable}\n {...props}\n />\n );\n}\n\nexport default WalrosLogo;\n","import type { ImgHTMLAttributes } from \"react\";\nimport {\n walrosWordmarkDarkUrl,\n walrosWordmarkLightUrl,\n} from \"../assets\";\n\nexport type WalrosWordmarkProps = Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n \"src\"\n> & {\n variant?: \"light\" | \"dark\";\n};\n\nexport function WalrosWordmark({\n variant = \"light\",\n alt = \"WalrOS\",\n draggable = false,\n ...props\n}: WalrosWordmarkProps) {\n const src =\n variant === \"dark\"\n ? walrosWordmarkDarkUrl\n : walrosWordmarkLightUrl;\n\n return (\n <img\n src={src}\n alt={alt}\n draggable={draggable}\n {...props}\n />\n );\n}\n\nexport default WalrosWordmark;\n","import type { CSSProperties } from \"react\";\n\nexport type WalrosThemeGlitchProps = {\n active: boolean;\n zIndex?: number;\n className?: string;\n style?: CSSProperties;\n};\n\nconst GLITCH_STYLES = `\n.walros-theme-glitch-root {\n position: fixed;\n inset: 0;\n pointer-events: none;\n overflow: hidden;\n}\n.walros-theme-glitch-root::before,\n.walros-theme-glitch-root::after {\n content: \"\";\n position: absolute;\n inset: 0;\n mix-blend-mode: screen;\n}\n.walros-theme-glitch-root::before {\n background:\n repeating-linear-gradient(\n 0deg,\n transparent 0 2px,\n rgba(59, 130, 246, 0.35) 2px 3px,\n transparent 3px 5px,\n rgba(236, 72, 153, 0.28) 5px 6px\n );\n animation: walros-glitch-scan 700ms steps(14) forwards;\n}\n.walros-theme-glitch-root::after {\n background:\n linear-gradient(\n 90deg,\n rgba(6, 182, 212, 0.5),\n transparent 40%,\n transparent 60%,\n rgba(236, 72, 153, 0.5)\n );\n animation: walros-glitch-slice 700ms steps(10) forwards;\n}\n\n@keyframes walros-glitch-scan {\n 0% { transform: translate(0, 0); opacity: 1; }\n 15% { transform: translate(-10px, 6px); opacity: 0.9; }\n 30% { transform: translate(8px, -4px); opacity: 1; }\n 45% { transform: translate(-6px, 3px); opacity: 0.85; }\n 60% { transform: translate(4px, -8px); opacity: 1; }\n 80% { transform: translate(-3px, 4px); opacity: 0.6; }\n 100% { transform: translate(0, 0); opacity: 0; }\n}\n\n@keyframes walros-glitch-slice {\n 0% { clip-path: inset(0 0 0 0); transform: translate(0, 0); opacity: 1; }\n 15% { clip-path: inset(20% 0 55% 0); transform: translate(-12px, 0); }\n 30% { clip-path: inset(60% 0 12% 0); transform: translate(14px, 0); }\n 45% { clip-path: inset(35% 0 40% 0); transform: translate(-10px, 0); }\n 60% { clip-path: inset(10% 0 75% 0); transform: translate(8px, 0); }\n 75% { clip-path: inset(72% 0 5% 0); transform: translate(-6px, 0); }\n 90% { clip-path: inset(25% 0 60% 0); transform: translate(4px, 0); opacity: 0.7; }\n 100% { clip-path: inset(0 0 100% 0); transform: translate(0, 0); opacity: 0; }\n}\n\n.walros-theme-glitch-lock {\n overscroll-behavior: none;\n}\n\n.walros-theme-glitch-page {\n will-change: transform, filter;\n}\n\n/* Comportamiento original de WalrOS Forum para páginas normales. */\n.walros-theme-glitch-page--body {\n animation: walros-glitch-page-body 500ms steps(8) both;\n}\n\n@keyframes walros-glitch-page-body {\n 0% { transform: translate(0, 0); filter: none; }\n 20% { transform: translate(-4px, 2px); filter: hue-rotate(40deg) contrast(1.15); }\n 40% { transform: translate(5px, -3px); filter: hue-rotate(-30deg) saturate(1.4); }\n 60% { transform: translate(-3px, 4px); filter: hue-rotate(90deg) contrast(1.1); }\n 80% { transform: translate(2px, -2px); filter: hue-rotate(-60deg) saturate(1.2); }\n 100% { transform: translate(0, 0); filter: none; }\n}\n\n/*\n * Modo seguro para parallax/sticky/ScrollTrigger.\n * El shake se aplica a una capa estable del viewport, nunca al scroll real.\n * El pequeño overscan evita descubrir bordes al desplazar la escena.\n */\n.walros-theme-glitch-page--viewport {\n transform-origin: 50% var(--walros-glitch-origin-y, 50%);\n animation: walros-glitch-page-viewport 500ms steps(8) both;\n}\n\n@keyframes walros-glitch-page-viewport {\n 0% { transform: translate3d(0, 0, 0) scale(1.012); filter: none; }\n 20% { transform: translate3d(-4px, 2px, 0) scale(1.012); filter: hue-rotate(40deg) contrast(1.15); }\n 40% { transform: translate3d(5px, -3px, 0) scale(1.012); filter: hue-rotate(-30deg) saturate(1.4); }\n 60% { transform: translate3d(-3px, 4px, 0) scale(1.012); filter: hue-rotate(90deg) contrast(1.1); }\n 80% { transform: translate3d(2px, -2px, 0) scale(1.012); filter: hue-rotate(-60deg) saturate(1.2); }\n 100% { transform: translate3d(0, 0, 0) scale(1); filter: none; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .walros-theme-glitch-root::before,\n .walros-theme-glitch-root::after {\n animation: walros-glitch-reduced 150ms ease-out forwards;\n }\n\n .walros-theme-glitch-page--body,\n .walros-theme-glitch-page--viewport {\n animation: none;\n }\n\n @keyframes walros-glitch-reduced {\n from { opacity: 0.35; }\n to { opacity: 0; }\n }\n}\n`;\n\nexport function WalrosThemeGlitch({\n active,\n zIndex = 9998,\n className,\n style,\n}: WalrosThemeGlitchProps) {\n return (\n <>\n <style>{GLITCH_STYLES}</style>\n {active ? (\n <div\n className={[\"walros-theme-glitch-root\", className]\n .filter(Boolean)\n .join(\" \")}\n style={{ zIndex, ...style }}\n aria-hidden=\"true\"\n />\n ) : null}\n </>\n );\n}\n\nexport default WalrosThemeGlitch;\n","import {\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport type { RefObject } from \"react\";\n\nexport type WalrosTheme = \"light\" | \"dark\";\nexport type WalrosThemeMode = \"body\" | \"viewport\";\n\nexport type WalrosThemeShakeTarget =\n | HTMLElement\n | RefObject<HTMLElement | null>\n | null\n | undefined;\n\nexport type UseWalrosThemeOptions = {\n storageKey?: string;\n defaultTheme?: WalrosTheme;\n useSystemPreference?: boolean;\n swapDelay?: number;\n totalDuration?: number;\n applyTheme?: (theme: WalrosTheme) => void;\n\n /**\n * `body` reproduce el comportamiento original de WalrOS Forum.\n * `viewport` bloquea el scroll y sacude solo los elementos indicados,\n * recomendado para parallax, sticky y GSAP ScrollTrigger.\n */\n mode?: WalrosThemeMode;\n\n /** Elementos que recibirán el shake cuando mode=\"viewport\". */\n shakeTargets?: readonly WalrosThemeShakeTarget[];\n\n /**\n * En modo viewport se activa por defecto. Mantiene scrollX/scrollY estables\n * con requestAnimationFrame sin usar position: fixed en el body.\n */\n lockScroll?: boolean;\n\n /** Se ejecuta después de restaurar el scroll; útil para ScrollTrigger.update(). */\n onAfterUnlock?: () => void;\n};\n\nexport type UseWalrosThemeResult = {\n theme: WalrosTheme;\n isDark: boolean;\n mounted: boolean;\n glitching: boolean;\n toggleTheme: () => void;\n setTheme: (theme: WalrosTheme) => void;\n};\n\ntype ViewportLockState = {\n scrollX: number;\n scrollY: number;\n rafId: number;\n active: boolean;\n bodyOverflow: string;\n htmlOverflow: string;\n htmlOverscrollBehavior: string;\n};\n\nconst GLITCH_BASE_CLASS = \"walros-theme-glitch-page\";\nconst GLITCH_BODY_CLASS = \"walros-theme-glitch-page--body\";\nconst GLITCH_VIEWPORT_CLASS = \"walros-theme-glitch-page--viewport\";\nconst GLITCH_LOCK_CLASS = \"walros-theme-glitch-lock\";\n\nfunction defaultApplyTheme(theme: WalrosTheme) {\n if (typeof document === \"undefined\") return;\n\n const root = document.documentElement;\n root.classList.toggle(\"dark\", theme === \"dark\");\n root.style.colorScheme = theme;\n}\n\nfunction readInitialTheme(\n storageKey: string,\n defaultTheme: WalrosTheme,\n useSystemPreference: boolean,\n): WalrosTheme {\n if (typeof window === \"undefined\") return defaultTheme;\n\n try {\n const stored = window.localStorage.getItem(storageKey);\n if (stored === \"light\" || stored === \"dark\") return stored;\n } catch {\n // localStorage puede estar bloqueado en modo privado.\n }\n\n if (\n useSystemPreference &&\n window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches\n ) {\n return \"dark\";\n }\n\n return defaultTheme;\n}\n\nfunction resolveShakeTargets(\n targets: readonly WalrosThemeShakeTarget[],\n): HTMLElement[] {\n const resolved = new Set<HTMLElement>();\n\n for (const target of targets) {\n if (!target) continue;\n\n const element =\n typeof target === \"object\" && \"current\" in target\n ? target.current\n : target;\n\n if (element) resolved.add(element);\n }\n\n return [...resolved];\n}\n\nexport function useWalrosTheme({\n storageKey = \"walros-theme\",\n defaultTheme = \"light\",\n useSystemPreference = false,\n swapDelay = 220,\n totalDuration = 720,\n applyTheme = defaultApplyTheme,\n mode = \"body\",\n shakeTargets = [],\n lockScroll,\n onAfterUnlock,\n}: UseWalrosThemeOptions = {}): UseWalrosThemeResult {\n const [theme, setThemeState] = useState<WalrosTheme>(() =>\n readInitialTheme(storageKey, defaultTheme, useSystemPreference),\n );\n const [mounted, setMounted] = useState(false);\n const [glitching, setGlitching] = useState(false);\n\n const themeRef = useRef(theme);\n const glitchingRef = useRef(false);\n const swapTimerRef = useRef<number | null>(null);\n const cleanupTimerRef = useRef<number | null>(null);\n const applyThemeRef = useRef(applyTheme);\n const modeRef = useRef(mode);\n const shakeTargetsRef = useRef(shakeTargets);\n const lockScrollRef = useRef(lockScroll);\n const onAfterUnlockRef = useRef(onAfterUnlock);\n const activeTargetsRef = useRef<HTMLElement[]>([]);\n const viewportLockRef = useRef<ViewportLockState | null>(null);\n\n themeRef.current = theme;\n applyThemeRef.current = applyTheme;\n modeRef.current = mode;\n shakeTargetsRef.current = shakeTargets;\n lockScrollRef.current = lockScroll;\n onAfterUnlockRef.current = onAfterUnlock;\n\n const persistTheme = useCallback(\n (nextTheme: WalrosTheme) => {\n applyThemeRef.current(nextTheme);\n setThemeState(nextTheme);\n themeRef.current = nextTheme;\n\n try {\n window.localStorage.setItem(storageKey, nextTheme);\n } catch {\n // El cambio debe funcionar aunque localStorage falle.\n }\n },\n [storageKey],\n );\n\n useEffect(() => {\n const initialTheme = readInitialTheme(\n storageKey,\n defaultTheme,\n useSystemPreference,\n );\n\n themeRef.current = initialTheme;\n setThemeState(initialTheme);\n applyThemeRef.current(initialTheme);\n setMounted(true);\n }, [defaultTheme, storageKey, useSystemPreference]);\n\n const clearTimers = useCallback(() => {\n if (swapTimerRef.current !== null) {\n window.clearTimeout(swapTimerRef.current);\n swapTimerRef.current = null;\n }\n\n if (cleanupTimerRef.current !== null) {\n window.clearTimeout(cleanupTimerRef.current);\n cleanupTimerRef.current = null;\n }\n }, []);\n\n const lockViewport = useCallback(() => {\n if (\n typeof window === \"undefined\" ||\n typeof document === \"undefined\" ||\n viewportLockRef.current\n ) {\n return;\n }\n\n const body = document.body;\n const html = document.documentElement;\n const lockState: ViewportLockState = {\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n rafId: 0,\n active: true,\n bodyOverflow: body.style.overflow,\n htmlOverflow: html.style.overflow,\n htmlOverscrollBehavior: html.style.overscrollBehavior,\n };\n\n viewportLockRef.current = lockState;\n\n const keepScrollStable = () => {\n if (!lockState.active) return;\n window.scrollTo(lockState.scrollX, lockState.scrollY);\n lockState.rafId = window.requestAnimationFrame(keepScrollStable);\n };\n\n html.classList.add(GLITCH_LOCK_CLASS);\n html.style.overflow = \"hidden\";\n html.style.overscrollBehavior = \"none\";\n body.style.overflow = \"hidden\";\n lockState.rafId = window.requestAnimationFrame(keepScrollStable);\n }, []);\n\n const unlockViewport = useCallback((runCallback: boolean) => {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return;\n }\n\n const lockState = viewportLockRef.current;\n if (!lockState) return;\n\n lockState.active = false;\n window.cancelAnimationFrame(lockState.rafId);\n\n const body = document.body;\n const html = document.documentElement;\n body.style.overflow = lockState.bodyOverflow;\n html.style.overflow = lockState.htmlOverflow;\n html.style.overscrollBehavior = lockState.htmlOverscrollBehavior;\n html.classList.remove(GLITCH_LOCK_CLASS);\n\n viewportLockRef.current = null;\n window.scrollTo(lockState.scrollX, lockState.scrollY);\n\n if (runCallback) {\n window.requestAnimationFrame(() => {\n onAfterUnlockRef.current?.();\n });\n }\n }, []);\n\n const removeShakeClasses = useCallback(() => {\n for (const target of activeTargetsRef.current) {\n target.classList.remove(\n GLITCH_BASE_CLASS,\n GLITCH_BODY_CLASS,\n GLITCH_VIEWPORT_CLASS,\n );\n target.style.removeProperty(\"--walros-glitch-origin-y\");\n }\n\n activeTargetsRef.current = [];\n }, []);\n\n const finishGlitch = useCallback(() => {\n removeShakeClasses();\n unlockViewport(true);\n glitchingRef.current = false;\n setGlitching(false);\n }, [removeShakeClasses, unlockViewport]);\n\n const setTheme = useCallback(\n (nextTheme: WalrosTheme) => {\n if (glitchingRef.current) return;\n persistTheme(nextTheme);\n },\n [persistTheme],\n );\n\n const toggleTheme = useCallback(() => {\n if (\n typeof window === \"undefined\" ||\n typeof document === \"undefined\" ||\n glitchingRef.current\n ) {\n return;\n }\n\n const currentMode = modeRef.current;\n const shouldLockScroll =\n lockScrollRef.current ?? currentMode === \"viewport\";\n\n if (currentMode === \"viewport\" && shouldLockScroll) {\n lockViewport();\n }\n\n const targets =\n currentMode === \"body\"\n ? [document.body]\n : resolveShakeTargets(shakeTargetsRef.current);\n\n const modeClass =\n currentMode === \"body\"\n ? GLITCH_BODY_CLASS\n : GLITCH_VIEWPORT_CLASS;\n\n for (const target of targets) {\n target.style.setProperty(\n \"--walros-glitch-origin-y\",\n currentMode === \"body\"\n ? `${window.scrollY + window.innerHeight / 2}px`\n : \"50%\",\n );\n target.classList.add(GLITCH_BASE_CLASS, modeClass);\n }\n\n activeTargetsRef.current = targets;\n glitchingRef.current = true;\n setGlitching(true);\n\n const reducedMotion = window.matchMedia?.(\n \"(prefers-reduced-motion: reduce)\",\n ).matches;\n\n const nextTheme: WalrosTheme =\n themeRef.current === \"dark\" ? \"light\" : \"dark\";\n\n const effectiveSwapDelay = reducedMotion\n ? 75\n : Math.max(0, swapDelay);\n const effectiveDuration = reducedMotion\n ? 150\n : Math.max(effectiveSwapDelay, totalDuration);\n\n swapTimerRef.current = window.setTimeout(() => {\n persistTheme(nextTheme);\n swapTimerRef.current = null;\n }, effectiveSwapDelay);\n\n cleanupTimerRef.current = window.setTimeout(() => {\n cleanupTimerRef.current = null;\n finishGlitch();\n }, effectiveDuration);\n }, [finishGlitch, lockViewport, persistTheme, swapDelay, totalDuration]);\n\n useEffect(() => {\n return () => {\n clearTimers();\n removeShakeClasses();\n unlockViewport(false);\n };\n }, [clearTimers, removeShakeClasses, unlockViewport]);\n\n return {\n theme,\n isDark: theme === \"dark\",\n mounted,\n glitching,\n toggleTheme,\n setTheme,\n };\n}\n\nexport default useWalrosTheme;\n"]}
|