@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.
Files changed (50) hide show
  1. package/README.github.md +63 -11
  2. package/README.md +2 -33
  3. package/README.npm.md +2 -33
  4. package/dist/components/GlitchLink.d.mts +12 -0
  5. package/dist/components/GlitchLink.d.ts +12 -0
  6. package/dist/components/GlitchLink.js +74 -0
  7. package/dist/components/GlitchLink.js.map +1 -0
  8. package/dist/components/GlitchLink.mjs +44 -0
  9. package/dist/components/GlitchLink.mjs.map +1 -0
  10. package/dist/components/PixelLoad.d.mts +20 -0
  11. package/dist/components/PixelLoad.d.ts +20 -0
  12. package/dist/components/PixelLoad.js +182 -0
  13. package/dist/components/PixelLoad.js.map +1 -0
  14. package/dist/components/PixelLoad.mjs +148 -0
  15. package/dist/components/PixelLoad.mjs.map +1 -0
  16. package/dist/components/TextDecoder.d.mts +15 -0
  17. package/dist/components/TextDecoder.d.ts +15 -0
  18. package/dist/components/TextDecoder.js +293 -0
  19. package/dist/components/TextDecoder.js.map +1 -0
  20. package/dist/components/TextDecoder.mjs +265 -0
  21. package/dist/components/TextDecoder.mjs.map +1 -0
  22. package/dist/components/button.d.mts +16 -0
  23. package/dist/components/button.d.ts +16 -0
  24. package/dist/components/button.js +109 -0
  25. package/dist/components/button.js.map +1 -0
  26. package/dist/components/button.mjs +74 -0
  27. package/dist/components/button.mjs.map +1 -0
  28. package/dist/components/card.d.mts +10 -0
  29. package/dist/components/card.d.ts +10 -0
  30. package/dist/components/card.js +115 -0
  31. package/dist/components/card.js.map +1 -0
  32. package/dist/components/card.mjs +76 -0
  33. package/dist/components/card.mjs.map +1 -0
  34. package/dist/index.css +250 -11
  35. package/dist/index.css.map +1 -1
  36. package/dist/index.d.mts +16 -21
  37. package/dist/index.d.ts +16 -21
  38. package/dist/index.js +467 -52
  39. package/dist/index.js.map +1 -1
  40. package/dist/index.mjs +467 -47
  41. package/dist/index.mjs.map +1 -1
  42. package/dist/lib/utils.d.mts +5 -0
  43. package/dist/lib/utils.d.ts +5 -0
  44. package/dist/lib/utils.js +36 -0
  45. package/dist/lib/utils.js.map +1 -0
  46. package/dist/lib/utils.mjs +12 -0
  47. package/dist/lib/utils.mjs.map +1 -0
  48. package/dist/styles.css +250 -11
  49. package/dist/styles.css.map +1 -1
  50. package/package.json +48 -12
package/dist/index.js CHANGED
@@ -32,12 +32,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
32
32
  var index_exports = {};
33
33
  __export(index_exports, {
34
34
  Button: () => Button,
35
- Card: () => Card,
36
- CardContent: () => CardContent,
37
- CardDescription: () => CardDescription,
38
- CardFooter: () => CardFooter,
39
- CardHeader: () => CardHeader,
40
- CardTitle: () => CardTitle,
35
+ GlitchLink: () => GlitchLink_default,
36
+ PixelLoad: () => PixelLoad,
37
+ Tabs: () => Tabs,
38
+ TabsContent: () => TabsContent,
39
+ TabsList: () => TabsList,
40
+ TabsTrigger: () => TabsTrigger,
41
+ TextDecoder: () => TextDecoder_default,
41
42
  buttonVariants: () => buttonVariants,
42
43
  cn: () => cn
43
44
  });
@@ -58,22 +59,22 @@ function cn(...inputs) {
58
59
  // src/components/button.tsx
59
60
  var import_jsx_runtime = require("react/jsx-runtime");
60
61
  var buttonVariants = (0, import_class_variance_authority.cva)(
61
- "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
62
+ "inline-flex items-center justify-center whitespace-nowrap rounded-[3.75rem] text-[0.875rem] font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
62
63
  {
63
64
  variants: {
64
65
  variant: {
65
66
  default: "bg-primary text-primary-foreground hover:bg-primary/90",
66
67
  destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
67
68
  outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
68
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
69
+ secondary: "bg-secondary/80 text-secondary-foreground hover:bg-secondary",
69
70
  ghost: "hover:bg-accent hover:text-accent-foreground",
70
71
  link: "text-primary underline-offset-4 hover:underline"
71
72
  },
72
73
  size: {
73
- default: "h-10 px-4 py-2",
74
- sm: "h-9 rounded-md px-3",
75
- lg: "h-11 rounded-md px-8",
76
- icon: "h-10 w-10"
74
+ default: "h-9 px-4 py-2",
75
+ sm: "h-8 text-[0.75rem] px-3 py-2",
76
+ lg: "h-10 px-8 py-2",
77
+ icon: "h-9 w-9"
77
78
  }
78
79
  },
79
80
  defaultVariants: {
@@ -83,85 +84,499 @@ var buttonVariants = (0, import_class_variance_authority.cva)(
83
84
  }
84
85
  );
85
86
  var Button = React.forwardRef(
86
- ({ className, variant, size, asChild = false, ...props }, ref) => {
87
+ ({
88
+ className,
89
+ variant,
90
+ size,
91
+ asChild = false,
92
+ loading = false,
93
+ icon,
94
+ ...props
95
+ }, ref) => {
87
96
  const Comp = asChild ? import_react_slot.Slot : "button";
88
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
97
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
89
98
  Comp,
90
99
  {
91
100
  className: cn(buttonVariants({ variant, size, className })),
92
101
  ref,
93
- ...props
102
+ disabled: loading || props.disabled,
103
+ ...props,
104
+ children: [
105
+ loading && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mr-2 h-4 w-4 animate-spin rounded-full border-[1.33px] border-primary-foreground border-t-transparent" }),
106
+ !loading && icon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mr-2", children: icon }),
107
+ props.children
108
+ ]
94
109
  }
95
110
  );
96
111
  }
97
112
  );
98
113
  Button.displayName = "Button";
99
114
 
100
- // src/components/card.tsx
115
+ // src/components/tabs.tsx
101
116
  var React2 = __toESM(require("react"));
117
+ var TabsPrimitive = __toESM(require("@radix-ui/react-tabs"));
102
118
  var import_jsx_runtime2 = require("react/jsx-runtime");
103
- var Card = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
104
- "div",
119
+ var Tabs = TabsPrimitive.Root;
120
+ var TabsList = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
121
+ TabsPrimitive.List,
105
122
  {
106
123
  ref,
107
124
  className: cn(
108
- "rounded-lg border bg-card text-card-foreground shadow-sm",
125
+ "inline-flex items-center justify-center rounded-[3.75rem] bg-muted p-1 text-muted-foreground",
109
126
  className
110
127
  ),
111
128
  ...props
112
129
  }
113
130
  ));
114
- Card.displayName = "Card";
115
- var CardHeader = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
116
- "div",
131
+ TabsList.displayName = TabsPrimitive.List.displayName;
132
+ var TabsTrigger = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
133
+ TabsPrimitive.Trigger,
117
134
  {
118
135
  ref,
119
- className: cn("flex flex-col space-y-1.5 p-6", className),
136
+ className: cn(
137
+ "inline-flex items-center justify-center whitespace-nowrap rounded-[3.75rem] px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
138
+ className
139
+ ),
120
140
  ...props
121
141
  }
122
142
  ));
123
- CardHeader.displayName = "CardHeader";
124
- var CardTitle = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
125
- "h3",
143
+ TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
144
+ var TabsContent = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
145
+ TabsPrimitive.Content,
126
146
  {
127
147
  ref,
128
148
  className: cn(
129
- "text-2xl font-semibold leading-none tracking-tight",
149
+ "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
130
150
  className
131
151
  ),
132
152
  ...props
133
153
  }
134
154
  ));
135
- CardTitle.displayName = "CardTitle";
136
- var CardDescription = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
137
- "p",
138
- {
139
- ref,
140
- className: cn("text-sm text-muted-foreground", className),
141
- ...props
155
+ TabsContent.displayName = TabsPrimitive.Content.displayName;
156
+
157
+ // src/components/TextDecoder.tsx
158
+ var import_react = __toESM(require("react"));
159
+ var import_jsx_runtime3 = require("react/jsx-runtime");
160
+ var SYMBOLS = ["\\", "-", "?", "/", "#", "!", "_", "+", "<", ">"];
161
+ var MAX_ITERATIONS = 3;
162
+ var SPEED = 400;
163
+ var scrambleText = (input, symbols) => {
164
+ if (!input) return "";
165
+ return input.split(" ").map((word) => {
166
+ if (!word) return "";
167
+ const randomSymbol = symbols[Math.floor(Math.random() * symbols.length)];
168
+ return randomSymbol.repeat(word.length);
169
+ }).join(" ");
170
+ };
171
+ var extractText = (node) => {
172
+ if (typeof node === "string" || typeof node === "number") {
173
+ return String(node);
142
174
  }
143
- ));
144
- CardDescription.displayName = "CardDescription";
145
- var CardContent = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref, className: cn("p-6 pt-0", className), ...props }));
146
- CardContent.displayName = "CardContent";
147
- var CardFooter = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
148
- "div",
149
- {
150
- ref,
151
- className: cn("flex items-center p-6 pt-0", className),
152
- ...props
175
+ if (Array.isArray(node)) {
176
+ return node.map(extractText).join("");
153
177
  }
154
- ));
155
- CardFooter.displayName = "CardFooter";
178
+ if (import_react.default.isValidElement(node)) {
179
+ const props = node.props;
180
+ let result = "";
181
+ if (typeof props.text === "string") {
182
+ result += props.text;
183
+ }
184
+ if (typeof props.label === "string") {
185
+ result += props.label;
186
+ }
187
+ if (typeof props.title === "string") {
188
+ result += props.title;
189
+ }
190
+ if (props.children) {
191
+ result += extractText(props.children);
192
+ }
193
+ return result;
194
+ }
195
+ return "";
196
+ };
197
+ var scrambleReactNode = (node, scrambledText, textStartIndex) => {
198
+ if (typeof node === "string" || typeof node === "number") {
199
+ const text = String(node);
200
+ let scrambled = "";
201
+ for (let i = 0; i < text.length; i++) {
202
+ if (textStartIndex.current < scrambledText.length) {
203
+ scrambled += scrambledText[textStartIndex.current];
204
+ textStartIndex.current++;
205
+ } else {
206
+ scrambled += text[i];
207
+ }
208
+ }
209
+ return scrambled;
210
+ }
211
+ if (Array.isArray(node)) {
212
+ return node.map((child, index) => {
213
+ const scrambledChild = scrambleReactNode(
214
+ child,
215
+ scrambledText,
216
+ textStartIndex
217
+ );
218
+ if (import_react.default.isValidElement(scrambledChild)) {
219
+ const originalKey = import_react.default.isValidElement(child) ? child.key : null;
220
+ if (scrambledChild.key == null && originalKey == null) {
221
+ return import_react.default.cloneElement(scrambledChild, { key: `decoded-${index}` });
222
+ }
223
+ if (scrambledChild.key == null && originalKey != null) {
224
+ return import_react.default.cloneElement(scrambledChild, { key: originalKey });
225
+ }
226
+ }
227
+ return scrambledChild;
228
+ });
229
+ }
230
+ if (import_react.default.isValidElement(node)) {
231
+ const props = node.props;
232
+ const newProps = { ...props };
233
+ if (typeof props.text === "string") {
234
+ const text = props.text;
235
+ let scrambled = "";
236
+ for (let i = 0; i < text.length; i++) {
237
+ if (textStartIndex.current < scrambledText.length) {
238
+ scrambled += scrambledText[textStartIndex.current];
239
+ textStartIndex.current++;
240
+ } else {
241
+ scrambled += text[i];
242
+ }
243
+ }
244
+ newProps.text = scrambled;
245
+ }
246
+ if (typeof props.label === "string") {
247
+ const label = props.label;
248
+ let scrambled = "";
249
+ for (let i = 0; i < label.length; i++) {
250
+ if (textStartIndex.current < scrambledText.length) {
251
+ scrambled += scrambledText[textStartIndex.current];
252
+ textStartIndex.current++;
253
+ } else {
254
+ scrambled += label[i];
255
+ }
256
+ }
257
+ newProps.label = scrambled;
258
+ }
259
+ if (typeof props.title === "string") {
260
+ const title = props.title;
261
+ let scrambled = "";
262
+ for (let i = 0; i < title.length; i++) {
263
+ if (textStartIndex.current < scrambledText.length) {
264
+ scrambled += scrambledText[textStartIndex.current];
265
+ textStartIndex.current++;
266
+ } else {
267
+ scrambled += title[i];
268
+ }
269
+ }
270
+ newProps.title = scrambled;
271
+ }
272
+ if (props.children) {
273
+ newProps.children = scrambleReactNode(
274
+ props.children,
275
+ scrambledText,
276
+ textStartIndex
277
+ );
278
+ }
279
+ return import_react.default.cloneElement(node, newProps);
280
+ }
281
+ return node;
282
+ };
283
+ var TextDecoder = ({
284
+ children,
285
+ className,
286
+ delay = 0,
287
+ symbols = SYMBOLS,
288
+ maxIterations = MAX_ITERATIONS,
289
+ speed = SPEED
290
+ }) => {
291
+ const [displayContent, setDisplayContent] = (0, import_react.useState)(null);
292
+ const [hasAnimated, setHasAnimated] = (0, import_react.useState)(false);
293
+ const elementRef = (0, import_react.useRef)(null);
294
+ const fullText = (0, import_react.useMemo)(() => extractText(children), [children]);
295
+ const initialScrambled = (0, import_react.useMemo)(
296
+ () => scrambleText(fullText, symbols),
297
+ [fullText, symbols]
298
+ );
299
+ (0, import_react.useEffect)(() => {
300
+ if (!hasAnimated && fullText) {
301
+ const textStartIndex = { current: 0 };
302
+ const scrambledContent = scrambleReactNode(
303
+ children,
304
+ initialScrambled,
305
+ textStartIndex
306
+ );
307
+ setDisplayContent(scrambledContent);
308
+ }
309
+ }, [children, initialScrambled, hasAnimated, fullText]);
310
+ (0, import_react.useEffect)(() => {
311
+ if (!fullText) {
312
+ setDisplayContent(null);
313
+ return;
314
+ }
315
+ if (hasAnimated) {
316
+ setDisplayContent(children);
317
+ return;
318
+ }
319
+ const element = elementRef.current;
320
+ if (!element) return;
321
+ let iteration = 0;
322
+ let intervalId = null;
323
+ let delayTimeoutId = null;
324
+ const observer = new IntersectionObserver(
325
+ (entries) => {
326
+ const entry = entries[0];
327
+ if (entry.isIntersecting && !hasAnimated) {
328
+ delayTimeoutId = setTimeout(() => {
329
+ const textStartIndex = { current: 0 };
330
+ const scrambledContent = scrambleReactNode(
331
+ children,
332
+ initialScrambled,
333
+ textStartIndex
334
+ );
335
+ setDisplayContent(scrambledContent);
336
+ intervalId = setInterval(() => {
337
+ iteration++;
338
+ if (iteration >= maxIterations) {
339
+ setDisplayContent(children);
340
+ setHasAnimated(true);
341
+ if (intervalId) clearInterval(intervalId);
342
+ } else {
343
+ const newScrambled = scrambleText(fullText, symbols);
344
+ const textStartIndex2 = { current: 0 };
345
+ const scrambledContent2 = scrambleReactNode(
346
+ children,
347
+ newScrambled,
348
+ textStartIndex2
349
+ );
350
+ setDisplayContent(scrambledContent2);
351
+ }
352
+ }, speed);
353
+ }, delay);
354
+ observer.disconnect();
355
+ }
356
+ },
357
+ {
358
+ threshold: 0.1
359
+ // Trigger when 10% of the element is visible
360
+ }
361
+ );
362
+ observer.observe(element);
363
+ return () => {
364
+ observer.disconnect();
365
+ if (intervalId) clearInterval(intervalId);
366
+ if (delayTimeoutId) clearTimeout(delayTimeoutId);
367
+ };
368
+ }, [
369
+ children,
370
+ fullText,
371
+ initialScrambled,
372
+ hasAnimated,
373
+ delay,
374
+ symbols,
375
+ maxIterations,
376
+ speed
377
+ ]);
378
+ const ariaLabel = (0, import_react.useMemo)(() => extractText(children), [children]);
379
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
380
+ "span",
381
+ {
382
+ ref: elementRef,
383
+ "aria-label": ariaLabel,
384
+ className,
385
+ children: displayContent
386
+ }
387
+ );
388
+ };
389
+ var TextDecoder_default = TextDecoder;
390
+
391
+ // src/components/GlitchLink.tsx
392
+ var import_link = __toESM(require("next/link"));
393
+ var import_react2 = require("react");
394
+ var import_jsx_runtime4 = require("react/jsx-runtime");
395
+ var DEFAULT_SYMBOLS = ["/", "#", "*"];
396
+ var GlitchLink = ({
397
+ href,
398
+ children,
399
+ symbols = DEFAULT_SYMBOLS,
400
+ className = "underline",
401
+ ...props
402
+ }) => {
403
+ const [isHovering, setIsHovering] = (0, import_react2.useState)(false);
404
+ const text = typeof children === "string" ? children : "";
405
+ const getRandomGlitch = () => {
406
+ if (!isHovering || !text) return children;
407
+ return text.split(" ").map((word) => {
408
+ const randomLetterIndex = Math.floor(Math.random() * word.length);
409
+ return word.replace(
410
+ word[randomLetterIndex],
411
+ symbols[Math.floor(Math.random() * symbols.length)]
412
+ );
413
+ }).join(" ");
414
+ };
415
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
416
+ import_link.default,
417
+ {
418
+ href,
419
+ className,
420
+ onMouseEnter: () => setIsHovering(true),
421
+ onMouseLeave: () => setIsHovering(false),
422
+ ...props,
423
+ children: text ? isHovering ? getRandomGlitch() : children : children
424
+ }
425
+ );
426
+ };
427
+ var GlitchLink_default = GlitchLink;
428
+
429
+ // src/components/PixelLoad.tsx
430
+ var import_image = __toESM(require("next/image"));
431
+ var import_react3 = require("react");
432
+ var import_jsx_runtime5 = require("react/jsx-runtime");
433
+ function isStaticImageData(src) {
434
+ return typeof src === "object" && "src" in src;
435
+ }
436
+ function getImageSrc(src) {
437
+ return isStaticImageData(src) ? src.src : src;
438
+ }
439
+ function PixelLoad({
440
+ src,
441
+ alt,
442
+ duration = 600,
443
+ steps = 15,
444
+ className,
445
+ onAnimationComplete,
446
+ priority,
447
+ quality,
448
+ placeholder = "empty",
449
+ blurDataURL,
450
+ objectFit = "cover"
451
+ }) {
452
+ const containerRef = (0, import_react3.useRef)(null);
453
+ const canvasRef = (0, import_react3.useRef)(null);
454
+ const [status, setStatus] = (0, import_react3.useState)("loading");
455
+ const [dimensions, setDimensions] = (0, import_react3.useState)(null);
456
+ const imageSrc = getImageSrc(src);
457
+ const drawPixelated = (0, import_react3.useCallback)(
458
+ (ctx, img, pixelSize, w, h) => {
459
+ ctx.imageSmoothingEnabled = false;
460
+ const sw = Math.max(1, Math.floor(w / pixelSize));
461
+ const sh = Math.max(1, Math.floor(h / pixelSize));
462
+ ctx.clearRect(0, 0, w, h);
463
+ ctx.drawImage(img, 0, 0, sw, sh);
464
+ ctx.drawImage(canvasRef.current, 0, 0, sw, sh, 0, 0, w, h);
465
+ },
466
+ []
467
+ );
468
+ const runAnimation = (0, import_react3.useCallback)(
469
+ (ctx, img, w, h) => {
470
+ const minPixelSize = Math.max(w, h) / 4;
471
+ const intervalMs = duration / steps;
472
+ let currentStep = 0;
473
+ setStatus("animating");
474
+ const animate = () => {
475
+ const progress = currentStep / steps;
476
+ const pixelSize = Math.max(1, Math.floor(minPixelSize * (1 - progress)));
477
+ drawPixelated(ctx, img, pixelSize, w, h);
478
+ currentStep++;
479
+ if (currentStep <= steps) {
480
+ window.setTimeout(animate, intervalMs);
481
+ } else {
482
+ setStatus("complete");
483
+ onAnimationComplete?.();
484
+ }
485
+ };
486
+ animate();
487
+ },
488
+ [duration, steps, drawPixelated, onAnimationComplete]
489
+ );
490
+ (0, import_react3.useEffect)(() => {
491
+ const container = containerRef.current;
492
+ if (!container) return;
493
+ const updateDimensions = () => {
494
+ const { width, height } = container.getBoundingClientRect();
495
+ setDimensions({ width: Math.floor(width), height: Math.floor(height) });
496
+ };
497
+ const resizeObserver = new ResizeObserver(updateDimensions);
498
+ resizeObserver.observe(container);
499
+ updateDimensions();
500
+ return () => {
501
+ resizeObserver.disconnect();
502
+ };
503
+ }, []);
504
+ (0, import_react3.useEffect)(() => {
505
+ if (!dimensions) return;
506
+ if (dimensions.width <= 0 || dimensions.height <= 0) return;
507
+ const canvas = canvasRef.current;
508
+ if (!canvas) return;
509
+ const ctx = canvas.getContext("2d");
510
+ if (!ctx) return;
511
+ canvas.width = dimensions.width;
512
+ canvas.height = dimensions.height;
513
+ const img = new window.Image();
514
+ img.crossOrigin = "anonymous";
515
+ img.onload = () => {
516
+ const minPixelSize = Math.max(dimensions.width, dimensions.height) / 4;
517
+ drawPixelated(ctx, img, minPixelSize, dimensions.width, dimensions.height);
518
+ runAnimation(ctx, img, dimensions.width, dimensions.height);
519
+ };
520
+ img.onerror = () => {
521
+ console.error("PixelLoad: Failed to load image");
522
+ };
523
+ img.src = imageSrc;
524
+ return () => {
525
+ img.onload = null;
526
+ img.onerror = null;
527
+ };
528
+ }, [imageSrc, dimensions, runAnimation, drawPixelated]);
529
+ const isComplete = status === "complete";
530
+ const isAnimating = status === "animating" || status === "loading";
531
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
532
+ "div",
533
+ {
534
+ ref: containerRef,
535
+ className: `relative w-full h-full ${className || ""}`,
536
+ children: [
537
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
538
+ "canvas",
539
+ {
540
+ ref: canvasRef,
541
+ className: "absolute top-0 left-0 w-full h-full",
542
+ style: {
543
+ objectFit,
544
+ opacity: isComplete ? 0 : 1,
545
+ zIndex: isAnimating ? 2 : 1
546
+ },
547
+ "aria-hidden": isComplete
548
+ }
549
+ ),
550
+ isComplete && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
551
+ import_image.default,
552
+ {
553
+ src,
554
+ alt,
555
+ fill: true,
556
+ priority,
557
+ quality,
558
+ placeholder,
559
+ blurDataURL,
560
+ className: "opacity-100 transition-opacity duration-150 ease-out z-[1]",
561
+ style: {
562
+ objectFit
563
+ }
564
+ }
565
+ )
566
+ ]
567
+ }
568
+ );
569
+ }
156
570
  // Annotate the CommonJS export names for ESM import in node:
157
571
  0 && (module.exports = {
158
572
  Button,
159
- Card,
160
- CardContent,
161
- CardDescription,
162
- CardFooter,
163
- CardHeader,
164
- CardTitle,
573
+ GlitchLink,
574
+ PixelLoad,
575
+ Tabs,
576
+ TabsContent,
577
+ TabsList,
578
+ TabsTrigger,
579
+ TextDecoder,
165
580
  buttonVariants,
166
581
  cn
167
582
  });