cyberui-2045 2.3.0 → 2.4.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.
Files changed (70) hide show
  1. package/AGENT.md +25 -23
  2. package/README.md +31 -28
  3. package/bin/init.js +11 -5
  4. package/bin/markers.js +18 -0
  5. package/bin/usage-content.js +136 -210
  6. package/dist/component-manifest.json +1454 -0
  7. package/dist/components/Badge.js +49 -0
  8. package/dist/components/Badge.js.map +1 -0
  9. package/dist/components/Button.js +62 -0
  10. package/dist/components/Button.js.map +1 -0
  11. package/dist/components/Card.js +31 -0
  12. package/dist/components/Card.js.map +1 -0
  13. package/dist/components/Carousel.js +585 -0
  14. package/dist/components/Carousel.js.map +1 -0
  15. package/dist/components/Checkbox.js +92 -0
  16. package/dist/components/Checkbox.js.map +1 -0
  17. package/dist/components/CircularProgress.js +87 -0
  18. package/dist/components/CircularProgress.js.map +1 -0
  19. package/dist/components/Divider.js +24 -0
  20. package/dist/components/Divider.js.map +1 -0
  21. package/dist/components/GradientText.js +27 -0
  22. package/dist/components/GradientText.js.map +1 -0
  23. package/dist/components/Image.js +369 -0
  24. package/dist/components/Image.js.map +1 -0
  25. package/dist/components/Input.js +70 -0
  26. package/dist/components/Input.js.map +1 -0
  27. package/dist/components/LinearProgress.js +39 -0
  28. package/dist/components/LinearProgress.js.map +1 -0
  29. package/dist/components/Modal.d.ts +19 -0
  30. package/dist/components/Modal.js +211 -0
  31. package/dist/components/Modal.js.map +1 -0
  32. package/dist/components/Notification.js +88 -0
  33. package/dist/components/Notification.js.map +1 -0
  34. package/dist/components/SectionTitle.js +33 -0
  35. package/dist/components/SectionTitle.js.map +1 -0
  36. package/dist/components/SegmentedProgress.js +82 -0
  37. package/dist/components/SegmentedProgress.js.map +1 -0
  38. package/dist/components/Select.js +93 -0
  39. package/dist/components/Select.js.map +1 -0
  40. package/dist/components/Skeleton.js +106 -0
  41. package/dist/components/Skeleton.js.map +1 -0
  42. package/dist/components/Steps.js +88 -0
  43. package/dist/components/Steps.js.map +1 -0
  44. package/dist/components/TabNavigation.js +153 -0
  45. package/dist/components/TabNavigation.js.map +1 -0
  46. package/dist/components/Timeline.js +99 -0
  47. package/dist/components/Timeline.js.map +1 -0
  48. package/dist/components/Toggle.js +73 -0
  49. package/dist/components/Toggle.js.map +1 -0
  50. package/dist/contexts/NotificationContext.js +100 -0
  51. package/dist/contexts/NotificationContext.js.map +1 -0
  52. package/dist/contexts/NotificationContextBase.js +6 -0
  53. package/dist/contexts/NotificationContextBase.js.map +1 -0
  54. package/dist/hooks/useAnimatedProgress.js +17 -0
  55. package/dist/hooks/useAnimatedProgress.js.map +1 -0
  56. package/dist/hooks/useCyberNotifications.js +14 -0
  57. package/dist/hooks/useCyberNotifications.js.map +1 -0
  58. package/dist/hooks/useCyberScrollbar.js +254 -0
  59. package/dist/hooks/useCyberScrollbar.js.map +1 -0
  60. package/dist/index.d.ts +1 -1
  61. package/dist/index.es.js +63 -5954
  62. package/dist/index.js +13 -13
  63. package/dist/utils/cn.js +9 -0
  64. package/dist/utils/cn.js.map +1 -0
  65. package/dist/utils/devWarn.d.ts +5 -0
  66. package/dist/utils/devWarn.js +8 -0
  67. package/dist/utils/devWarn.js.map +1 -0
  68. package/dist/utils/responsive.js +120 -0
  69. package/dist/utils/responsive.js.map +1 -0
  70. package/package.json +158 -125
@@ -0,0 +1,369 @@
1
+ import { j as e } from "../_virtual/jsx-runtime.js";
2
+ import { memo as q, useState as c, useRef as H, useCallback as l, useEffect as J, useMemo as k } from "react";
3
+ import { createPortal as Q } from "react-dom";
4
+ import { cn as X } from "../utils/cn.js";
5
+ import { getResponsiveClasses as Y, RESPONSIVE_SIZE_MAPS as ee } from "../utils/responsive.js";
6
+ const te = {
7
+ openDuration: 50,
8
+ closeDuration: 350,
9
+ cyberpunkEffects: !0
10
+ }, ae = q(
11
+ ({
12
+ src: g,
13
+ alt: a,
14
+ size: w = "md",
15
+ preview: o = !0,
16
+ fallback: d,
17
+ placeholder: N,
18
+ className: E = "",
19
+ animation: _,
20
+ eager: p = !1,
21
+ previewClassName: K = "",
22
+ onPreviewOpen: $,
23
+ onPreviewClose: C,
24
+ onLoad: L,
25
+ onError: I,
26
+ ...y
27
+ }) => {
28
+ const n = { ...te, ..._ }, [u, D] = c(!1), [r, R] = c(!1), [x, P] = c(!1), [m, S] = c(!0), [s, h] = c(!1), [i, F] = c(!1), M = H(null), O = H(null), W = l(
29
+ (t) => Y(t, ee.card),
30
+ []
31
+ ), v = l(
32
+ (t) => {
33
+ S(!1), h(!1), L?.(t);
34
+ },
35
+ [L]
36
+ ), z = l(
37
+ (t) => {
38
+ S(!1), d && !i ? (F(!0), h(!1)) : h(!0), I?.(t);
39
+ },
40
+ [I, d, i]
41
+ ), f = l(() => {
42
+ o && !s && (P(!0), D(!0), $?.(), setTimeout(() => {
43
+ P(!1);
44
+ }, n.openDuration));
45
+ }, [o, s, $, n.openDuration]), b = l(() => {
46
+ R(!0), C?.(), setTimeout(() => {
47
+ D(!1), R(!1);
48
+ }, n.closeDuration);
49
+ }, [C, n.closeDuration]), T = l(
50
+ (t) => {
51
+ (t.target === M.current || t.target === t.currentTarget) && b();
52
+ },
53
+ [b]
54
+ ), j = l(
55
+ (t) => {
56
+ t.key === "Escape" && b();
57
+ },
58
+ [b]
59
+ );
60
+ J(() => {
61
+ if (u) {
62
+ document.addEventListener("keydown", j);
63
+ const t = document.body.style.overflow, B = document.documentElement.style.scrollbarGutter, V = document.body.style.paddingRight, Z = window.innerWidth - document.documentElement.clientWidth;
64
+ return document.body.style.overflow = "hidden", document.body.style.paddingRight = `${Z}px`, document.documentElement.style.scrollbarGutter = "auto", () => {
65
+ document.removeEventListener("keydown", j), document.body.style.overflow = t, document.body.style.paddingRight = V, document.documentElement.style.scrollbarGutter = B;
66
+ };
67
+ }
68
+ }, [u, j]);
69
+ const A = k(
70
+ () => X(
71
+ "relative rounded-lg overflow-hidden border-2 border-accent/30 transition-all duration-300 ease-in-out transform flex justify-center content-center",
72
+ o && !s ? "cursor-pointer hover:scale-105 hover:border-accent hover:shadow-lg-accent focus:outline-none focus:ring-4 focus:ring-accent/50" : "",
73
+ W(w),
74
+ E
75
+ ),
76
+ [o, s, W, w, E]
77
+ ), G = k(
78
+ () => ({
79
+ role: o ? "button" : "img",
80
+ tabIndex: o && !s ? 0 : -1,
81
+ "aria-label": o ? `${a}. Click to enlarge` : a,
82
+ "aria-expanded": o ? u : void 0,
83
+ onKeyDown: o && !s ? (t) => {
84
+ (t.key === "Enter" || t.key === " ") && (t.preventDefault(), f());
85
+ } : void 0
86
+ }),
87
+ [o, s, a, u, f]
88
+ ), U = k(
89
+ () => /* @__PURE__ */ e.jsxs(
90
+ "div",
91
+ {
92
+ className: A,
93
+ onClick: f,
94
+ ...G,
95
+ children: [
96
+ m && /* @__PURE__ */ e.jsx(
97
+ "div",
98
+ {
99
+ className: "absolute m-0 inset-0 flex items-center justify-center bg-surface border-2 border-accent/20",
100
+ role: "status",
101
+ "aria-label": "Loading image",
102
+ children: N || /* @__PURE__ */ e.jsx("div", { className: "animate-pulse bg-gradient-to-r from-accent/20 to-secondary/20 w-full h-full flex items-center justify-center", children: /* @__PURE__ */ e.jsx("div", { className: "text-muted text-sm", children: "Loading..." }) })
103
+ }
104
+ ),
105
+ s ? /* @__PURE__ */ e.jsx(
106
+ "div",
107
+ {
108
+ className: "flex items-center justify-center bg-surface border-2 border-error/30 text-error p-4 rounded-lg min-h-[100px]",
109
+ role: "alert",
110
+ "aria-label": "Failed to load image",
111
+ children: /* @__PURE__ */ e.jsxs("div", { className: "text-center", children: [
112
+ /* @__PURE__ */ e.jsx("div", { className: "text-2xl mb-2", "aria-hidden": "true", children: "⚠" }),
113
+ /* @__PURE__ */ e.jsx("div", { className: "text-sm", children: "Failed to load image" })
114
+ ] })
115
+ }
116
+ ) : i ? /* @__PURE__ */ e.jsx(
117
+ "img",
118
+ {
119
+ ref: O,
120
+ src: d,
121
+ alt: `${a} (fallback)`,
122
+ className: "w-full h-full m-0 object-cover transition-opacity duration-300",
123
+ style: { opacity: m ? 0 : 1 },
124
+ onLoad: v,
125
+ onError: () => {
126
+ h(!0), F(!1);
127
+ },
128
+ loading: p ? "eager" : "lazy",
129
+ decoding: "async",
130
+ ...y
131
+ }
132
+ ) : /* @__PURE__ */ e.jsx(
133
+ "img",
134
+ {
135
+ ref: O,
136
+ src: g,
137
+ alt: a,
138
+ className: "w-full h-full m-0 object-cover transition-opacity duration-300",
139
+ style: { opacity: m ? 0 : 1 },
140
+ onLoad: v,
141
+ onError: z,
142
+ loading: p ? "eager" : "lazy",
143
+ decoding: "async",
144
+ ...y
145
+ }
146
+ ),
147
+ o && !m && !s && /* @__PURE__ */ e.jsx(
148
+ "div",
149
+ {
150
+ className: "absolute inset-0 bg-black/0 hover:bg-black/20 transition-all duration-300 flex items-center justify-center opacity-0 hover:opacity-100",
151
+ "aria-hidden": "true",
152
+ children: /* @__PURE__ */ e.jsx("div", { className: "bg-accent/90 text-base px-3 py-1 rounded-md text-sm font-semibold tracking-wider uppercase", children: "Preview" })
153
+ }
154
+ )
155
+ ]
156
+ }
157
+ ),
158
+ [
159
+ A,
160
+ f,
161
+ G,
162
+ m,
163
+ N,
164
+ s,
165
+ i,
166
+ d,
167
+ a,
168
+ v,
169
+ p,
170
+ y,
171
+ g,
172
+ z,
173
+ o
174
+ ]
175
+ );
176
+ return /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
177
+ U,
178
+ u && Q(
179
+ /* @__PURE__ */ e.jsxs(
180
+ "div",
181
+ {
182
+ ref: M,
183
+ className: `fixed z-50 flex items-center justify-center p-4 transition-all ease-out ${K} ${r ? "bg-black/0 backdrop-blur-none opacity-0 duration-300" : x ? "bg-black/80 backdrop-blur-sm opacity-100 duration-500" : "bg-black/80 backdrop-blur-sm opacity-100 duration-300"}`,
184
+ style: {
185
+ top: 0,
186
+ left: 0,
187
+ width: "100vw",
188
+ height: "100vh",
189
+ maxWidth: "none"
190
+ },
191
+ onClick: T,
192
+ role: "dialog",
193
+ "aria-modal": "true",
194
+ "aria-label": `Preview: ${a}`,
195
+ children: [
196
+ n.cyberpunkEffects && /* @__PURE__ */ e.jsx(
197
+ "div",
198
+ {
199
+ className: `absolute transition-opacity duration-300 ${r ? "opacity-0" : "opacity-20"}`,
200
+ style: {
201
+ top: 0,
202
+ left: 0,
203
+ width: "100vw",
204
+ height: "100vh"
205
+ },
206
+ "aria-hidden": "true",
207
+ children: /* @__PURE__ */ e.jsx(
208
+ "div",
209
+ {
210
+ className: "absolute",
211
+ style: {
212
+ top: 0,
213
+ left: 0,
214
+ width: "100vw",
215
+ height: "100vh",
216
+ backgroundImage: `
217
+ linear-gradient(rgba(0, 255, 136, 0.3) 1px, transparent 1px),
218
+ linear-gradient(90deg, rgba(0, 255, 136, 0.3) 1px, transparent 1px)
219
+ `,
220
+ backgroundSize: "40px 40px"
221
+ }
222
+ }
223
+ )
224
+ }
225
+ ),
226
+ /* @__PURE__ */ e.jsxs(
227
+ "div",
228
+ {
229
+ className: "relative w-full h-full flex items-center justify-center",
230
+ onClick: T,
231
+ children: [
232
+ /* @__PURE__ */ e.jsx(
233
+ "button",
234
+ {
235
+ onClick: b,
236
+ className: `absolute top-4 right-4 text-white hover:text-accent/80 transition-all duration-300 font-bold z-20 rounded-full w-10 h-10 flex items-center justify-center cursor-pointer transform ${r ? "bg-black/0 scale-50 rotate-180 opacity-0" : x ? "bg-black/50 scale-0 rotate-0 opacity-0 duration-500" : "bg-black/50 hover:bg-accent/20 scale-100 rotate-0 opacity-100 hover:scale-110"}`,
237
+ style: { lineHeight: "1" },
238
+ children: /* @__PURE__ */ e.jsxs(
239
+ "svg",
240
+ {
241
+ width: "16",
242
+ height: "16",
243
+ viewBox: "0 0 16 16",
244
+ fill: "none",
245
+ className: "relative",
246
+ children: [
247
+ /* @__PURE__ */ e.jsx(
248
+ "path",
249
+ {
250
+ d: "M12 4L4 12M4 4L12 12",
251
+ stroke: "currentColor",
252
+ strokeWidth: "2",
253
+ strokeLinecap: "round",
254
+ strokeLinejoin: "round"
255
+ }
256
+ ),
257
+ /* @__PURE__ */ e.jsx(
258
+ "path",
259
+ {
260
+ d: "M12 4L4 12M4 4L12 12",
261
+ stroke: "currentColor",
262
+ strokeWidth: "2",
263
+ strokeLinecap: "round",
264
+ strokeLinejoin: "round",
265
+ className: "absolute inset-0 text-accent opacity-0 hover:opacity-100 transition-opacity duration-200 animate-pulse"
266
+ }
267
+ )
268
+ ]
269
+ }
270
+ )
271
+ }
272
+ ),
273
+ /* @__PURE__ */ e.jsxs(
274
+ "div",
275
+ {
276
+ className: `relative max-w-full max-h-full flex items-center justify-center transition-all ease-out ${r ? "scale-75 opacity-0 rotate-1 duration-300" : x ? "scale-95 opacity-0 rotate-0 duration-500" : "scale-100 opacity-100 rotate-0 duration-300"}`,
277
+ onClick: (t) => t.stopPropagation(),
278
+ children: [
279
+ n.cyberpunkEffects && /* @__PURE__ */ e.jsx(
280
+ "div",
281
+ {
282
+ className: `absolute inset-0 rounded-lg border-2 transition-all duration-300 ${r ? "border-transparent shadow-none" : "border-accent shadow-lg-accent animate-pulse"}`,
283
+ "aria-hidden": "true"
284
+ }
285
+ ),
286
+ n.cyberpunkEffects && /* @__PURE__ */ e.jsx(
287
+ "div",
288
+ {
289
+ className: `absolute inset-0 overflow-hidden rounded-lg transition-opacity duration-300 z-10 ${r ? "opacity-0" : "opacity-100"}`,
290
+ "aria-hidden": "true",
291
+ children: /* @__PURE__ */ e.jsxs("div", { className: "absolute top-0 left-0 w-full h-px animate-scan opacity-20", children: [
292
+ /* @__PURE__ */ e.jsx("div", { className: "w-full h-full bg-gradient-to-r from-transparent via-accent to-transparent shadow-lg-accent opacity-80" }),
293
+ /* @__PURE__ */ e.jsx("div", { className: "absolute inset-0 w-full h-full bg-gradient-to-r from-transparent via-white to-transparent opacity-60" })
294
+ ] })
295
+ }
296
+ ),
297
+ /* @__PURE__ */ e.jsx(
298
+ "img",
299
+ {
300
+ src: i ? d : g,
301
+ alt: i ? `${a} (fallback)` : a,
302
+ className: `max-w-[95vw] max-h-[95vh] w-auto h-auto object-contain rounded-lg transition-all duration-300 ease-out ${r ? "filter blur-sm brightness-50" : "filter blur-0 brightness-100"}`,
303
+ style: {
304
+ maxWidth: "95vw",
305
+ maxHeight: "95vh",
306
+ width: "auto",
307
+ height: "auto"
308
+ }
309
+ }
310
+ ),
311
+ /* @__PURE__ */ e.jsx(
312
+ "div",
313
+ {
314
+ className: `absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/80 via-black/40 to-transparent p-3 rounded-b-lg transition-all duration-300 ${r ? "translate-y-4 opacity-0" : "translate-y-0 opacity-100"}`,
315
+ children: /* @__PURE__ */ e.jsxs("p", { className: "text-white text-sm font-medium truncate relative", children: [
316
+ i ? `${a} (fallback)` : a,
317
+ n.cyberpunkEffects && /* @__PURE__ */ e.jsx("span", { className: "absolute inset-0 text-accent opacity-20 animate-pulse", children: i ? `${a} (fallback)` : a })
318
+ ] })
319
+ }
320
+ ),
321
+ n.cyberpunkEffects && /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
322
+ /* @__PURE__ */ e.jsx(
323
+ "div",
324
+ {
325
+ className: `absolute top-2 left-2 w-4 h-4 border-l-2 border-t-2 border-accent transition-all duration-300 ${r ? "opacity-0 scale-0" : "opacity-60 scale-100"}`,
326
+ "aria-hidden": "true"
327
+ }
328
+ ),
329
+ /* @__PURE__ */ e.jsx(
330
+ "div",
331
+ {
332
+ className: `absolute top-2 right-2 w-4 h-4 border-r-2 border-t-2 border-accent transition-all duration-300 ${r ? "opacity-0 scale-0" : "opacity-60 scale-100"}`,
333
+ "aria-hidden": "true"
334
+ }
335
+ ),
336
+ /* @__PURE__ */ e.jsx(
337
+ "div",
338
+ {
339
+ className: `absolute bottom-2 left-2 w-4 h-4 border-l-2 border-b-2 border-accent transition-all duration-300 ${r ? "opacity-0 scale-0" : "opacity-60 scale-100"}`,
340
+ "aria-hidden": "true"
341
+ }
342
+ ),
343
+ /* @__PURE__ */ e.jsx(
344
+ "div",
345
+ {
346
+ className: `absolute bottom-2 right-2 w-4 h-4 border-r-2 border-b-2 border-accent transition-all duration-300 ${r ? "opacity-0 scale-0" : "opacity-60 scale-100"}`,
347
+ "aria-hidden": "true"
348
+ }
349
+ )
350
+ ] })
351
+ ]
352
+ }
353
+ )
354
+ ]
355
+ }
356
+ )
357
+ ]
358
+ }
359
+ ),
360
+ document.body
361
+ )
362
+ ] });
363
+ }
364
+ );
365
+ ae.displayName = "CyberUI.Image";
366
+ export {
367
+ ae as default
368
+ };
369
+ //# sourceMappingURL=Image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Image.js","sources":["../../src/components/Image.tsx"],"sourcesContent":["import React, {\r\n useState,\r\n useEffect,\r\n useRef,\r\n useCallback,\r\n memo,\r\n useMemo,\r\n} from \"react\";\r\nimport { createPortal } from \"react-dom\";\r\nimport { cn } from \"../utils/cn\";\r\nimport type { ResponsiveValue } from \"../utils/responsive\";\r\nimport {\r\n getResponsiveClasses,\r\n RESPONSIVE_SIZE_MAPS,\r\n} from \"../utils/responsive\";\r\n\r\n/**\r\n * Size options for the Image component\r\n */\r\nexport type ImageSize = \"sm\" | \"md\" | \"lg\";\r\n\r\n/**\r\n * Animation configuration for preview transitions\r\n */\r\nexport interface ImageAnimationConfig {\r\n /** Duration of opening animation in milliseconds */\r\n openDuration?: number;\r\n /** Duration of closing animation in milliseconds */\r\n closeDuration?: number;\r\n /** Enable/disable cyberpunk effects */\r\n cyberpunkEffects?: boolean;\r\n}\r\n\r\n/**\r\n * Callback functions for Image component events\r\n */\r\nexport interface ImageCallbacks {\r\n /** Fired when preview opens */\r\n onPreviewOpen?: () => void;\r\n /** Fired when preview closes */\r\n onPreviewClose?: () => void;\r\n /** Fired when image loads successfully */\r\n onLoad?: (event: React.SyntheticEvent<HTMLImageElement>) => void;\r\n /** Fired when image fails to load */\r\n onError?: (event: React.SyntheticEvent<HTMLImageElement>) => void;\r\n}\r\n\r\n\r\n/**\r\n * Props for the CyberUI Image component\r\n *\r\n * @example\r\n * // Basic image with preview\r\n * <Image\r\n * src=\"/cyber-city.jpg\"\r\n * alt=\"Cyberpunk cityscape\"\r\n * size=\"lg\"\r\n * />\r\n *\r\n * @example\r\n * // Image with fallback and custom animation\r\n * <Image\r\n * src={src}\r\n * alt=\"Avatar\"\r\n * fallback=\"/default-avatar.png\"\r\n * animation={{ cyberpunkEffects: false }}\r\n * />\r\n */\r\nexport interface ImageProps\r\n extends Omit<\r\n React.ImgHTMLAttributes<HTMLImageElement>,\r\n \"size\" | \"onLoad\" | \"onError\"\r\n >,\r\n ImageCallbacks {\r\n /** Image source URL (required) */\r\n src: string;\r\n /** Alternative text for accessibility (required) */\r\n alt: string;\r\n /** Size of the image container */\r\n size?: ResponsiveValue<ImageSize>;\r\n /**\r\n * Enable click-to-expand fullscreen preview on click.\r\n * Must be explicitly set to `true` — disabled by default.\r\n * @default false\r\n */\r\n preview?: boolean;\r\n /** Fallback image URL when main image fails to load */\r\n fallback?: string;\r\n /** Custom loading placeholder component */\r\n placeholder?: React.ReactNode;\r\n /** Additional CSS classes */\r\n className?: string;\r\n /** Animation configuration */\r\n animation?: ImageAnimationConfig;\r\n /** Disable lazy loading (images load immediately) */\r\n eager?: boolean;\r\n /** Custom preview container styles */\r\n previewClassName?: string;\r\n}\r\n\r\n/**\r\n * Default animation configuration\r\n */\r\nconst DEFAULT_ANIMATION: Required<ImageAnimationConfig> = {\r\n openDuration: 50,\r\n closeDuration: 350,\r\n cyberpunkEffects: true,\r\n};\r\n\r\n/**\r\n * CyberUI Image Component\r\n *\r\n * A cyberpunk-themed image component with click-to-expand preview functionality,\r\n * loading states, error handling, and smooth animations.\r\n *\r\n * @example\r\n * ```tsx\r\n * <Image\r\n * src=\"/cyber-city.jpg\"\r\n * alt=\"Cyberpunk cityscape\"\r\n * size=\"lg\"\r\n * onPreviewOpen={() => console.log('Preview opened')}\r\n * />\r\n * ```\r\n */\r\nconst Image: React.FC<ImageProps> = memo(\r\n ({\r\n src,\r\n alt,\r\n size = \"md\",\r\n preview = true,\r\n fallback,\r\n placeholder,\r\n className = \"\",\r\n animation,\r\n eager = false,\r\n previewClassName = \"\",\r\n onPreviewOpen,\r\n onPreviewClose,\r\n onLoad,\r\n onError,\r\n ...props\r\n }) => {\r\n // Animation configuration with defaults\r\n const animationConfig = { ...DEFAULT_ANIMATION, ...animation };\r\n\r\n // Component state\r\n const [isPreviewOpen, setIsPreviewOpen] = useState(false);\r\n const [isClosing, setIsClosing] = useState(false);\r\n const [isOpening, setIsOpening] = useState(false);\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [hasError, setHasError] = useState(false);\r\n const [showFallback, setShowFallback] = useState(false);\r\n\r\n // Refs\r\n const overlayRef = useRef<HTMLDivElement>(null);\r\n const imageRef = useRef<HTMLImageElement>(null);\r\n\r\n // Memoized size classes calculation\r\n const getSizeClasses = useCallback(\r\n (size: ResponsiveValue<ImageSize>): string => {\r\n return getResponsiveClasses(size, RESPONSIVE_SIZE_MAPS.card);\r\n },\r\n []\r\n );\r\n\r\n // Image event handlers with callbacks\r\n const handleImageLoad = useCallback(\r\n (event: React.SyntheticEvent<HTMLImageElement>) => {\r\n setIsLoading(false);\r\n setHasError(false);\r\n onLoad?.(event);\r\n },\r\n [onLoad]\r\n );\r\n\r\n const handleImageError = useCallback(\r\n (event: React.SyntheticEvent<HTMLImageElement>) => {\r\n setIsLoading(false);\r\n if (fallback && !showFallback) {\r\n // Show fallback instead of error\r\n setShowFallback(true);\r\n setHasError(false);\r\n } else {\r\n // No fallback or fallback also failed\r\n setHasError(true);\r\n }\r\n onError?.(event);\r\n },\r\n [onError, fallback, showFallback]\r\n );\r\n\r\n // Preview controls\r\n const handleImageClick = useCallback(() => {\r\n if (preview && !hasError) {\r\n setIsOpening(true);\r\n setIsPreviewOpen(true);\r\n onPreviewOpen?.();\r\n\r\n setTimeout(() => {\r\n setIsOpening(false);\r\n }, animationConfig.openDuration);\r\n }\r\n }, [preview, hasError, onPreviewOpen, animationConfig.openDuration]);\r\n\r\n const closePreview = useCallback(() => {\r\n setIsClosing(true);\r\n onPreviewClose?.();\r\n\r\n setTimeout(() => {\r\n setIsPreviewOpen(false);\r\n setIsClosing(false);\r\n }, animationConfig.closeDuration);\r\n }, [onPreviewClose, animationConfig.closeDuration]);\r\n\r\n // Event handlers for preview overlay\r\n const handleOverlayClick = useCallback(\r\n (e: React.MouseEvent) => {\r\n if (e.target === overlayRef.current || e.target === e.currentTarget) {\r\n closePreview();\r\n }\r\n },\r\n [closePreview]\r\n );\r\n\r\n const handleKeyDown = useCallback(\r\n (e: KeyboardEvent) => {\r\n if (e.key === \"Escape\") {\r\n closePreview();\r\n }\r\n },\r\n [closePreview]\r\n );\r\n\r\n useEffect(() => {\r\n if (isPreviewOpen) {\r\n document.addEventListener(\"keydown\", handleKeyDown);\r\n\r\n // Store original values\r\n const originalOverflow = document.body.style.overflow;\r\n const originalScrollbarGutter =\r\n document.documentElement.style.scrollbarGutter;\r\n const originalPaddingRight = document.body.style.paddingRight;\r\n\r\n // Calculate scrollbar width to compensate\r\n const scrollbarWidth =\r\n window.innerWidth - document.documentElement.clientWidth;\r\n\r\n // Apply changes smoothly\r\n document.body.style.overflow = \"hidden\";\r\n document.body.style.paddingRight = `${scrollbarWidth}px`;\r\n document.documentElement.style.scrollbarGutter = \"auto\";\r\n\r\n return () => {\r\n document.removeEventListener(\"keydown\", handleKeyDown);\r\n // Always restore original values immediately to prevent page freeze\r\n document.body.style.overflow = originalOverflow;\r\n document.body.style.paddingRight = originalPaddingRight;\r\n document.documentElement.style.scrollbarGutter = originalScrollbarGutter;\r\n };\r\n }\r\n }, [isPreviewOpen, handleKeyDown]);\r\n\r\n // Memoized class calculations\r\n const imageClasses = useMemo(\r\n () =>\r\n cn(\r\n \"relative rounded-lg overflow-hidden border-2 border-accent/30 transition-all duration-300 ease-in-out transform flex justify-center content-center\",\r\n preview && !hasError\r\n ? \"cursor-pointer hover:scale-105 hover:border-accent hover:shadow-lg-accent focus:outline-none focus:ring-4 focus:ring-accent/50\"\r\n : \"\",\r\n getSizeClasses(size),\r\n className\r\n ),\r\n [preview, hasError, getSizeClasses, size, className]\r\n );\r\n\r\n // Accessibility attributes\r\n const accessibilityProps = useMemo(\r\n () => ({\r\n role: preview ? \"button\" : \"img\",\r\n tabIndex: preview && !hasError ? 0 : -1,\r\n \"aria-label\": preview ? `${alt}. Click to enlarge` : alt,\r\n \"aria-expanded\": preview ? isPreviewOpen : undefined,\r\n onKeyDown:\r\n preview && !hasError\r\n ? (e: React.KeyboardEvent) => {\r\n if (e.key === \"Enter\" || e.key === \" \") {\r\n e.preventDefault();\r\n handleImageClick();\r\n }\r\n }\r\n : undefined,\r\n }),\r\n [preview, hasError, alt, isPreviewOpen, handleImageClick]\r\n );\r\n\r\n // Main image element with enhanced accessibility and error handling\r\n const imageElement = useMemo(\r\n () => (\r\n <div\r\n className={imageClasses}\r\n onClick={handleImageClick}\r\n {...accessibilityProps}\r\n >\r\n {/* Loading State */}\r\n {isLoading && (\r\n <div\r\n className=\"absolute m-0 inset-0 flex items-center justify-center bg-surface border-2 border-accent/20\"\r\n role=\"status\"\r\n aria-label=\"Loading image\"\r\n >\r\n {placeholder || (\r\n <div className=\"animate-pulse bg-gradient-to-r from-accent/20 to-secondary/20 w-full h-full flex items-center justify-center\">\r\n <div className=\"text-muted text-sm\">Loading...</div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Error State */}\r\n {hasError ? (\r\n <div\r\n className=\"flex items-center justify-center bg-surface border-2 border-error/30 text-error p-4 rounded-lg min-h-[100px]\"\r\n role=\"alert\"\r\n aria-label=\"Failed to load image\"\r\n >\r\n <div className=\"text-center\">\r\n <div className=\"text-2xl mb-2\" aria-hidden=\"true\">\r\n ⚠\r\n </div>\r\n <div className=\"text-sm\">Failed to load image</div>\r\n </div>\r\n </div>\r\n ) : showFallback ? (\r\n <img\r\n ref={imageRef}\r\n src={fallback}\r\n alt={`${alt} (fallback)`}\r\n className=\"w-full h-full m-0 object-cover transition-opacity duration-300\"\r\n style={{ opacity: isLoading ? 0 : 1 }}\r\n onLoad={handleImageLoad}\r\n onError={() => {\r\n setHasError(true);\r\n setShowFallback(false);\r\n }}\r\n loading={eager ? \"eager\" : \"lazy\"}\r\n decoding=\"async\"\r\n {...props}\r\n />\r\n ) : (\r\n <img\r\n ref={imageRef}\r\n src={src}\r\n alt={alt}\r\n className=\"w-full h-full m-0 object-cover transition-opacity duration-300\"\r\n style={{ opacity: isLoading ? 0 : 1 }}\r\n onLoad={handleImageLoad}\r\n onError={handleImageError}\r\n loading={eager ? \"eager\" : \"lazy\"}\r\n decoding=\"async\"\r\n {...props}\r\n />\r\n )}\r\n\r\n {/* Preview Overlay */}\r\n {preview && !isLoading && !hasError && (\r\n <div\r\n className=\"absolute inset-0 bg-black/0 hover:bg-black/20 transition-all duration-300 flex items-center justify-center opacity-0 hover:opacity-100\"\r\n aria-hidden=\"true\"\r\n >\r\n <div className=\"bg-accent/90 text-base px-3 py-1 rounded-md text-sm font-semibold tracking-wider uppercase\">\r\n Preview\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n ),\r\n [\r\n imageClasses,\r\n handleImageClick,\r\n accessibilityProps,\r\n isLoading,\r\n placeholder,\r\n hasError,\r\n showFallback,\r\n fallback,\r\n alt,\r\n handleImageLoad,\r\n eager,\r\n props,\r\n src,\r\n handleImageError,\r\n preview,\r\n ]\r\n );\r\n\r\n return (\r\n <>\r\n {imageElement}\r\n\r\n {/* Preview Overlay */}\r\n {isPreviewOpen && createPortal(\r\n <div\r\n ref={overlayRef}\r\n className={`fixed z-50 flex items-center justify-center p-4 transition-all ease-out ${previewClassName} ${\r\n isClosing\r\n ? \"bg-black/0 backdrop-blur-none opacity-0 duration-300\"\r\n : isOpening\r\n ? \"bg-black/80 backdrop-blur-sm opacity-100 duration-500\"\r\n : \"bg-black/80 backdrop-blur-sm opacity-100 duration-300\"\r\n }`}\r\n style={{\r\n top: 0,\r\n left: 0,\r\n width: \"100vw\",\r\n height: \"100vh\",\r\n maxWidth: \"none\",\r\n }}\r\n onClick={handleOverlayClick}\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n aria-label={`Preview: ${alt}`}\r\n >\r\n {/* Cyberpunk Grid Background */}\r\n {animationConfig.cyberpunkEffects && (\r\n <div\r\n className={`absolute transition-opacity duration-300 ${\r\n isClosing ? \"opacity-0\" : \"opacity-20\"\r\n }`}\r\n style={{\r\n top: 0,\r\n left: 0,\r\n width: \"100vw\",\r\n height: \"100vh\",\r\n }}\r\n aria-hidden=\"true\"\r\n >\r\n <div\r\n className=\"absolute\"\r\n style={{\r\n top: 0,\r\n left: 0,\r\n width: \"100vw\",\r\n height: \"100vh\",\r\n backgroundImage: `\r\n linear-gradient(rgba(0, 255, 136, 0.3) 1px, transparent 1px),\r\n linear-gradient(90deg, rgba(0, 255, 136, 0.3) 1px, transparent 1px)\r\n `,\r\n backgroundSize: \"40px 40px\",\r\n }}\r\n />\r\n </div>\r\n )}\r\n\r\n <div\r\n className=\"relative w-full h-full flex items-center justify-center\"\r\n onClick={handleOverlayClick}\r\n >\r\n {/* Animated Close Button */}\r\n <button\r\n onClick={closePreview}\r\n className={`absolute top-4 right-4 text-white hover:text-accent/80 transition-all duration-300 font-bold z-20 rounded-full w-10 h-10 flex items-center justify-center cursor-pointer transform ${\r\n isClosing\r\n ? \"bg-black/0 scale-50 rotate-180 opacity-0\"\r\n : isOpening\r\n ? \"bg-black/50 scale-0 rotate-0 opacity-0 duration-500\"\r\n : \"bg-black/50 hover:bg-accent/20 scale-100 rotate-0 opacity-100 hover:scale-110\"\r\n }`}\r\n style={{ lineHeight: \"1\" }}\r\n >\r\n <svg\r\n width=\"16\"\r\n height=\"16\"\r\n viewBox=\"0 0 16 16\"\r\n fill=\"none\"\r\n className=\"relative\"\r\n >\r\n <path\r\n d=\"M12 4L4 12M4 4L12 12\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n />\r\n <path\r\n d=\"M12 4L4 12M4 4L12 12\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n className=\"absolute inset-0 text-accent opacity-0 hover:opacity-100 transition-opacity duration-200 animate-pulse\"\r\n />\r\n </svg>\r\n </button>\r\n\r\n {/* Main Image Container */}\r\n <div\r\n className={`relative max-w-full max-h-full flex items-center justify-center transition-all ease-out ${\r\n isClosing\r\n ? \"scale-75 opacity-0 rotate-1 duration-300\"\r\n : isOpening\r\n ? \"scale-95 opacity-0 rotate-0 duration-500\"\r\n : \"scale-100 opacity-100 rotate-0 duration-300\"\r\n }`}\r\n onClick={(e) => e.stopPropagation()}\r\n >\r\n {/* Glitch Effect Border */}\r\n {animationConfig.cyberpunkEffects && (\r\n <div\r\n className={`absolute inset-0 rounded-lg border-2 transition-all duration-300 ${\r\n isClosing\r\n ? \"border-transparent shadow-none\"\r\n : \"border-accent shadow-lg-accent animate-pulse\"\r\n }`}\r\n aria-hidden=\"true\"\r\n />\r\n )}\r\n\r\n {/* Scanning Line Effect */}\r\n {animationConfig.cyberpunkEffects && (\r\n <div\r\n className={`absolute inset-0 overflow-hidden rounded-lg transition-opacity duration-300 z-10 ${\r\n isClosing ? \"opacity-0\" : \"opacity-100\"\r\n }`}\r\n aria-hidden=\"true\"\r\n >\r\n <div className=\"absolute top-0 left-0 w-full h-px animate-scan opacity-20\">\r\n <div className=\"w-full h-full bg-gradient-to-r from-transparent via-accent to-transparent shadow-lg-accent opacity-80\"></div>\r\n <div className=\"absolute inset-0 w-full h-full bg-gradient-to-r from-transparent via-white to-transparent opacity-60\"></div>\r\n </div>\r\n </div>\r\n )}\r\n\r\n <img\r\n src={showFallback ? fallback : src}\r\n alt={showFallback ? `${alt} (fallback)` : alt}\r\n className={`max-w-[95vw] max-h-[95vh] w-auto h-auto object-contain rounded-lg transition-all duration-300 ease-out ${\r\n isClosing\r\n ? \"filter blur-sm brightness-50\"\r\n : \"filter blur-0 brightness-100\"\r\n }`}\r\n style={{\r\n maxWidth: \"95vw\",\r\n maxHeight: \"95vh\",\r\n width: \"auto\",\r\n height: \"auto\",\r\n }}\r\n />\r\n\r\n {/* Caption with Cyber Effect */}\r\n <div\r\n className={`absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/80 via-black/40 to-transparent p-3 rounded-b-lg transition-all duration-300 ${\r\n isClosing\r\n ? \"translate-y-4 opacity-0\"\r\n : \"translate-y-0 opacity-100\"\r\n }`}\r\n >\r\n <p className=\"text-white text-sm font-medium truncate relative\">\r\n {showFallback ? `${alt} (fallback)` : alt}\r\n {animationConfig.cyberpunkEffects && (\r\n <span className=\"absolute inset-0 text-accent opacity-20 animate-pulse\">\r\n {showFallback ? `${alt} (fallback)` : alt}\r\n </span>\r\n )}\r\n </p>\r\n </div>\r\n\r\n {/* Corner Accents */}\r\n {animationConfig.cyberpunkEffects && (\r\n <>\r\n <div\r\n className={`absolute top-2 left-2 w-4 h-4 border-l-2 border-t-2 border-accent transition-all duration-300 ${\r\n isClosing ? \"opacity-0 scale-0\" : \"opacity-60 scale-100\"\r\n }`}\r\n aria-hidden=\"true\"\r\n />\r\n <div\r\n className={`absolute top-2 right-2 w-4 h-4 border-r-2 border-t-2 border-accent transition-all duration-300 ${\r\n isClosing ? \"opacity-0 scale-0\" : \"opacity-60 scale-100\"\r\n }`}\r\n aria-hidden=\"true\"\r\n />\r\n <div\r\n className={`absolute bottom-2 left-2 w-4 h-4 border-l-2 border-b-2 border-accent transition-all duration-300 ${\r\n isClosing ? \"opacity-0 scale-0\" : \"opacity-60 scale-100\"\r\n }`}\r\n aria-hidden=\"true\"\r\n />\r\n <div\r\n className={`absolute bottom-2 right-2 w-4 h-4 border-r-2 border-b-2 border-accent transition-all duration-300 ${\r\n isClosing ? \"opacity-0 scale-0\" : \"opacity-60 scale-100\"\r\n }`}\r\n aria-hidden=\"true\"\r\n />\r\n </>\r\n )}\r\n </div>\r\n </div>\r\n </div>,\r\n document.body\r\n )}\r\n </>\r\n );\r\n }\r\n);\r\n\r\n// Set display name for debugging\r\nImage.displayName = \"CyberUI.Image\";\r\n\r\nexport default Image;\r\n"],"names":["DEFAULT_ANIMATION","Image","memo","src","alt","size","preview","fallback","placeholder","className","animation","eager","previewClassName","onPreviewOpen","onPreviewClose","onLoad","onError","props","animationConfig","isPreviewOpen","setIsPreviewOpen","useState","isClosing","setIsClosing","isOpening","setIsOpening","isLoading","setIsLoading","hasError","setHasError","showFallback","setShowFallback","overlayRef","useRef","imageRef","getSizeClasses","useCallback","getResponsiveClasses","RESPONSIVE_SIZE_MAPS","handleImageLoad","event","handleImageError","handleImageClick","closePreview","handleOverlayClick","e","handleKeyDown","useEffect","originalOverflow","originalScrollbarGutter","originalPaddingRight","scrollbarWidth","imageClasses","useMemo","cn","accessibilityProps","imageElement","jsxs","jsx","Fragment","createPortal"],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import { j as o } from "../_virtual/jsx-runtime.js";
2
+ import { useId as j } from "react";
3
+ import { getResponsiveClasses as N, RESPONSIVE_SIZE_MAPS as S } from "../utils/responsive.js";
4
+ import { cn as E } from "../utils/cn.js";
5
+ const I = ({
6
+ variant: i = "primary",
7
+ size: f = "md",
8
+ label: l,
9
+ helperText: d,
10
+ error: e,
11
+ leftIcon: t,
12
+ rightIcon: n,
13
+ className: m = "",
14
+ disabled: c = !1,
15
+ ...u
16
+ }) => {
17
+ const h = j(), a = u.id || h, g = [
18
+ "w-full",
19
+ "rounded-lg",
20
+ "bg-surface",
21
+ "text-default",
22
+ "placeholder-muted",
23
+ "transition-all",
24
+ "duration-300",
25
+ "focus:outline-none",
26
+ c ? "cursor-not-allowed opacity-60" : "cursor-text"
27
+ ].join(" "), p = (r) => N(r, S.input), x = (r) => {
28
+ const s = p(r);
29
+ return t && n ? `pl-10 pr-10 ${s}` : t ? `pl-10 pr-4 ${s}` : n ? `pl-4 pr-10 ${s}` : `px-4 ${s}`;
30
+ }, y = (r, s, $) => s ? "border-2 border-error shadow-error/30 hover:shadow-error focus:ring-2 focus:ring-error focus:shadow-error active:bg-base" : $ ? {
31
+ primary: "border-2 border-accent/20 shadow-none",
32
+ secondary: "border-2 border-secondary/20 shadow-none",
33
+ danger: "border-2 border-error/20 shadow-none",
34
+ ghost: "border border-border-default shadow-none"
35
+ }[r] : {
36
+ primary: "border-2 border-accent shadow-input-accent hover:shadow-lg-accent focus:ring-2 focus:ring-accent focus:shadow-lg-accent active:bg-base",
37
+ secondary: "border-2 border-secondary shadow-secondary/30 hover:shadow-secondary focus:ring-2 focus:ring-secondary focus:shadow-secondary active:bg-base",
38
+ danger: "border-2 border-error shadow-error/30 hover:shadow-error focus:ring-2 focus:ring-error focus:shadow-error active:bg-base",
39
+ ghost: "border border-border-default shadow-none hover:border-accent focus:ring-2 focus:ring-accent focus:border-accent active:bg-base"
40
+ }[r], v = (r) => ({
41
+ primary: "text-accent",
42
+ secondary: "text-secondary",
43
+ danger: "text-error",
44
+ ghost: "text-muted"
45
+ })[r], w = E(g, x(f), y(i, !!e, c), m), b = v(i), C = e ? `${a}-error` : d ? `${a}-help` : void 0;
46
+ return /* @__PURE__ */ o.jsxs("div", { className: "space-y-2", children: [
47
+ l && /* @__PURE__ */ o.jsx("label", { htmlFor: a, className: "block text-sm font-medium text-default", children: l }),
48
+ /* @__PURE__ */ o.jsxs("div", { className: "relative", children: [
49
+ t && /* @__PURE__ */ o.jsx("div", { className: `absolute inset-y-0 left-0 flex items-center pl-3 ${b}`, children: t }),
50
+ /* @__PURE__ */ o.jsx(
51
+ "input",
52
+ {
53
+ className: w,
54
+ disabled: c,
55
+ id: a,
56
+ "aria-invalid": !!e,
57
+ "aria-describedby": C,
58
+ ...u
59
+ }
60
+ ),
61
+ n && /* @__PURE__ */ o.jsx("div", { className: `absolute inset-y-0 right-0 flex items-center pr-3 ${b}`, children: n })
62
+ ] }),
63
+ (d || e) && /* @__PURE__ */ o.jsx("div", { id: e ? `${a}-error` : `${a}-help`, className: `text-xs font-mono ${e ? "text-error" : "text-muted"}`, children: e || d })
64
+ ] });
65
+ };
66
+ I.displayName = "CyberUI.Input";
67
+ export {
68
+ I as default
69
+ };
70
+ //# sourceMappingURL=Input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Input.js","sources":["../../src/components/Input.tsx"],"sourcesContent":["import React, { useId } from 'react';\r\nimport type { ResponsiveValue } from '../utils/responsive';\r\nimport { getResponsiveClasses, RESPONSIVE_SIZE_MAPS } from '../utils/responsive';\r\nimport { cn } from '../utils/cn';\r\n\r\n/**\r\n * A cyberpunk-styled text input field.\r\n *\r\n * @example\r\n * // Basic input with label\r\n * <Input label=\"Username\" placeholder=\"Enter alias...\" />\r\n *\r\n * @example\r\n * // Input with error state and icon\r\n * <Input\r\n * label=\"Password\"\r\n * type=\"password\"\r\n * error=\"Invalid credentials\"\r\n * leftIcon={<LockIcon />}\r\n * />\r\n */\r\nexport interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\r\n /**\r\n * Visual style of the input.\r\n * @default 'primary'\r\n */\r\n variant?: 'primary' | 'secondary' | 'danger' | 'ghost';\r\n /**\r\n * Size of the input (height and padding).\r\n * @default 'md'\r\n */\r\n size?: ResponsiveValue<'sm' | 'md' | 'lg'>;\r\n /** Label for the input */\r\n label?: string;\r\n /** Optional helper text shown below the input */\r\n helperText?: string;\r\n /** Error message that overrides helper text and highlights the input */\r\n error?: string;\r\n /** Icon to render on the left side of the input */\r\n leftIcon?: React.ReactNode;\r\n /** Icon to render on the right side of the input */\r\n rightIcon?: React.ReactNode;\r\n}\r\n\r\n/**\r\n * A highly customizable Cyberpunk input field with support for icons, labels, and error states.\r\n * \r\n * @example\r\n * <Input \r\n * label=\"Neural Key\" \r\n * placeholder=\"Enter bypass code\" \r\n * variant=\"primary\" \r\n * />\r\n * \r\n * @example\r\n * <Input \r\n * label=\"Data Port\" \r\n * error=\"Access Denied\" \r\n * leftIcon={<LockIcon />} \r\n * />\r\n */\r\nconst Input: React.FC<InputProps> = ({\r\n variant = 'primary',\r\n size = 'md',\r\n label,\r\n helperText,\r\n error,\r\n leftIcon,\r\n rightIcon,\r\n className = '',\r\n disabled = false,\r\n ...props\r\n}) => {\r\n const generatedId = useId();\r\n const inputId = (props as { id?: string }).id || generatedId;\r\n\r\n const baseClasses = [\r\n 'w-full',\r\n 'rounded-lg',\r\n 'bg-surface',\r\n 'text-default',\r\n 'placeholder-muted',\r\n 'transition-all',\r\n 'duration-300',\r\n 'focus:outline-none',\r\n disabled ? 'cursor-not-allowed opacity-60' : 'cursor-text'\r\n ].join(' ');\r\n\r\n const getSizeClasses = (size: ResponsiveValue<'sm' | 'md' | 'lg'>): string => {\r\n return getResponsiveClasses(size, RESPONSIVE_SIZE_MAPS.input);\r\n };\r\n\r\n const getPaddingClasses = (size: ResponsiveValue<'sm' | 'md' | 'lg'>): string => {\r\n const baseSizeClasses = getSizeClasses(size);\r\n\r\n if (leftIcon && rightIcon) return `pl-10 pr-10 ${baseSizeClasses}`;\r\n if (leftIcon) return `pl-10 pr-4 ${baseSizeClasses}`;\r\n if (rightIcon) return `pl-4 pr-10 ${baseSizeClasses}`;\r\n return `px-4 ${baseSizeClasses}`;\r\n };\r\n\r\n // Variant styles\r\n const getVariantClasses = (variant: string, hasError: boolean, disabled: boolean): string => {\r\n if (hasError) {\r\n return 'border-2 border-error shadow-error/30 hover:shadow-error focus:ring-2 focus:ring-error focus:shadow-error active:bg-base';\r\n }\r\n\r\n if (disabled) {\r\n const variants = {\r\n primary: 'border-2 border-accent/20 shadow-none',\r\n secondary: 'border-2 border-secondary/20 shadow-none',\r\n danger: 'border-2 border-error/20 shadow-none',\r\n ghost: 'border border-border-default shadow-none'\r\n };\r\n return variants[variant as keyof typeof variants];\r\n }\r\n\r\n const variants = {\r\n primary: 'border-2 border-accent shadow-input-accent hover:shadow-lg-accent focus:ring-2 focus:ring-accent focus:shadow-lg-accent active:bg-base',\r\n secondary: 'border-2 border-secondary shadow-secondary/30 hover:shadow-secondary focus:ring-2 focus:ring-secondary focus:shadow-secondary active:bg-base',\r\n danger: 'border-2 border-error shadow-error/30 hover:shadow-error focus:ring-2 focus:ring-error focus:shadow-error active:bg-base',\r\n ghost: 'border border-border-default shadow-none hover:border-accent focus:ring-2 focus:ring-accent focus:border-accent active:bg-base'\r\n };\r\n\r\n return variants[variant as keyof typeof variants];\r\n };\r\n\r\n // Icon color classes\r\n const getIconColorClass = (variant: string): string => {\r\n const colors = {\r\n primary: 'text-accent',\r\n secondary: 'text-secondary',\r\n danger: 'text-error',\r\n ghost: 'text-muted'\r\n };\r\n return colors[variant as keyof typeof colors];\r\n };\r\n\r\n const inputClasses = cn(baseClasses, getPaddingClasses(size), getVariantClasses(variant, !!error, disabled), className);\r\n\r\n const iconColorClass = getIconColorClass(variant);\r\n\r\n const describedById = error ? `${inputId}-error` : helperText ? `${inputId}-help` : undefined;\r\n\r\n return (\r\n <div className=\"space-y-2\">\r\n {/* Label */}\r\n {label && (\r\n <label htmlFor={inputId} className=\"block text-sm font-medium text-default\">\r\n {label}\r\n </label>\r\n )}\r\n\r\n {/* Input Container */}\r\n <div className=\"relative\">\r\n {/* Left Icon */}\r\n {leftIcon && (\r\n <div className={`absolute inset-y-0 left-0 flex items-center pl-3 ${iconColorClass}`}>\r\n {leftIcon}\r\n </div>\r\n )}\r\n\r\n {/* Input */}\r\n <input\r\n className={inputClasses}\r\n disabled={disabled}\r\n id={inputId}\r\n aria-invalid={!!error}\r\n aria-describedby={describedById}\r\n {...props}\r\n />\r\n\r\n {/* Right Icon */}\r\n {rightIcon && (\r\n <div className={`absolute inset-y-0 right-0 flex items-center pr-3 ${iconColorClass}`}>\r\n {rightIcon}\r\n </div>\r\n )}\r\n </div>\r\n\r\n {/* Helper Text or Error */}\r\n {(helperText || error) && (\r\n <div id={error ? `${inputId}-error` : `${inputId}-help`} className={`text-xs font-mono ${error ? 'text-error' : 'text-muted'}`}>\r\n {error || helperText}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nInput.displayName = \"CyberUI.Input\";\r\n\r\nexport default Input;\r\n"],"names":["Input","variant","size","label","helperText","error","leftIcon","rightIcon","className","disabled","props","generatedId","useId","inputId","baseClasses","getSizeClasses","getResponsiveClasses","RESPONSIVE_SIZE_MAPS","getPaddingClasses","baseSizeClasses","getVariantClasses","hasError","getIconColorClass","inputClasses","cn","iconColorClass","describedById","jsxs","jsx"],"mappings":";;;;AA6DA,MAAMA,IAA8B,CAAC;AAAA,EACnC,SAAAC,IAAU;AAAA,EACV,MAAAC,IAAO;AAAA,EACP,OAAAC;AAAA,EACA,YAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,UAAAC,IAAW;AAAA,EACX,GAAGC;AACL,MAAM;AACJ,QAAMC,IAAcC,EAAA,GACdC,IAAWH,EAA0B,MAAMC,GAE3CG,IAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACAL,IAAW,kCAAkC;AAAA,EAAA,EAC7C,KAAK,GAAG,GAEJM,IAAiB,CAACb,MACfc,EAAqBd,GAAMe,EAAqB,KAAK,GAGxDC,IAAoB,CAAChB,MAAsD;AAC/E,UAAMiB,IAAkBJ,EAAeb,CAAI;AAE3C,WAAII,KAAYC,IAAkB,eAAeY,CAAe,KAC5Db,IAAiB,cAAca,CAAe,KAC9CZ,IAAkB,cAAcY,CAAe,KAC5C,QAAQA,CAAe;AAAA,EAChC,GAGMC,IAAoB,CAACnB,GAAiBoB,GAAmBZ,MACzDY,IACK,6HAGLZ,IACe;AAAA,IACf,SAAS;AAAA,IACT,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,OAAO;AAAA,EAAA,EAEOR,CAAgC,IAGjC;AAAA,IACf,SAAS;AAAA,IACT,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,OAAO;AAAA,EAAA,EAGOA,CAAgC,GAI5CqB,IAAoB,CAACrB,OACV;AAAA,IACb,SAAS;AAAA,IACT,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,OAAO;AAAA,EAAA,GAEKA,CAA8B,GAGxCsB,IAAeC,EAAGV,GAAaI,EAAkBhB,CAAI,GAAGkB,EAAkBnB,GAAS,CAAC,CAACI,GAAOI,CAAQ,GAAGD,CAAS,GAEhHiB,IAAiBH,EAAkBrB,CAAO,GAE1CyB,IAAgBrB,IAAQ,GAAGQ,CAAO,WAAWT,IAAa,GAAGS,CAAO,UAAU;AAEpF,SACEc,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,aAEZ,UAAA;AAAA,IAAAxB,2BACE,SAAA,EAAM,SAASU,GAAS,WAAU,0CAChC,UAAAV,GACH;AAAA,IAIFwB,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAU,YAEZ,UAAA;AAAA,MAAArB,2BACE,OAAA,EAAI,WAAW,oDAAoDmB,CAAc,IAC/E,UAAAnB,GACH;AAAA,MAIFsB,gBAAAA,EAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAWL;AAAA,UACX,UAAAd;AAAA,UACA,IAAII;AAAA,UACJ,gBAAc,CAAC,CAACR;AAAA,UAChB,oBAAkBqB;AAAA,UACjB,GAAGhB;AAAA,QAAA;AAAA,MAAA;AAAA,MAILH,KACCqB,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAW,qDAAqDH,CAAc,IAChF,UAAAlB,EAAA,CACH;AAAA,IAAA,GAEJ;AAAA,KAGEH,KAAcC,MACduB,gBAAAA,EAAAA,IAAC,SAAI,IAAIvB,IAAQ,GAAGQ,CAAO,WAAW,GAAGA,CAAO,SAAS,WAAW,qBAAqBR,IAAQ,eAAe,YAAY,IACzH,eAASD,EAAA,CACZ;AAAA,EAAA,GAEJ;AAEJ;AAEAJ,EAAM,cAAc;"}
@@ -0,0 +1,39 @@
1
+ import { j as t } from "../_virtual/jsx-runtime.js";
2
+ import "react";
3
+ import { getResponsiveClasses as n, RESPONSIVE_SIZE_MAPS as i } from "../utils/responsive.js";
4
+ import { cn as o } from "../utils/cn.js";
5
+ import { warnOnce as h } from "../utils/devWarn.js";
6
+ const f = ({
7
+ progress: e,
8
+ size: s = "md",
9
+ className: l = ""
10
+ }) => {
11
+ const d = (a) => n(a, i.linearProgress.width), c = (a) => n(a, i.linearProgress.height);
12
+ (e < 0 || e > 100) && h(
13
+ `linearprogress-range-${e}`,
14
+ `LinearProgress: progress={${e}} is outside the 0-100 range — the bar is not clamped and will visually overflow its container. Pass a percentage value, e.g. (loaded / total) * 100.`
15
+ );
16
+ const m = d(s), r = c(s), g = o("bg-surface rounded-full shadow-inner", r, l || m), u = o("bg-gradient-to-r from-accent to-primary rounded-full shadow-lg-accent transition-all duration-500 ease-out", r);
17
+ return /* @__PURE__ */ t.jsx(
18
+ "div",
19
+ {
20
+ className: g,
21
+ role: "progressbar",
22
+ "aria-valuenow": Math.max(0, Math.min(100, e)),
23
+ "aria-valuemin": 0,
24
+ "aria-valuemax": 100,
25
+ children: /* @__PURE__ */ t.jsx(
26
+ "div",
27
+ {
28
+ className: u,
29
+ style: { width: `${e}%` }
30
+ }
31
+ )
32
+ }
33
+ );
34
+ };
35
+ f.displayName = "CyberUI.LinearProgress";
36
+ export {
37
+ f as default
38
+ };
39
+ //# sourceMappingURL=LinearProgress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinearProgress.js","sources":["../../src/components/LinearProgress.tsx"],"sourcesContent":["import React from \"react\";\r\nimport type { ResponsiveValue } from \"../utils/responsive\";\r\nimport { getResponsiveClasses, RESPONSIVE_SIZE_MAPS } from \"../utils/responsive\";\r\nimport { cn } from \"../utils/cn\";\r\nimport { warnOnce } from \"../utils/devWarn\";\r\n\r\n/**\r\n * A linear progress bar with gradient and glow effects.\r\n *\r\n * @example\r\n * // Basic progress bar\r\n * <LinearProgress progress={60} />\r\n *\r\n * @example\r\n * // Large progress bar with custom class\r\n * <LinearProgress\r\n * progress={85}\r\n * size=\"lg\"\r\n * className=\"my-4\"\r\n * />\r\n */\r\nexport interface LinearProgressProps {\r\n /**\r\n * Progress value (0-100).\r\n */\r\n progress: number;\r\n /**\r\n * Height of the progress bar.\r\n * @default 'md'\r\n */\r\n size?: ResponsiveValue<'sm' | 'md' | 'lg'>;\r\n /** Optional custom class name to override default styles */\r\n className?: string;\r\n}\r\n\r\n/**\r\n * A sleek, animated linear progress bar with cyberpunk aesthetic.\r\n *\r\n * The bar is `w-full` by default — it fills its container width.\r\n * Wrap it in a constrained element to control its width.\r\n *\r\n * @example\r\n * // Full-width bar (fills parent)\r\n * <LinearProgress progress={75} />\r\n *\r\n * @example\r\n * // Width-constrained\r\n * <div className=\"w-64\">\r\n * <LinearProgress progress={kbytesLoaded} size={{ base: 'sm', lg: 'md' }} />\r\n * </div>\r\n */\r\nconst LinearProgress: React.FC<LinearProgressProps> = ({\r\n progress,\r\n size = 'md',\r\n className = \"\",\r\n}) => {\r\n const getWidthClasses = (size: ResponsiveValue<'sm' | 'md' | 'lg'>): string => {\r\n return getResponsiveClasses(size, RESPONSIVE_SIZE_MAPS.linearProgress.width);\r\n };\r\n\r\n const getHeightClasses = (size: ResponsiveValue<'sm' | 'md' | 'lg'>): string => {\r\n return getResponsiveClasses(size, RESPONSIVE_SIZE_MAPS.linearProgress.height);\r\n };\r\n\r\n if (progress < 0 || progress > 100) {\r\n warnOnce(\r\n `linearprogress-range-${progress}`,\r\n `LinearProgress: progress={${progress}} is outside the 0-100 range — the bar is not clamped and will visually overflow its container. Pass a percentage value, e.g. (loaded / total) * 100.`\r\n );\r\n }\r\n\r\n const widthClasses = getWidthClasses(size);\r\n const heightClasses = getHeightClasses(size);\r\n\r\n const containerClasses = cn('bg-surface rounded-full shadow-inner', heightClasses, className || widthClasses);\r\n\r\n const progressBarClasses = cn('bg-gradient-to-r from-accent to-primary rounded-full shadow-lg-accent transition-all duration-500 ease-out', heightClasses);\r\n\r\n return (\r\n <div\r\n className={containerClasses}\r\n role=\"progressbar\"\r\n aria-valuenow={Math.max(0, Math.min(100, progress))}\r\n aria-valuemin={0}\r\n aria-valuemax={100}\r\n >\r\n <div\r\n className={progressBarClasses}\r\n style={{ width: `${progress}%` }}\r\n ></div>\r\n </div>\r\n );\r\n};\r\n\r\nLinearProgress.displayName = \"CyberUI.LinearProgress\";\r\n\r\nexport default LinearProgress;\r\n"],"names":["LinearProgress","progress","size","className","getWidthClasses","getResponsiveClasses","RESPONSIVE_SIZE_MAPS","getHeightClasses","warnOnce","widthClasses","heightClasses","containerClasses","cn","progressBarClasses","jsx"],"mappings":";;;;;AAmDA,MAAMA,IAAgD,CAAC;AAAA,EACrD,UAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,WAAAC,IAAY;AACd,MAAM;AACJ,QAAMC,IAAkB,CAACF,MAChBG,EAAqBH,GAAMI,EAAqB,eAAe,KAAK,GAGvEC,IAAmB,CAACL,MACjBG,EAAqBH,GAAMI,EAAqB,eAAe,MAAM;AAG9E,GAAIL,IAAW,KAAKA,IAAW,QAC7BO;AAAA,IACE,wBAAwBP,CAAQ;AAAA,IAChC,6BAA6BA,CAAQ;AAAA,EAAA;AAIzC,QAAMQ,IAAeL,EAAgBF,CAAI,GACnCQ,IAAgBH,EAAiBL,CAAI,GAErCS,IAAmBC,EAAG,wCAAwCF,GAAeP,KAAaM,CAAY,GAEtGI,IAAqBD,EAAG,8GAA8GF,CAAa;AAEzJ,SACEI,gBAAAA,EAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWH;AAAA,MACX,MAAK;AAAA,MACL,iBAAe,KAAK,IAAI,GAAG,KAAK,IAAI,KAAKV,CAAQ,CAAC;AAAA,MAClD,iBAAe;AAAA,MACf,iBAAe;AAAA,MAEf,UAAAa,gBAAAA,EAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAWD;AAAA,UACX,OAAO,EAAE,OAAO,GAAGZ,CAAQ,IAAA;AAAA,QAAI;AAAA,MAAA;AAAA,IAChC;AAAA,EAAA;AAGP;AAEAD,EAAe,cAAc;"}
@@ -60,15 +60,28 @@ export interface ModalProps extends ModalCallbacks {
60
60
  * Callback when the modal requests to close.
61
61
  */
62
62
  onClose: () => void;
63
+ /** Title text shown in the modal header. */
63
64
  title?: string;
65
+ /** The content to be rendered inside the modal body. */
64
66
  children: React.ReactNode;
67
+ /**
68
+ * Custom footer content. Overrides the default Cancel/Confirm action buttons
69
+ * (`onCancel`/`onConfirm` and related props are ignored when `footer` is set).
70
+ */
65
71
  footer?: React.ReactNode;
72
+ /** Fired when the Cancel button is clicked. Only rendered if provided. */
66
73
  onCancel?: () => void;
74
+ /** Fired when the Confirm button is clicked. Only rendered if provided. */
67
75
  onConfirm?: () => void;
76
+ /** Label for the Cancel button. @default 'Cancel' */
68
77
  cancelText?: string;
78
+ /** Label for the Confirm button. @default 'Confirm' */
69
79
  confirmText?: string;
80
+ /** Shows a loading state and disables the Confirm button. @default false */
70
81
  confirmLoading?: boolean;
82
+ /** Whether to render the Cancel button (requires `onCancel`). @default true */
71
83
  showCancel?: boolean;
84
+ /** Whether to render the Confirm button (requires `onConfirm`). @default true */
72
85
  showConfirm?: boolean;
73
86
  /**
74
87
  * Width of the modal.
@@ -84,11 +97,17 @@ export interface ModalProps extends ModalCallbacks {
84
97
  * @default 'default'
85
98
  */
86
99
  variant?: "default" | "danger";
100
+ /** Whether clicking the overlay backdrop closes the modal. @default true */
87
101
  closeOnOverlayClick?: boolean;
102
+ /** Whether pressing Escape closes the modal. @default true */
88
103
  closeOnEscape?: boolean;
104
+ /** CRT open/close animation timing and effects. */
89
105
  animation?: ModalAnimationConfig;
106
+ /** Additional CSS classes for the modal panel. */
90
107
  className?: string;
108
+ /** Additional CSS classes for the overlay backdrop. */
91
109
  overlayClassName?: string;
110
+ /** Whether to render the header close (×) button. @default true */
92
111
  showCloseButton?: boolean;
93
112
  }
94
113
  /**