@alkimi.org/ui-kit 0.1.8 → 0.1.10
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.github.md +63 -11
- package/README.md +2 -33
- package/README.npm.md +2 -33
- package/dist/components/GlitchLink.d.mts +12 -0
- package/dist/components/GlitchLink.d.ts +12 -0
- package/dist/components/GlitchLink.js +74 -0
- package/dist/components/GlitchLink.js.map +1 -0
- package/dist/components/GlitchLink.mjs +44 -0
- package/dist/components/GlitchLink.mjs.map +1 -0
- package/dist/components/PixelLoad.d.mts +20 -0
- package/dist/components/PixelLoad.d.ts +20 -0
- package/dist/components/PixelLoad.js +182 -0
- package/dist/components/PixelLoad.js.map +1 -0
- package/dist/components/PixelLoad.mjs +148 -0
- package/dist/components/PixelLoad.mjs.map +1 -0
- package/dist/components/TextDecoder.d.mts +15 -0
- package/dist/components/TextDecoder.d.ts +15 -0
- package/dist/components/TextDecoder.js +293 -0
- package/dist/components/TextDecoder.js.map +1 -0
- package/dist/components/TextDecoder.mjs +265 -0
- package/dist/components/TextDecoder.mjs.map +1 -0
- package/dist/components/button.d.mts +16 -0
- package/dist/components/button.d.ts +16 -0
- package/dist/components/button.js +109 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/button.mjs +74 -0
- package/dist/components/button.mjs.map +1 -0
- package/dist/components/card.d.mts +10 -0
- package/dist/components/card.d.ts +10 -0
- package/dist/components/card.js +115 -0
- package/dist/components/card.js.map +1 -0
- package/dist/components/card.mjs +76 -0
- package/dist/components/card.mjs.map +1 -0
- package/dist/index.css +250 -11
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +16 -21
- package/dist/index.d.ts +16 -21
- package/dist/index.js +467 -52
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +467 -47
- package/dist/index.mjs.map +1 -1
- package/dist/lib/utils.d.mts +5 -0
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.js +36 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/utils.mjs +12 -0
- package/dist/lib/utils.mjs.map +1 -0
- package/dist/styles.css +250 -11
- package/dist/styles.css.map +1 -1
- package/package.json +48 -12
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
// src/components/PixelLoad.tsx
|
|
5
|
+
import Image from "next/image";
|
|
6
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
function isStaticImageData(src) {
|
|
9
|
+
return typeof src === "object" && "src" in src;
|
|
10
|
+
}
|
|
11
|
+
function getImageSrc(src) {
|
|
12
|
+
return isStaticImageData(src) ? src.src : src;
|
|
13
|
+
}
|
|
14
|
+
function PixelLoad({
|
|
15
|
+
src,
|
|
16
|
+
alt,
|
|
17
|
+
duration = 600,
|
|
18
|
+
steps = 15,
|
|
19
|
+
className,
|
|
20
|
+
onAnimationComplete,
|
|
21
|
+
priority,
|
|
22
|
+
quality,
|
|
23
|
+
placeholder = "empty",
|
|
24
|
+
blurDataURL,
|
|
25
|
+
objectFit = "cover"
|
|
26
|
+
}) {
|
|
27
|
+
const containerRef = useRef(null);
|
|
28
|
+
const canvasRef = useRef(null);
|
|
29
|
+
const [status, setStatus] = useState("loading");
|
|
30
|
+
const [dimensions, setDimensions] = useState(null);
|
|
31
|
+
const imageSrc = getImageSrc(src);
|
|
32
|
+
const drawPixelated = useCallback(
|
|
33
|
+
(ctx, img, pixelSize, w, h) => {
|
|
34
|
+
ctx.imageSmoothingEnabled = false;
|
|
35
|
+
const sw = Math.max(1, Math.floor(w / pixelSize));
|
|
36
|
+
const sh = Math.max(1, Math.floor(h / pixelSize));
|
|
37
|
+
ctx.clearRect(0, 0, w, h);
|
|
38
|
+
ctx.drawImage(img, 0, 0, sw, sh);
|
|
39
|
+
ctx.drawImage(canvasRef.current, 0, 0, sw, sh, 0, 0, w, h);
|
|
40
|
+
},
|
|
41
|
+
[]
|
|
42
|
+
);
|
|
43
|
+
const runAnimation = useCallback(
|
|
44
|
+
(ctx, img, w, h) => {
|
|
45
|
+
const minPixelSize = Math.max(w, h) / 4;
|
|
46
|
+
const intervalMs = duration / steps;
|
|
47
|
+
let currentStep = 0;
|
|
48
|
+
setStatus("animating");
|
|
49
|
+
const animate = () => {
|
|
50
|
+
const progress = currentStep / steps;
|
|
51
|
+
const pixelSize = Math.max(1, Math.floor(minPixelSize * (1 - progress)));
|
|
52
|
+
drawPixelated(ctx, img, pixelSize, w, h);
|
|
53
|
+
currentStep++;
|
|
54
|
+
if (currentStep <= steps) {
|
|
55
|
+
window.setTimeout(animate, intervalMs);
|
|
56
|
+
} else {
|
|
57
|
+
setStatus("complete");
|
|
58
|
+
onAnimationComplete?.();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
animate();
|
|
62
|
+
},
|
|
63
|
+
[duration, steps, drawPixelated, onAnimationComplete]
|
|
64
|
+
);
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const container = containerRef.current;
|
|
67
|
+
if (!container) return;
|
|
68
|
+
const updateDimensions = () => {
|
|
69
|
+
const { width, height } = container.getBoundingClientRect();
|
|
70
|
+
setDimensions({ width: Math.floor(width), height: Math.floor(height) });
|
|
71
|
+
};
|
|
72
|
+
const resizeObserver = new ResizeObserver(updateDimensions);
|
|
73
|
+
resizeObserver.observe(container);
|
|
74
|
+
updateDimensions();
|
|
75
|
+
return () => {
|
|
76
|
+
resizeObserver.disconnect();
|
|
77
|
+
};
|
|
78
|
+
}, []);
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (!dimensions) return;
|
|
81
|
+
if (dimensions.width <= 0 || dimensions.height <= 0) return;
|
|
82
|
+
const canvas = canvasRef.current;
|
|
83
|
+
if (!canvas) return;
|
|
84
|
+
const ctx = canvas.getContext("2d");
|
|
85
|
+
if (!ctx) return;
|
|
86
|
+
canvas.width = dimensions.width;
|
|
87
|
+
canvas.height = dimensions.height;
|
|
88
|
+
const img = new window.Image();
|
|
89
|
+
img.crossOrigin = "anonymous";
|
|
90
|
+
img.onload = () => {
|
|
91
|
+
const minPixelSize = Math.max(dimensions.width, dimensions.height) / 4;
|
|
92
|
+
drawPixelated(ctx, img, minPixelSize, dimensions.width, dimensions.height);
|
|
93
|
+
runAnimation(ctx, img, dimensions.width, dimensions.height);
|
|
94
|
+
};
|
|
95
|
+
img.onerror = () => {
|
|
96
|
+
console.error("PixelLoad: Failed to load image");
|
|
97
|
+
};
|
|
98
|
+
img.src = imageSrc;
|
|
99
|
+
return () => {
|
|
100
|
+
img.onload = null;
|
|
101
|
+
img.onerror = null;
|
|
102
|
+
};
|
|
103
|
+
}, [imageSrc, dimensions, runAnimation, drawPixelated]);
|
|
104
|
+
const isComplete = status === "complete";
|
|
105
|
+
const isAnimating = status === "animating" || status === "loading";
|
|
106
|
+
return /* @__PURE__ */ jsxs(
|
|
107
|
+
"div",
|
|
108
|
+
{
|
|
109
|
+
ref: containerRef,
|
|
110
|
+
className: `relative w-full h-full ${className || ""}`,
|
|
111
|
+
children: [
|
|
112
|
+
/* @__PURE__ */ jsx(
|
|
113
|
+
"canvas",
|
|
114
|
+
{
|
|
115
|
+
ref: canvasRef,
|
|
116
|
+
className: "absolute top-0 left-0 w-full h-full",
|
|
117
|
+
style: {
|
|
118
|
+
objectFit,
|
|
119
|
+
opacity: isComplete ? 0 : 1,
|
|
120
|
+
zIndex: isAnimating ? 2 : 1
|
|
121
|
+
},
|
|
122
|
+
"aria-hidden": isComplete
|
|
123
|
+
}
|
|
124
|
+
),
|
|
125
|
+
isComplete && /* @__PURE__ */ jsx(
|
|
126
|
+
Image,
|
|
127
|
+
{
|
|
128
|
+
src,
|
|
129
|
+
alt,
|
|
130
|
+
fill: true,
|
|
131
|
+
priority,
|
|
132
|
+
quality,
|
|
133
|
+
placeholder,
|
|
134
|
+
blurDataURL,
|
|
135
|
+
className: "opacity-100 transition-opacity duration-150 ease-out z-[1]",
|
|
136
|
+
style: {
|
|
137
|
+
objectFit
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
export {
|
|
146
|
+
PixelLoad
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=PixelLoad.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/PixelLoad.tsx"],"sourcesContent":["\"use client\"\n\nimport Image, { type StaticImageData } from \"next/image\"\nimport { JSX, useCallback, useEffect, useRef, useState } from \"react\"\n\ntype PixelLoadStatus = \"loading\" | \"animating\" | \"complete\"\n\ntype ImageSrc = string | StaticImageData\n\nexport interface PixelLoadProps {\n src: ImageSrc\n alt: string\n duration?: number\n steps?: number\n className?: string\n onAnimationComplete?: () => void\n priority?: boolean\n quality?: number\n placeholder?: \"blur\" | \"empty\"\n blurDataURL?: string\n objectFit?: \"contain\" | \"cover\" | \"fill\" | \"none\" | \"scale-down\"\n}\n\nfunction isStaticImageData(src: ImageSrc): src is StaticImageData {\n return typeof src === \"object\" && \"src\" in src\n}\n\nfunction getImageSrc(src: ImageSrc): string {\n return isStaticImageData(src) ? src.src : src\n}\n\nexport function PixelLoad({\n src,\n alt,\n duration = 600,\n steps = 15,\n className,\n onAnimationComplete,\n priority,\n quality,\n placeholder = \"empty\",\n blurDataURL,\n objectFit = \"cover\",\n}: PixelLoadProps): JSX.Element {\n const containerRef = useRef<HTMLDivElement>(null)\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const [status, setStatus] = useState<PixelLoadStatus>(\"loading\")\n const [dimensions, setDimensions] = useState<{\n width: number\n height: number\n } | null>(null)\n\n const imageSrc = getImageSrc(src)\n\n const drawPixelated = useCallback(\n (\n ctx: CanvasRenderingContext2D,\n img: HTMLImageElement,\n pixelSize: number,\n w: number,\n h: number\n ): void => {\n ctx.imageSmoothingEnabled = false\n\n const sw = Math.max(1, Math.floor(w / pixelSize))\n const sh = Math.max(1, Math.floor(h / pixelSize))\n\n ctx.clearRect(0, 0, w, h)\n ctx.drawImage(img, 0, 0, sw, sh)\n ctx.drawImage(canvasRef.current!, 0, 0, sw, sh, 0, 0, w, h)\n },\n []\n )\n\n const runAnimation = useCallback(\n (\n ctx: CanvasRenderingContext2D,\n img: HTMLImageElement,\n w: number,\n h: number\n ): void => {\n const minPixelSize = Math.max(w, h) / 4\n const intervalMs = duration / steps\n let currentStep = 0\n\n setStatus(\"animating\")\n\n const animate = (): void => {\n const progress = currentStep / steps\n const pixelSize = Math.max(1, Math.floor(minPixelSize * (1 - progress)))\n\n drawPixelated(ctx, img, pixelSize, w, h)\n\n currentStep++\n\n if (currentStep <= steps) {\n window.setTimeout(animate, intervalMs)\n } else {\n setStatus(\"complete\")\n onAnimationComplete?.()\n }\n }\n\n animate()\n },\n [duration, steps, drawPixelated, onAnimationComplete]\n )\n\n useEffect(() => {\n const container = containerRef.current\n if (!container) return\n\n const updateDimensions = (): void => {\n const { width, height } = container.getBoundingClientRect()\n setDimensions({ width: Math.floor(width), height: Math.floor(height) })\n }\n\n const resizeObserver = new ResizeObserver(updateDimensions)\n resizeObserver.observe(container)\n updateDimensions()\n\n return (): void => {\n resizeObserver.disconnect()\n }\n }, [])\n\n useEffect(() => {\n if (!dimensions) return\n\n // Guard against invalid dimensions\n if (dimensions.width <= 0 || dimensions.height <= 0) return\n\n const canvas = canvasRef.current\n if (!canvas) return\n\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n // Set canvas dimensions immediately to ensure it covers the area\n canvas.width = dimensions.width\n canvas.height = dimensions.height\n\n const img = new window.Image()\n img.crossOrigin = \"anonymous\"\n\n img.onload = (): void => {\n // Draw first frame immediately to prevent original image from showing\n const minPixelSize = Math.max(dimensions.width, dimensions.height) / 4\n drawPixelated(ctx, img, minPixelSize, dimensions.width, dimensions.height)\n // Then start animation\n runAnimation(ctx, img, dimensions.width, dimensions.height)\n }\n\n img.onerror = (): void => {\n console.error(\"PixelLoad: Failed to load image\")\n }\n\n img.src = imageSrc\n\n return (): void => {\n img.onload = null\n img.onerror = null\n }\n }, [imageSrc, dimensions, runAnimation, drawPixelated])\n\n const isComplete = status === \"complete\"\n const isAnimating = status === \"animating\" || status === \"loading\"\n\n return (\n <div\n ref={containerRef}\n className={`relative w-full h-full ${className || \"\"}`}\n >\n <canvas\n ref={canvasRef}\n className=\"absolute top-0 left-0 w-full h-full\"\n style={{\n objectFit,\n opacity: isComplete ? 0 : 1,\n zIndex: isAnimating ? 2 : 1,\n }}\n aria-hidden={isComplete}\n />\n {isComplete && (\n <Image\n src={src}\n alt={alt}\n fill\n priority={priority}\n quality={quality}\n placeholder={placeholder}\n blurDataURL={blurDataURL}\n className=\"opacity-100 transition-opacity duration-150 ease-out z-[1]\"\n style={{\n objectFit,\n }}\n />\n )}\n </div>\n )\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface TextDecoderProps {
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
className?: string;
|
|
7
|
+
delay?: number;
|
|
8
|
+
symbols?: string[];
|
|
9
|
+
maxIterations?: number;
|
|
10
|
+
speed?: number;
|
|
11
|
+
}
|
|
12
|
+
declare const TextDecoder: ({ children, className, delay, symbols, maxIterations, speed, }: TextDecoderProps) => react_jsx_runtime.JSX.Element;
|
|
13
|
+
declare const SuspenseDecodedText: (props: TextDecoderProps) => react_jsx_runtime.JSX.Element;
|
|
14
|
+
|
|
15
|
+
export { SuspenseDecodedText, type TextDecoderProps, TextDecoder as default };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface TextDecoderProps {
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
className?: string;
|
|
7
|
+
delay?: number;
|
|
8
|
+
symbols?: string[];
|
|
9
|
+
maxIterations?: number;
|
|
10
|
+
speed?: number;
|
|
11
|
+
}
|
|
12
|
+
declare const TextDecoder: ({ children, className, delay, symbols, maxIterations, speed, }: TextDecoderProps) => react_jsx_runtime.JSX.Element;
|
|
13
|
+
declare const SuspenseDecodedText: (props: TextDecoderProps) => react_jsx_runtime.JSX.Element;
|
|
14
|
+
|
|
15
|
+
export { SuspenseDecodedText, type TextDecoderProps, TextDecoder as default };
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
"use strict";
|
|
3
|
+
"use client";
|
|
4
|
+
var __create = Object.create;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __export = (target, all) => {
|
|
11
|
+
for (var name in all)
|
|
12
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
13
|
+
};
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
+
for (let key of __getOwnPropNames(from))
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
18
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
23
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
24
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
25
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
26
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
27
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
28
|
+
mod
|
|
29
|
+
));
|
|
30
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
|
+
|
|
32
|
+
// src/components/TextDecoder.tsx
|
|
33
|
+
var TextDecoder_exports = {};
|
|
34
|
+
__export(TextDecoder_exports, {
|
|
35
|
+
SuspenseDecodedText: () => SuspenseDecodedText,
|
|
36
|
+
default: () => TextDecoder_default
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(TextDecoder_exports);
|
|
39
|
+
var import_react = __toESM(require("react"));
|
|
40
|
+
|
|
41
|
+
// src/lib/utils.ts
|
|
42
|
+
var import_clsx = require("clsx");
|
|
43
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
44
|
+
function cn(...inputs) {
|
|
45
|
+
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/components/TextDecoder.tsx
|
|
49
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
50
|
+
var SYMBOLS = ["\\", "-", "?", "/", "#", "!", "_", "+", "<", ">"];
|
|
51
|
+
var MAX_ITERATIONS = 3;
|
|
52
|
+
var SPEED = 400;
|
|
53
|
+
var scrambleText = (input, symbols) => {
|
|
54
|
+
if (!input) return "";
|
|
55
|
+
return input.split(" ").map((word) => {
|
|
56
|
+
if (!word) return "";
|
|
57
|
+
const randomSymbol = symbols[Math.floor(Math.random() * symbols.length)];
|
|
58
|
+
return randomSymbol.repeat(word.length);
|
|
59
|
+
}).join(" ");
|
|
60
|
+
};
|
|
61
|
+
var extractText = (node) => {
|
|
62
|
+
if (typeof node === "string" || typeof node === "number") {
|
|
63
|
+
return String(node);
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(node)) {
|
|
66
|
+
return node.map(extractText).join("");
|
|
67
|
+
}
|
|
68
|
+
if (import_react.default.isValidElement(node)) {
|
|
69
|
+
const props = node.props;
|
|
70
|
+
let result = "";
|
|
71
|
+
if (typeof props.text === "string") {
|
|
72
|
+
result += props.text;
|
|
73
|
+
}
|
|
74
|
+
if (typeof props.label === "string") {
|
|
75
|
+
result += props.label;
|
|
76
|
+
}
|
|
77
|
+
if (typeof props.title === "string") {
|
|
78
|
+
result += props.title;
|
|
79
|
+
}
|
|
80
|
+
if (props.children) {
|
|
81
|
+
result += extractText(props.children);
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
return "";
|
|
86
|
+
};
|
|
87
|
+
var scrambleReactNode = (node, scrambledText, textStartIndex) => {
|
|
88
|
+
if (typeof node === "string" || typeof node === "number") {
|
|
89
|
+
const text = String(node);
|
|
90
|
+
let scrambled = "";
|
|
91
|
+
for (let i = 0; i < text.length; i++) {
|
|
92
|
+
if (textStartIndex.current < scrambledText.length) {
|
|
93
|
+
scrambled += scrambledText[textStartIndex.current];
|
|
94
|
+
textStartIndex.current++;
|
|
95
|
+
} else {
|
|
96
|
+
scrambled += text[i];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return scrambled;
|
|
100
|
+
}
|
|
101
|
+
if (Array.isArray(node)) {
|
|
102
|
+
return node.map((child, index) => {
|
|
103
|
+
const scrambledChild = scrambleReactNode(
|
|
104
|
+
child,
|
|
105
|
+
scrambledText,
|
|
106
|
+
textStartIndex
|
|
107
|
+
);
|
|
108
|
+
if (import_react.default.isValidElement(scrambledChild)) {
|
|
109
|
+
const originalKey = import_react.default.isValidElement(child) ? child.key : null;
|
|
110
|
+
if (scrambledChild.key == null && originalKey == null) {
|
|
111
|
+
return import_react.default.cloneElement(scrambledChild, { key: `decoded-${index}` });
|
|
112
|
+
}
|
|
113
|
+
if (scrambledChild.key == null && originalKey != null) {
|
|
114
|
+
return import_react.default.cloneElement(scrambledChild, { key: originalKey });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return scrambledChild;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
if (import_react.default.isValidElement(node)) {
|
|
121
|
+
const props = node.props;
|
|
122
|
+
const newProps = { ...props };
|
|
123
|
+
if (typeof props.text === "string") {
|
|
124
|
+
const text = props.text;
|
|
125
|
+
let scrambled = "";
|
|
126
|
+
for (let i = 0; i < text.length; i++) {
|
|
127
|
+
if (textStartIndex.current < scrambledText.length) {
|
|
128
|
+
scrambled += scrambledText[textStartIndex.current];
|
|
129
|
+
textStartIndex.current++;
|
|
130
|
+
} else {
|
|
131
|
+
scrambled += text[i];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
newProps.text = scrambled;
|
|
135
|
+
}
|
|
136
|
+
if (typeof props.label === "string") {
|
|
137
|
+
const label = props.label;
|
|
138
|
+
let scrambled = "";
|
|
139
|
+
for (let i = 0; i < label.length; i++) {
|
|
140
|
+
if (textStartIndex.current < scrambledText.length) {
|
|
141
|
+
scrambled += scrambledText[textStartIndex.current];
|
|
142
|
+
textStartIndex.current++;
|
|
143
|
+
} else {
|
|
144
|
+
scrambled += label[i];
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
newProps.label = scrambled;
|
|
148
|
+
}
|
|
149
|
+
if (typeof props.title === "string") {
|
|
150
|
+
const title = props.title;
|
|
151
|
+
let scrambled = "";
|
|
152
|
+
for (let i = 0; i < title.length; i++) {
|
|
153
|
+
if (textStartIndex.current < scrambledText.length) {
|
|
154
|
+
scrambled += scrambledText[textStartIndex.current];
|
|
155
|
+
textStartIndex.current++;
|
|
156
|
+
} else {
|
|
157
|
+
scrambled += title[i];
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
newProps.title = scrambled;
|
|
161
|
+
}
|
|
162
|
+
if (props.children) {
|
|
163
|
+
newProps.children = scrambleReactNode(
|
|
164
|
+
props.children,
|
|
165
|
+
scrambledText,
|
|
166
|
+
textStartIndex
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
return import_react.default.cloneElement(node, newProps);
|
|
170
|
+
}
|
|
171
|
+
return node;
|
|
172
|
+
};
|
|
173
|
+
var TextDecoder = ({
|
|
174
|
+
children,
|
|
175
|
+
className,
|
|
176
|
+
delay = 0,
|
|
177
|
+
symbols = SYMBOLS,
|
|
178
|
+
maxIterations = MAX_ITERATIONS,
|
|
179
|
+
speed = SPEED
|
|
180
|
+
}) => {
|
|
181
|
+
const [displayContent, setDisplayContent] = (0, import_react.useState)(null);
|
|
182
|
+
const [hasAnimated, setHasAnimated] = (0, import_react.useState)(false);
|
|
183
|
+
const elementRef = (0, import_react.useRef)(null);
|
|
184
|
+
const fullText = (0, import_react.useMemo)(() => extractText(children), [children]);
|
|
185
|
+
const initialScrambled = (0, import_react.useMemo)(
|
|
186
|
+
() => scrambleText(fullText, symbols),
|
|
187
|
+
[fullText, symbols]
|
|
188
|
+
);
|
|
189
|
+
(0, import_react.useEffect)(() => {
|
|
190
|
+
if (!hasAnimated && fullText) {
|
|
191
|
+
const textStartIndex = { current: 0 };
|
|
192
|
+
const scrambledContent = scrambleReactNode(
|
|
193
|
+
children,
|
|
194
|
+
initialScrambled,
|
|
195
|
+
textStartIndex
|
|
196
|
+
);
|
|
197
|
+
setDisplayContent(scrambledContent);
|
|
198
|
+
}
|
|
199
|
+
}, [children, initialScrambled, hasAnimated, fullText]);
|
|
200
|
+
(0, import_react.useEffect)(() => {
|
|
201
|
+
if (!fullText) {
|
|
202
|
+
setDisplayContent(null);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (hasAnimated) {
|
|
206
|
+
setDisplayContent(children);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const element = elementRef.current;
|
|
210
|
+
if (!element) return;
|
|
211
|
+
let iteration = 0;
|
|
212
|
+
let intervalId = null;
|
|
213
|
+
let delayTimeoutId = null;
|
|
214
|
+
const observer = new IntersectionObserver(
|
|
215
|
+
(entries) => {
|
|
216
|
+
const entry = entries[0];
|
|
217
|
+
if (entry.isIntersecting && !hasAnimated) {
|
|
218
|
+
delayTimeoutId = setTimeout(() => {
|
|
219
|
+
const textStartIndex = { current: 0 };
|
|
220
|
+
const scrambledContent = scrambleReactNode(
|
|
221
|
+
children,
|
|
222
|
+
initialScrambled,
|
|
223
|
+
textStartIndex
|
|
224
|
+
);
|
|
225
|
+
setDisplayContent(scrambledContent);
|
|
226
|
+
intervalId = setInterval(() => {
|
|
227
|
+
iteration++;
|
|
228
|
+
if (iteration >= maxIterations) {
|
|
229
|
+
setDisplayContent(children);
|
|
230
|
+
setHasAnimated(true);
|
|
231
|
+
if (intervalId) clearInterval(intervalId);
|
|
232
|
+
} else {
|
|
233
|
+
const newScrambled = scrambleText(fullText, symbols);
|
|
234
|
+
const textStartIndex2 = { current: 0 };
|
|
235
|
+
const scrambledContent2 = scrambleReactNode(
|
|
236
|
+
children,
|
|
237
|
+
newScrambled,
|
|
238
|
+
textStartIndex2
|
|
239
|
+
);
|
|
240
|
+
setDisplayContent(scrambledContent2);
|
|
241
|
+
}
|
|
242
|
+
}, speed);
|
|
243
|
+
}, delay);
|
|
244
|
+
observer.disconnect();
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
threshold: 0.1
|
|
249
|
+
// Trigger when 10% of the element is visible
|
|
250
|
+
}
|
|
251
|
+
);
|
|
252
|
+
observer.observe(element);
|
|
253
|
+
return () => {
|
|
254
|
+
observer.disconnect();
|
|
255
|
+
if (intervalId) clearInterval(intervalId);
|
|
256
|
+
if (delayTimeoutId) clearTimeout(delayTimeoutId);
|
|
257
|
+
};
|
|
258
|
+
}, [
|
|
259
|
+
children,
|
|
260
|
+
fullText,
|
|
261
|
+
initialScrambled,
|
|
262
|
+
hasAnimated,
|
|
263
|
+
delay,
|
|
264
|
+
symbols,
|
|
265
|
+
maxIterations,
|
|
266
|
+
speed
|
|
267
|
+
]);
|
|
268
|
+
const ariaLabel = (0, import_react.useMemo)(() => extractText(children), [children]);
|
|
269
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
270
|
+
"span",
|
|
271
|
+
{
|
|
272
|
+
ref: elementRef,
|
|
273
|
+
"aria-label": ariaLabel,
|
|
274
|
+
className,
|
|
275
|
+
children: displayContent
|
|
276
|
+
}
|
|
277
|
+
);
|
|
278
|
+
};
|
|
279
|
+
var SuspenseDecodedText = (props) => {
|
|
280
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
281
|
+
import_react.Suspense,
|
|
282
|
+
{
|
|
283
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: cn("opacity-0", props.className), children: props.children }),
|
|
284
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextDecoder, { ...props })
|
|
285
|
+
}
|
|
286
|
+
);
|
|
287
|
+
};
|
|
288
|
+
var TextDecoder_default = TextDecoder;
|
|
289
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
290
|
+
0 && (module.exports = {
|
|
291
|
+
SuspenseDecodedText
|
|
292
|
+
});
|
|
293
|
+
//# sourceMappingURL=TextDecoder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/TextDecoder.tsx","../../src/lib/utils.ts"],"sourcesContent":["\"use client\"\nimport React, {\n useState,\n useEffect,\n useMemo,\n useRef,\n Suspense,\n ReactNode,\n} from \"react\"\nimport { cn } from \"../lib/utils\"\n\n// The symbols to use for the scrambling effect (moved outside to avoid recreation)\nconst SYMBOLS = [\"\\\\\", \"-\", \"?\", \"/\", \"#\", \"!\", \"_\", \"+\", \"<\", \">\"]\nconst MAX_ITERATIONS = 3 // How many times to scramble\nconst SPEED = 400 // Speed in milliseconds between scrambles\n\n// Helper function moved outside component to avoid recreation\nconst scrambleText = (input: string, symbols: string[]): string => {\n if (!input) return \"\"\n\n return input\n .split(\" \")\n .map((word: string) => {\n if (!word) return \"\"\n const randomSymbol = symbols[Math.floor(Math.random() * symbols.length)]\n return randomSymbol.repeat(word.length)\n })\n .join(\" \")\n}\n\n// Extract text content from React nodes recursively\n// Also checks common text props like 'text', 'label', 'title', etc.\nconst extractText = (node: ReactNode): string => {\n if (typeof node === \"string\" || typeof node === \"number\") {\n return String(node)\n }\n\n if (Array.isArray(node)) {\n return node.map(extractText).join(\"\")\n }\n\n if (React.isValidElement(node)) {\n const props = node.props as {\n children?: ReactNode\n text?: string\n label?: string\n title?: string\n [key: string]: unknown\n }\n\n let result = \"\"\n\n // Extract text from props first (in order: text, label, title)\n if (typeof props.text === \"string\") {\n result += props.text\n }\n if (typeof props.label === \"string\") {\n result += props.label\n }\n if (typeof props.title === \"string\") {\n result += props.title\n }\n\n // Then extract from children\n if (props.children) {\n result += extractText(props.children)\n }\n\n return result\n }\n\n return \"\"\n}\n\n// Clone React nodes and replace text content with scrambled text\n// This function maps scrambled text back to the original structure\nconst scrambleReactNode = (\n node: ReactNode,\n scrambledText: string,\n textStartIndex: { current: number }\n): ReactNode => {\n if (typeof node === \"string\" || typeof node === \"number\") {\n const text = String(node)\n // For each character in the original text, take the corresponding scrambled character\n // This preserves the length and structure\n let scrambled = \"\"\n for (let i = 0; i < text.length; i++) {\n if (textStartIndex.current < scrambledText.length) {\n scrambled += scrambledText[textStartIndex.current]\n textStartIndex.current++\n } else {\n // Fallback if scrambled text is shorter (shouldn't happen, but safety check)\n scrambled += text[i]\n }\n }\n return scrambled\n }\n\n if (Array.isArray(node)) {\n return node.map((child, index) => {\n const scrambledChild = scrambleReactNode(\n child,\n scrambledText,\n textStartIndex\n )\n // Preserve original key if it exists, otherwise add one for React elements\n if (React.isValidElement(scrambledChild)) {\n const originalKey = React.isValidElement(child) ? child.key : null\n if (scrambledChild.key == null && originalKey == null) {\n return React.cloneElement(scrambledChild, { key: `decoded-${index}` })\n }\n // If original had a key but scrambled doesn't, preserve it\n if (scrambledChild.key == null && originalKey != null) {\n return React.cloneElement(scrambledChild, { key: originalKey })\n }\n }\n return scrambledChild\n })\n }\n\n if (React.isValidElement(node)) {\n // Regular element handling - works for all components\n const props = node.props as {\n children?: ReactNode\n text?: string\n label?: string\n title?: string\n [key: string]: unknown\n }\n const newProps = { ...props }\n\n // Handle text props in the same order as extraction (text, label, title)\n if (typeof props.text === \"string\") {\n const text = props.text\n let scrambled = \"\"\n for (let i = 0; i < text.length; i++) {\n if (textStartIndex.current < scrambledText.length) {\n scrambled += scrambledText[textStartIndex.current]\n textStartIndex.current++\n } else {\n scrambled += text[i]\n }\n }\n newProps.text = scrambled\n }\n\n if (typeof props.label === \"string\") {\n const label = props.label\n let scrambled = \"\"\n for (let i = 0; i < label.length; i++) {\n if (textStartIndex.current < scrambledText.length) {\n scrambled += scrambledText[textStartIndex.current]\n textStartIndex.current++\n } else {\n scrambled += label[i]\n }\n }\n newProps.label = scrambled\n }\n\n if (typeof props.title === \"string\") {\n const title = props.title\n let scrambled = \"\"\n for (let i = 0; i < title.length; i++) {\n if (textStartIndex.current < scrambledText.length) {\n scrambled += scrambledText[textStartIndex.current]\n textStartIndex.current++\n } else {\n scrambled += title[i]\n }\n }\n newProps.title = scrambled\n }\n\n // Handle children after props\n if (props.children) {\n newProps.children = scrambleReactNode(\n props.children,\n scrambledText,\n textStartIndex\n )\n }\n return React.cloneElement(node, newProps)\n }\n\n return node\n}\n\nexport interface TextDecoderProps {\n children: ReactNode\n className?: string\n delay?: number // Delay in milliseconds before starting animation\n symbols?: string[] // Symbols to use for scrambling effect\n maxIterations?: number // How many times to scramble\n speed?: number // Speed in milliseconds between scrambles\n}\n\nconst TextDecoder = ({\n children,\n className,\n delay = 0,\n symbols = SYMBOLS,\n maxIterations = MAX_ITERATIONS,\n speed = SPEED,\n}: TextDecoderProps) => {\n const [displayContent, setDisplayContent] = useState<ReactNode>(null)\n const [hasAnimated, setHasAnimated] = useState(false)\n const elementRef = useRef<HTMLSpanElement>(null)\n\n // Extract full text for scrambling\n const fullText = useMemo(() => extractText(children), [children])\n\n // Memoize initial scrambled text\n const initialScrambled = useMemo(\n () => scrambleText(fullText, symbols),\n [fullText, symbols]\n )\n\n // Initialize with scrambled content to prevent layout shift\n useEffect(() => {\n if (!hasAnimated && fullText) {\n const textStartIndex = { current: 0 }\n const scrambledContent = scrambleReactNode(\n children,\n initialScrambled,\n textStartIndex\n )\n setDisplayContent(scrambledContent)\n }\n }, [children, initialScrambled, hasAnimated, fullText])\n\n useEffect(() => {\n if (!fullText) {\n setDisplayContent(null)\n return\n }\n\n // If already animated, show the final content\n if (hasAnimated) {\n setDisplayContent(children)\n return\n }\n\n const element = elementRef.current\n if (!element) return\n\n let iteration = 0\n let intervalId: NodeJS.Timeout | null = null\n let delayTimeoutId: NodeJS.Timeout | null = null\n\n // Intersection Observer to detect when element is visible\n const observer = new IntersectionObserver(\n (entries) => {\n const entry = entries[0]\n if (entry.isIntersecting && !hasAnimated) {\n // Start animation after delay\n delayTimeoutId = setTimeout(() => {\n // 1. Initial scramble\n const textStartIndex = { current: 0 }\n const scrambledContent = scrambleReactNode(\n children,\n initialScrambled,\n textStartIndex\n )\n setDisplayContent(scrambledContent)\n\n // 2. Set up the interval\n intervalId = setInterval(() => {\n iteration++\n\n if (iteration >= maxIterations) {\n // Stop scrambling and show the real content\n setDisplayContent(children)\n setHasAnimated(true)\n if (intervalId) clearInterval(intervalId)\n } else {\n // Continue scrambling\n const newScrambled = scrambleText(fullText, symbols)\n const textStartIndex = { current: 0 }\n const scrambledContent = scrambleReactNode(\n children,\n newScrambled,\n textStartIndex\n )\n setDisplayContent(scrambledContent)\n }\n }, speed)\n }, delay)\n\n // Disconnect observer once animation starts\n observer.disconnect()\n }\n },\n {\n threshold: 0.1, // Trigger when 10% of the element is visible\n }\n )\n\n observer.observe(element)\n\n // Cleanup function\n return () => {\n observer.disconnect()\n if (intervalId) clearInterval(intervalId)\n if (delayTimeoutId) clearTimeout(delayTimeoutId)\n }\n }, [\n children,\n fullText,\n initialScrambled,\n hasAnimated,\n delay,\n symbols,\n maxIterations,\n speed,\n ])\n\n const ariaLabel = useMemo(() => extractText(children), [children])\n\n return (\n <span\n ref={elementRef}\n aria-label={ariaLabel} // Accessibility: Screen readers read the real text\n className={className}\n >\n {displayContent}\n </span>\n )\n}\n\nconst SuspenseDecodedText = (props: TextDecoderProps) => {\n return (\n <Suspense\n fallback={\n <span className={cn(\"opacity-0\", props.className)}>\n {props.children}\n </span>\n }\n >\n <TextDecoder {...props} />\n </Suspense>\n )\n}\n\nexport { SuspenseDecodedText }\nexport default TextDecoder\n","import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":"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","names":["React","textStartIndex","scrambledContent"]}
|