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,73 @@
1
+ import { j as t } from "../_virtual/jsx-runtime.js";
2
+ import "react";
3
+ import { getResponsiveClasses as b } from "../utils/responsive.js";
4
+ import { cn as s } from "../utils/cn.js";
5
+ const j = ({
6
+ label: a,
7
+ size: l = "md",
8
+ variant: f = "primary",
9
+ className: p = "",
10
+ checked: g = !1,
11
+ onChange: n,
12
+ disabled: e = !1,
13
+ id: c,
14
+ ...u
15
+ }) => {
16
+ const m = (r) => {
17
+ e || n && n(r.target.checked);
18
+ }, d = (r) => b(r, {
19
+ sm: "w-10 h-5 after:h-4 after:w-4",
20
+ md: "w-14 h-7 after:h-6 after:w-6",
21
+ lg: "w-16 h-8 after:h-7 after:w-7"
22
+ }), h = (r, o) => {
23
+ if (o)
24
+ return "bg-gray-600 peer-checked:bg-gray-500 opacity-50 cursor-not-allowed";
25
+ const i = {
26
+ primary: "bg-gray-600 peer-checked:bg-linear-(--gradient-accent) peer-focus:ring-primary",
27
+ secondary: "bg-gray-600 peer-checked:bg-secondary peer-focus:ring-secondary",
28
+ accent: "bg-gray-600 peer-checked:bg-accent peer-focus:ring-accent"
29
+ };
30
+ return i[r] || i.primary;
31
+ }, y = s(
32
+ "relative inline-flex items-center",
33
+ e ? "cursor-not-allowed opacity-50" : "cursor-pointer"
34
+ ), x = s(
35
+ d(l),
36
+ h(f, e),
37
+ "peer-focus:outline-none rounded-full peer",
38
+ "peer-checked:after:translate-x-full peer-checked:after:border-white",
39
+ "after:content-[''] after:absolute after:top-[2px] after:left-[2px]",
40
+ "after:bg-white after:rounded-full after:transition-all",
41
+ "transition-colors duration-300"
42
+ ), w = s("flex items-center justify-between", a && "space-x-3", p);
43
+ return /* @__PURE__ */ t.jsxs("div", { className: w, children: [
44
+ a && /* @__PURE__ */ t.jsx(
45
+ "label",
46
+ {
47
+ htmlFor: c,
48
+ className: `text-default font-medium ${e ? "text-muted opacity-50" : "cursor-pointer"}`,
49
+ children: a
50
+ }
51
+ ),
52
+ /* @__PURE__ */ t.jsxs("label", { className: y, children: [
53
+ /* @__PURE__ */ t.jsx(
54
+ "input",
55
+ {
56
+ type: "checkbox",
57
+ className: "sr-only peer",
58
+ checked: g,
59
+ onChange: m,
60
+ disabled: e,
61
+ id: c,
62
+ ...u
63
+ }
64
+ ),
65
+ /* @__PURE__ */ t.jsx("div", { className: x })
66
+ ] })
67
+ ] });
68
+ };
69
+ j.displayName = "CyberUI.Toggle";
70
+ export {
71
+ j as default
72
+ };
73
+ //# sourceMappingURL=Toggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toggle.js","sources":["../../src/components/Toggle.tsx"],"sourcesContent":["import React from 'react';\r\nimport type { ResponsiveValue } from '../utils/responsive';\r\nimport { getResponsiveClasses } from '../utils/responsive';\r\nimport { cn } from '../utils/cn';\r\n\r\n/**\r\n * A toggle switch component.\r\n *\r\n * @example\r\n * // Basic toggle\r\n * <Toggle\r\n * label=\"Enable Notifications\"\r\n * checked={enabled}\r\n * onChange={setEnabled}\r\n * />\r\n *\r\n * @example\r\n * // Large accent toggle\r\n * <Toggle\r\n * checked={isActive}\r\n * onChange={toggle}\r\n * size=\"lg\"\r\n * variant=\"accent\"\r\n * />\r\n */\r\nexport interface ToggleProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'onChange'> {\r\n /** Optional label text to display next to the toggle */\r\n label?: string;\r\n /**\r\n * Size of the toggle.\r\n * @default 'md'\r\n */\r\n size?: ResponsiveValue<'sm' | 'md' | 'lg'>;\r\n /**\r\n * Visual style variant.\r\n * @default 'primary'\r\n */\r\n variant?: 'primary' | 'secondary' | 'accent';\r\n /** Optional custom class name */\r\n className?: string;\r\n /** Whether the toggle is currently checked */\r\n checked?: boolean;\r\n /** Callback fired when the toggle state changes */\r\n onChange?: (checked: boolean) => void;\r\n}\r\n\r\n/**\r\n * A futuristic cyberpunk-themed toggle switch with neon glow and smooth transitions.\r\n * \r\n * @example\r\n * <Toggle \r\n * label=\"Night Mode\" \r\n * checked={isDark} \r\n * onChange={setIsDark} \r\n * />\r\n */\r\nconst Toggle: React.FC<ToggleProps> = ({\r\n label,\r\n size = 'md',\r\n variant = 'primary',\r\n className = '',\r\n checked = false,\r\n onChange,\r\n disabled = false,\r\n id,\r\n ...props\r\n}) => {\r\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n if (disabled) return;\r\n if (onChange) {\r\n onChange(e.target.checked);\r\n }\r\n };\r\n\r\n const getSizeClasses = (size: ResponsiveValue<'sm' | 'md' | 'lg'>): string => {\r\n const sizeMap = {\r\n sm: 'w-10 h-5 after:h-4 after:w-4',\r\n md: 'w-14 h-7 after:h-6 after:w-6',\r\n lg: 'w-16 h-8 after:h-7 after:w-7'\r\n };\r\n return getResponsiveClasses(size, sizeMap);\r\n };\r\n\r\n const getVariantClasses = (variant: string, disabled: boolean): string => {\r\n if (disabled) {\r\n return 'bg-gray-600 peer-checked:bg-gray-500 opacity-50 cursor-not-allowed';\r\n }\r\n\r\n const variants = {\r\n primary: 'bg-gray-600 peer-checked:bg-linear-(--gradient-accent) peer-focus:ring-primary',\r\n secondary: 'bg-gray-600 peer-checked:bg-secondary peer-focus:ring-secondary',\r\n accent: 'bg-gray-600 peer-checked:bg-accent peer-focus:ring-accent'\r\n };\r\n\r\n return variants[variant as keyof typeof variants] || variants.primary;\r\n };\r\n\r\n const toggleClasses = cn(\r\n 'relative inline-flex items-center',\r\n disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'\r\n );\r\n\r\n const sliderClasses = cn(\r\n getSizeClasses(size),\r\n getVariantClasses(variant, disabled),\r\n 'peer-focus:outline-none rounded-full peer',\r\n 'peer-checked:after:translate-x-full peer-checked:after:border-white',\r\n 'after:content-[\\'\\'] after:absolute after:top-[2px] after:left-[2px]',\r\n 'after:bg-white after:rounded-full after:transition-all',\r\n 'transition-colors duration-300'\r\n );\r\n\r\n const containerClasses = cn('flex items-center justify-between', label && 'space-x-3', className);\r\n\r\n return (\r\n <div className={containerClasses}>\r\n {label && (\r\n <label\r\n htmlFor={id}\r\n className={`text-default font-medium ${disabled ? 'text-muted opacity-50' : 'cursor-pointer'}`}\r\n >\r\n {label}\r\n </label>\r\n )}\r\n <label className={toggleClasses}>\r\n <input\r\n type=\"checkbox\"\r\n className=\"sr-only peer\"\r\n checked={checked}\r\n onChange={handleChange}\r\n disabled={disabled}\r\n id={id}\r\n {...props}\r\n />\r\n <div className={sliderClasses}></div>\r\n </label>\r\n </div>\r\n );\r\n};\r\n\r\nToggle.displayName = \"CyberUI.Toggle\";\r\n\r\nexport default Toggle;\r\n"],"names":["Toggle","label","size","variant","className","checked","onChange","disabled","id","props","handleChange","e","getSizeClasses","getResponsiveClasses","getVariantClasses","variants","toggleClasses","cn","sliderClasses","containerClasses","jsxs","jsx"],"mappings":";;;;AAwDA,MAAMA,IAAgC,CAAC;AAAA,EACrC,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,SAAAC,IAAU;AAAA,EACV,WAAAC,IAAY;AAAA,EACZ,SAAAC,IAAU;AAAA,EACV,UAAAC;AAAA,EACA,UAAAC,IAAW;AAAA,EACX,IAAAC;AAAA,EACA,GAAGC;AACL,MAAM;AACJ,QAAMC,IAAe,CAACC,MAA2C;AAC/D,IAAIJ,KACAD,KACFA,EAASK,EAAE,OAAO,OAAO;AAAA,EAE7B,GAEMC,IAAiB,CAACV,MAMfW,EAAqBX,GALZ;AAAA,IACd,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,EAAA,CAEmC,GAGrCY,IAAoB,CAACX,GAAiBI,MAA8B;AACxE,QAAIA;AACF,aAAO;AAGT,UAAMQ,IAAW;AAAA,MACf,SAAS;AAAA,MACT,WAAW;AAAA,MACX,QAAQ;AAAA,IAAA;AAGV,WAAOA,EAASZ,CAAgC,KAAKY,EAAS;AAAA,EAChE,GAEMC,IAAgBC;AAAA,IACpB;AAAA,IACAV,IAAW,kCAAkC;AAAA,EAAA,GAGzCW,IAAgBD;AAAA,IACpBL,EAAeV,CAAI;AAAA,IACnBY,EAAkBX,GAASI,CAAQ;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,GAGIY,IAAmBF,EAAG,qCAAqChB,KAAS,aAAaG,CAAS;AAEhG,SACEgB,gBAAAA,EAAAA,KAAC,OAAA,EAAI,WAAWD,GACb,UAAA;AAAA,IAAAlB,KACCoB,gBAAAA,EAAAA;AAAAA,MAAC;AAAA,MAAA;AAAA,QACC,SAASb;AAAA,QACT,WAAW,4BAA4BD,IAAW,0BAA0B,gBAAgB;AAAA,QAE3F,UAAAN;AAAA,MAAA;AAAA,IAAA;AAAA,IAGLmB,gBAAAA,EAAAA,KAAC,SAAA,EAAM,WAAWJ,GAChB,UAAA;AAAA,MAAAK,gBAAAA,EAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAAhB;AAAA,UACA,UAAUK;AAAA,UACV,UAAAH;AAAA,UACA,IAAAC;AAAA,UACC,GAAGC;AAAA,QAAA;AAAA,MAAA;AAAA,MAENY,gBAAAA,EAAAA,IAAC,OAAA,EAAI,WAAWH,EAAA,CAAe;AAAA,IAAA,EAAA,CACjC;AAAA,EAAA,GACF;AAEJ;AAEAlB,EAAO,cAAc;"}
@@ -0,0 +1,100 @@
1
+ import { j as d } from "../_virtual/jsx-runtime.js";
2
+ import { useState as y, useCallback as n } from "react";
3
+ import j from "../components/Notification.js";
4
+ import { NotificationContext as C } from "./NotificationContextBase.js";
5
+ const W = ({ children: u, position: s = "top-right", defaultDuration: m = 2500 }) => {
6
+ const [h, r] = y([]), g = n(
7
+ (t, i, e, l = {}) => {
8
+ const c = Date.now().toString(), { autoHide: v = !0, duration: w = m } = l;
9
+ return r((a) => [...a, { id: c, type: t, title: i, message: e }]), v && setTimeout(() => {
10
+ r(
11
+ (a) => a.map((o) => o.id === c ? { ...o, isClosing: !0 } : o)
12
+ ), setTimeout(() => {
13
+ r((a) => a.filter((o) => o.id !== c));
14
+ }, 500);
15
+ }, w), c;
16
+ },
17
+ [m]
18
+ ), f = n((t) => {
19
+ r(
20
+ (i) => i.map((e) => e.id === t ? { ...e, isClosing: !0 } : e)
21
+ ), setTimeout(() => {
22
+ r((i) => i.filter((e) => e.id !== t));
23
+ }, 500);
24
+ }, []), p = n(() => {
25
+ r([]);
26
+ }, []), x = n((t, i) => {
27
+ r(
28
+ (e) => e.map((l) => l.id === t ? { ...l, width: i } : l)
29
+ );
30
+ }, []), N = {
31
+ notifications: h,
32
+ showNotification: g,
33
+ hideNotification: f,
34
+ clearAllNotifications: p
35
+ };
36
+ return /* @__PURE__ */ d.jsxs(C.Provider, { value: N, children: [
37
+ u,
38
+ h.length > 0 && /* @__PURE__ */ d.jsx(
39
+ "div",
40
+ {
41
+ className: `fixed z-50 ${$(s)}`,
42
+ "aria-live": "polite",
43
+ "aria-relevant": "additions text",
44
+ "aria-atomic": "true",
45
+ children: h.map((t, i) => /* @__PURE__ */ d.jsx(
46
+ "div",
47
+ {
48
+ className: "absolute",
49
+ style: {
50
+ right: s.includes("right") ? 0 : void 0,
51
+ left: s.includes("left") ? 0 : void 0,
52
+ top: `${i * 70}px`,
53
+ width: t.width ? `${t.width}px` : "auto"
54
+ },
55
+ children: /* @__PURE__ */ d.jsx(
56
+ "div",
57
+ {
58
+ className: `transform transition-all duration-500 ease-out scale-75 opacity-90 w-full ${s.includes("right") ? "flex justify-end" : "flex justify-start"} ${t.isClosing ? `${s.includes("right") ? "translate-x-full" : "-translate-x-full"} opacity-0` : "translate-x-0 opacity-90"}`,
59
+ style: {
60
+ whiteSpace: "nowrap",
61
+ transformOrigin: s.includes("right") ? "right center" : "left center",
62
+ transform: t.isClosing ? `translateX(${s.includes("right") ? "100%" : "-100%"}) scale(0.75)` : `translateX(${t.width ? "0px" : s.includes("right") ? "100%" : "-100%"}) scale(0.75)`
63
+ },
64
+ ref: (e) => {
65
+ if (e && !t.width) {
66
+ const l = e.scrollWidth;
67
+ x(t.id, l);
68
+ }
69
+ },
70
+ children: /* @__PURE__ */ d.jsx(
71
+ j,
72
+ {
73
+ type: t.type,
74
+ title: t.title,
75
+ message: t.message,
76
+ onClose: () => f(t.id),
77
+ size: "sm"
78
+ }
79
+ )
80
+ }
81
+ )
82
+ },
83
+ t.id
84
+ ))
85
+ }
86
+ )
87
+ ] });
88
+ }, $ = (u) => {
89
+ const s = {
90
+ "top-right": "top-4 right-4",
91
+ "top-left": "top-4 left-4",
92
+ "bottom-right": "bottom-4 right-4",
93
+ "bottom-left": "bottom-4 left-4"
94
+ };
95
+ return s[u] || s["top-right"];
96
+ };
97
+ export {
98
+ W as CyberNotificationProvider
99
+ };
100
+ //# sourceMappingURL=NotificationContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationContext.js","sources":["../../src/contexts/NotificationContext.tsx"],"sourcesContent":["import React, { useState, useCallback, type ReactNode } from \"react\";\r\nimport Notification from \"../components/Notification\";\r\nimport {\r\n NotificationContext,\r\n type CyberNotification,\r\n type NotificationOptions,\r\n type NotificationContextType,\r\n} from \"./NotificationContextBase\";\r\n\r\nexport interface CyberNotificationProviderProps {\r\n children: ReactNode;\r\n position?: \"top-right\" | \"top-left\" | \"bottom-right\" | \"bottom-left\";\r\n defaultDuration?: number;\r\n}\r\n\r\n/**\r\n * Context provider for the Cyberpunk notification system.\r\n * Wrap your application root with this provider to enable toasts.\r\n * \r\n * @example\r\n * <CyberNotificationProvider position=\"top-right\">\r\n * <App />\r\n * </CyberNotificationProvider>\r\n */\r\nexport const CyberNotificationProvider: React.FC<\r\n CyberNotificationProviderProps\r\n> = ({ children, position = \"top-right\", defaultDuration = 2500 }) => {\r\n const [notifications, setNotifications] = useState<CyberNotification[]>([]);\r\n\r\n const showNotification = useCallback(\r\n (\r\n type: \"success\" | \"warning\" | \"error\",\r\n title: string,\r\n message: string,\r\n options: NotificationOptions = {}\r\n ): string => {\r\n const id = Date.now().toString();\r\n const { autoHide = true, duration = defaultDuration } = options;\r\n\r\n setNotifications((prev) => [...prev, { id, type, title, message }]);\r\n\r\n if (autoHide) {\r\n setTimeout(() => {\r\n // Start closing animation\r\n setNotifications((prev) =>\r\n prev.map((n) => (n.id === id ? { ...n, isClosing: true } : n))\r\n );\r\n // Remove after animation completes\r\n setTimeout(() => {\r\n setNotifications((prev) => prev.filter((n) => n.id !== id));\r\n }, 500); // Animation duration\r\n }, duration);\r\n }\r\n\r\n return id;\r\n },\r\n [defaultDuration]\r\n );\r\n\r\n const hideNotification = useCallback((id: string) => {\r\n // Start closing animation\r\n setNotifications((prev) =>\r\n prev.map((n) => (n.id === id ? { ...n, isClosing: true } : n))\r\n );\r\n // Remove after animation completes\r\n setTimeout(() => {\r\n setNotifications((prev) => prev.filter((n) => n.id !== id));\r\n }, 500); // Animation duration\r\n }, []);\r\n\r\n const clearAllNotifications = useCallback(() => {\r\n setNotifications([]);\r\n }, []);\r\n\r\n const updateNotificationWidth = useCallback((id: string, width: number) => {\r\n setNotifications((prev) =>\r\n prev.map((n) => (n.id === id ? { ...n, width } : n))\r\n );\r\n }, []);\r\n\r\n const value: NotificationContextType = {\r\n notifications,\r\n showNotification,\r\n hideNotification,\r\n clearAllNotifications,\r\n };\r\n\r\n return (\r\n <NotificationContext.Provider value={value}>\r\n {children}\r\n {/* Notification Container */}\r\n {notifications.length > 0 && (\r\n <div\r\n className={`fixed z-50 ${getPositionClasses(position)}`}\r\n aria-live=\"polite\"\r\n aria-relevant=\"additions text\"\r\n aria-atomic=\"true\"\r\n >\r\n {notifications.map((notification, index) => (\r\n <div\r\n key={notification.id}\r\n className=\"absolute\"\r\n style={{\r\n right: position.includes(\"right\") ? 0 : undefined,\r\n left: position.includes(\"left\") ? 0 : undefined,\r\n top: `${index * 70}px`,\r\n width: notification.width ? `${notification.width}px` : \"auto\",\r\n }}\r\n >\r\n <div\r\n className={`transform transition-all duration-500 ease-out scale-75 opacity-90 w-full ${\r\n position.includes(\"right\")\r\n ? \"flex justify-end\"\r\n : \"flex justify-start\"\r\n } ${\r\n notification.isClosing\r\n ? `${\r\n position.includes(\"right\")\r\n ? \"translate-x-full\"\r\n : \"-translate-x-full\"\r\n } opacity-0`\r\n : \"translate-x-0 opacity-90\"\r\n }`}\r\n style={{\r\n whiteSpace: \"nowrap\" as const,\r\n transformOrigin: position.includes(\"right\")\r\n ? \"right center\"\r\n : \"left center\",\r\n transform: notification.isClosing\r\n ? `translateX(${\r\n position.includes(\"right\") ? \"100%\" : \"-100%\"\r\n }) scale(0.75)`\r\n : `translateX(${\r\n notification.width\r\n ? \"0px\"\r\n : position.includes(\"right\")\r\n ? \"100%\"\r\n : \"-100%\"\r\n }) scale(0.75)`,\r\n }}\r\n ref={(el) => {\r\n if (el && !notification.width) {\r\n const scaledWidth = el.scrollWidth;\r\n updateNotificationWidth(notification.id, scaledWidth);\r\n }\r\n }}\r\n >\r\n <Notification\r\n type={notification.type}\r\n title={notification.title}\r\n message={notification.message}\r\n onClose={() => hideNotification(notification.id)}\r\n size=\"sm\"\r\n />\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </NotificationContext.Provider>\r\n );\r\n};\r\n\r\n// Helper function for positioning\r\nconst getPositionClasses = (position: string): string => {\r\n const positions = {\r\n \"top-right\": \"top-4 right-4\",\r\n \"top-left\": \"top-4 left-4\",\r\n \"bottom-right\": \"bottom-4 right-4\",\r\n \"bottom-left\": \"bottom-4 left-4\",\r\n };\r\n return (\r\n positions[position as keyof typeof positions] || positions[\"top-right\"]\r\n );\r\n};\r\n"],"names":["CyberNotificationProvider","children","position","defaultDuration","notifications","setNotifications","useState","showNotification","useCallback","type","title","message","options","id","autoHide","duration","prev","n","hideNotification","clearAllNotifications","updateNotificationWidth","width","value","jsxs","NotificationContext","jsx","getPositionClasses","notification","index","el","scaledWidth","Notification","positions"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { createContext as t } from "react";
2
+ const e = t(void 0);
3
+ export {
4
+ e as NotificationContext
5
+ };
6
+ //# sourceMappingURL=NotificationContextBase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NotificationContextBase.js","sources":["../../src/contexts/NotificationContextBase.ts"],"sourcesContent":["import { createContext } from \"react\";\r\n\r\nexport interface CyberNotification {\r\n id: string;\r\n type: \"success\" | \"warning\" | \"error\";\r\n title: string;\r\n message: string;\r\n width?: number;\r\n isClosing?: boolean;\r\n}\r\n\r\nexport interface NotificationOptions {\r\n autoHide?: boolean;\r\n duration?: number;\r\n}\r\n\r\nexport interface NotificationContextType {\r\n notifications: CyberNotification[];\r\n showNotification: (\r\n type: \"success\" | \"warning\" | \"error\",\r\n title: string,\r\n message: string,\r\n options?: NotificationOptions\r\n ) => string;\r\n hideNotification: (id: string) => void;\r\n clearAllNotifications: () => void;\r\n}\r\n\r\nexport const NotificationContext = createContext<\r\n NotificationContextType | undefined\r\n>(undefined);\r\n"],"names":["NotificationContext","createContext"],"mappings":";AA4BO,MAAMA,IAAsBC,EAEjC,MAAS;"}
@@ -0,0 +1,17 @@
1
+ import { useState as i, useEffect as m } from "react";
2
+ const d = (c = {}) => {
3
+ const { min: t = 5, max: r = 95, speed: s = 30 } = c, [a, l] = i(0), [n, o] = i(1);
4
+ return m(() => {
5
+ const u = setInterval(() => {
6
+ l((f) => {
7
+ let e = f + n;
8
+ return e >= r ? (e = r, o(-1)) : e <= t && (e = t, o(1)), e;
9
+ });
10
+ }, s);
11
+ return () => clearInterval(u);
12
+ }, [n, t, r, s]), a;
13
+ };
14
+ export {
15
+ d as useAnimatedProgress
16
+ };
17
+ //# sourceMappingURL=useAnimatedProgress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAnimatedProgress.js","sources":["../../src/hooks/useAnimatedProgress.ts"],"sourcesContent":["import { useState, useEffect } from 'react';\r\n\r\nexport interface UseAnimatedProgressOptions {\r\n min?: number;\r\n max?: number;\r\n speed?: number;\r\n}\r\n\r\n/**\r\n * A hook that oscillates a value between a min and max range.\r\n * Useful for creating \"breathing\" or \"pulse\" animations.\r\n *\r\n * @param options Configuration options\r\n * @param options.min Minimum value (default: 5)\r\n * @param options.max Maximum value (default: 95)\r\n * @param options.speed Speed of oscillation in ms (default: 30)\r\n * @returns The current animated value\r\n */\r\nexport const useAnimatedProgress = (options: UseAnimatedProgressOptions = {}) => {\r\n const { min = 5, max = 95, speed = 30 } = options;\r\n const [progress, setProgress] = useState(0);\r\n const [direction, setDirection] = useState(1);\r\n\r\n useEffect(() => {\r\n const interval = setInterval(() => {\r\n setProgress((prev) => {\r\n let next = prev + direction;\r\n\r\n if (next >= max) {\r\n next = max;\r\n setDirection(-1);\r\n } else if (next <= min) {\r\n next = min;\r\n setDirection(1);\r\n }\r\n\r\n return next;\r\n });\r\n }, speed);\r\n\r\n return () => clearInterval(interval);\r\n }, [direction, min, max, speed]);\r\n\r\n return progress;\r\n};\r\n"],"names":["useAnimatedProgress","options","min","max","speed","progress","setProgress","useState","direction","setDirection","useEffect","interval","prev","next"],"mappings":";AAkBO,MAAMA,IAAsB,CAACC,IAAsC,OAAO;AAC/E,QAAM,EAAE,KAAAC,IAAM,GAAG,KAAAC,IAAM,IAAI,OAAAC,IAAQ,OAAOH,GACpC,CAACI,GAAUC,CAAW,IAAIC,EAAS,CAAC,GACpC,CAACC,GAAWC,CAAY,IAAIF,EAAS,CAAC;AAE5C,SAAAG,EAAU,MAAM;AACd,UAAMC,IAAW,YAAY,MAAM;AACjC,MAAAL,EAAY,CAACM,MAAS;AACpB,YAAIC,IAAOD,IAAOJ;AAElB,eAAIK,KAAQV,KACVU,IAAOV,GACPM,EAAa,EAAE,KACNI,KAAQX,MACjBW,IAAOX,GACPO,EAAa,CAAC,IAGTI;AAAA,MACT,CAAC;AAAA,IACH,GAAGT,CAAK;AAER,WAAO,MAAM,cAAcO,CAAQ;AAAA,EACrC,GAAG,CAACH,GAAWN,GAAKC,GAAKC,CAAK,CAAC,GAExBC;AACT;"}
@@ -0,0 +1,14 @@
1
+ import { useContext as o } from "react";
2
+ import { NotificationContext as i } from "../contexts/NotificationContextBase.js";
3
+ const n = () => {
4
+ const t = o(i);
5
+ if (t === void 0)
6
+ throw new Error(
7
+ "useCyberNotifications must be used within a CyberNotificationProvider"
8
+ );
9
+ return t;
10
+ };
11
+ export {
12
+ n as useCyberNotifications
13
+ };
14
+ //# sourceMappingURL=useCyberNotifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCyberNotifications.js","sources":["../../src/hooks/useCyberNotifications.ts"],"sourcesContent":["import { useContext } from \"react\";\r\nimport { NotificationContext } from \"../contexts/NotificationContextBase\";\r\n\r\n/**\r\n * Access the notification context to show toast notifications.\r\n * Must be used within a CyberNotificationProvider.\r\n *\r\n * @returns The notification context value containing `showNotification`\r\n * @throws Error if used outside of CyberNotificationProvider\r\n */\r\nexport const useCyberNotifications = () => {\r\n const context = useContext(NotificationContext);\r\n if (context === undefined) {\r\n throw new Error(\r\n \"useCyberNotifications must be used within a CyberNotificationProvider\"\r\n );\r\n }\r\n return context;\r\n};\r\n\r\nexport type {\r\n CyberNotification,\r\n NotificationOptions,\r\n} from \"../contexts/NotificationContextBase\";\r\n"],"names":["useCyberNotifications","context","useContext","NotificationContext"],"mappings":";;AAUO,MAAMA,IAAwB,MAAM;AACzC,QAAMC,IAAUC,EAAWC,CAAmB;AAC9C,MAAIF,MAAY;AACd,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAGJ,SAAOA;AACT;"}
@@ -0,0 +1,254 @@
1
+ import { useRef as b, useState as I, useEffect as H, useCallback as h } from "react";
2
+ const p = {
3
+ MOBILE_BREAKPOINT: 768,
4
+ STABLE_TIMEOUT: 1e3,
5
+ MOBILE_HIDE_DELAY: 1e3,
6
+ VELOCITY_MULTIPLIER: 2,
7
+ DISTANCE_THRESHOLD: 100,
8
+ MAX_ANIMATION_SPEED: 5,
9
+ MIN_GLOW_DURATION: 150
10
+ }, te = (J = {}) => {
11
+ const {
12
+ glowColor: y = "primary",
13
+ sensitivity: O = 2,
14
+ disabled: w = !1,
15
+ pageLevel: v,
16
+ variant: R = "default",
17
+ className: $ = ""
18
+ } = J, a = b(null), m = b(null), C = b(Date.now()), _ = b(0), E = b(void 0), f = b([]), S = b(void 0), [N, B] = I({
19
+ isScrolling: !1,
20
+ direction: null,
21
+ velocity: 0,
22
+ position: 0,
23
+ scrollDistance: 0
24
+ }), [x, Q] = I(!1), [M, P] = I(() => typeof window > "u" ? !1 : window.innerWidth >= p.MOBILE_BREAKPOINT), L = b(0), [s, k] = I(v ?? !1);
25
+ H(() => {
26
+ if (v !== void 0)
27
+ k(v);
28
+ else {
29
+ const r = setTimeout(() => {
30
+ const e = a.current !== null;
31
+ k(!e);
32
+ }, 0);
33
+ return () => clearTimeout(r);
34
+ }
35
+ }, [v]);
36
+ const W = h((r) => {
37
+ switch (r) {
38
+ case "transparent":
39
+ return {
40
+ background: "transparent",
41
+ backdropFilter: "none",
42
+ border: "none",
43
+ boxShadow: "none"
44
+ };
45
+ case "minimal":
46
+ return {
47
+ background: "rgba(26, 26, 46, 0.6)",
48
+ backdropFilter: "blur(3px)",
49
+ border: "1px solid rgba(255, 0, 93, 0.2)",
50
+ boxShadow: "0 0 5px rgba(255, 0, 93, 0.2)"
51
+ };
52
+ case "default":
53
+ default:
54
+ return {
55
+ background: "linear-gradient(180deg, rgba(26, 26, 46, 0.95), rgba(45, 45, 68, 0.95))",
56
+ backdropFilter: "blur(6px)",
57
+ border: "1px solid rgba(255, 0, 93, 0.3)",
58
+ boxShadow: "0 0 10px rgba(255, 0, 93, 0.3), inset 0 0 10px rgba(255, 0, 93, 0.1)"
59
+ };
60
+ }
61
+ }, []), z = h(() => {
62
+ const r = window.innerWidth < p.MOBILE_BREAKPOINT;
63
+ return {
64
+ isMobile: r,
65
+ scrollbarWidth: r ? 12 : 16,
66
+ arrowSize: r ? 10 : 14,
67
+ lineSize: r ? 8 : 12,
68
+ arrowGap: r ? 2 : 4
69
+ };
70
+ }, []), F = h((r, e, n, o) => {
71
+ const t = (o + n) * 2, d = n * 4, u = (r - t - d) / 2;
72
+ return Math.floor(u / (e + n));
73
+ }, []), U = h((r) => {
74
+ if (s) {
75
+ if (!document.querySelector("#cyber-page-scrollbar-styles")) {
76
+ const e = document.createElement("style");
77
+ e.id = "cyber-page-scrollbar-styles", e.textContent = `
78
+ html::-webkit-scrollbar { display: none; }
79
+ html { scrollbar-width: none; -ms-overflow-style: none; }
80
+ `, document.head.appendChild(e);
81
+ }
82
+ } else if (r) {
83
+ if (r.style.scrollbarWidth = "none", r.style.msOverflowStyle = "none", !document.querySelector("#cyber-scrollbar-styles")) {
84
+ const e = document.createElement("style");
85
+ e.id = "cyber-scrollbar-styles", e.textContent = `
86
+ .cyber-scrollbar-container::-webkit-scrollbar { display: none; }
87
+ `, document.head.appendChild(e);
88
+ }
89
+ r.classList.add("cyber-scrollbar-container");
90
+ }
91
+ }, [s]), A = h((r, e, n, o) => {
92
+ const t = document.createElement("div"), d = r === "arrow";
93
+ d && e ? (t.className = `cyber-arrow cyber-arrow-${e} cyber-arrow-${n}`, t.innerHTML = e === "up" ? "▲" : "▼") : (t.className = `cyber-line cyber-line-${n}`, t.innerHTML = "=");
94
+ const l = o.isMobile ? "none" : `drop-shadow(0 0 6px var(--color-${y}))
95
+ drop-shadow(0 0 12px var(--color-${y}))
96
+ drop-shadow(0 0 18px var(--color-${y}))`;
97
+ return t.style.cssText = `
98
+ font-size: ${d ? o.arrowSize : o.lineSize}px;
99
+ color: var(--color-${y});
100
+ opacity: 0;
101
+ transition: all 0.2s ease;
102
+ filter: ${l};
103
+ line-height: 1;
104
+ font-weight: bold;
105
+ `, t;
106
+ }, [y]), V = h(() => {
107
+ if (s)
108
+ return {
109
+ height: window.innerHeight,
110
+ top: 0,
111
+ right: 0
112
+ };
113
+ {
114
+ const e = a.current.getBoundingClientRect();
115
+ return {
116
+ height: e.height,
117
+ top: e.top,
118
+ right: window.innerWidth - e.right
119
+ };
120
+ }
121
+ }, [s]), q = h(() => {
122
+ if (w || !s && !a.current || (m.current && m.current.remove(), !(s ? document.body.scrollHeight > window.innerHeight : a.current.scrollHeight > a.current.clientHeight))) return;
123
+ const e = z(), n = V(), o = F(n.height, e.arrowSize, e.arrowGap, e.lineSize);
124
+ U(s ? void 0 : a.current || void 0);
125
+ const t = document.createElement("div");
126
+ t.className = `cyber-scrollbar ${$}`.trim();
127
+ const l = e.isMobile ? "transparent" : R, u = W(l);
128
+ t.style.cssText = `
129
+ position: fixed;
130
+ top: ${n.top}px;
131
+ right: ${n.right}px;
132
+ width: ${e.scrollbarWidth}px;
133
+ height: ${n.height}px;
134
+ pointer-events: none;
135
+ z-index: 9999;
136
+ display: ${M ? "flex" : "none"};
137
+ flex-direction: column;
138
+ align-items: center;
139
+ justify-content: center;
140
+ gap: ${e.arrowGap}px;
141
+ background: ${u.background};
142
+ backdrop-filter: ${u.backdropFilter};
143
+ border-radius: ${s ? "4px 0 0 4px" : "4px"};
144
+ border: ${u.border};
145
+ box-shadow: ${u.boxShadow};
146
+ `;
147
+ for (let c = 0; c < o; c++)
148
+ t.appendChild(A("arrow", "up", c, e));
149
+ for (let c = 0; c < 2; c++)
150
+ t.appendChild(A("line", void 0, c, e));
151
+ for (let c = 0; c < o; c++)
152
+ t.appendChild(A("arrow", "down", c, e));
153
+ document.body.appendChild(t), m.current = t;
154
+ const i = s ? void 0 : () => {
155
+ const c = a.current;
156
+ if (c) {
157
+ const T = c.getBoundingClientRect();
158
+ t.style.top = `${T.top}px`, t.style.right = `${window.innerWidth - T.right}px`, t.style.height = `${T.height}px`;
159
+ }
160
+ };
161
+ return i && (window.addEventListener("resize", i), window.addEventListener("scroll", i)), () => {
162
+ t.remove(), !s && a.current && a.current.classList.remove("cyber-scrollbar-container"), i && (window.removeEventListener("resize", i), window.removeEventListener("scroll", i));
163
+ };
164
+ }, [w, s, M, U, V, A, z, F, W, R, $]), K = h((r, e) => {
165
+ const n = Math.max(1, Math.min(3, Math.ceil(r * 0.8))), o = Math.floor(e / p.DISTANCE_THRESHOLD);
166
+ return n + o;
167
+ }, []), Y = h((r, e, n) => {
168
+ const o = Array.from(r).filter(
169
+ (d) => d.classList.contains(`cyber-arrow-${e}`)
170
+ ), t = Math.min(n, o.length);
171
+ return e === "up" ? o.slice(-t) : o.slice(0, t);
172
+ }, []), G = h((r, e, n) => {
173
+ const o = Math.min(e * O, p.MAX_ANIMATION_SPEED), t = window.innerWidth < p.MOBILE_BREAKPOINT, d = Math.max(300 / o, p.MIN_GLOW_DURATION) * (t ? 1.5 : 1), l = Math.max(40, 80 / o) * (t ? 1.25 : 1), u = n === "up" ? [...r].reverse() : r;
174
+ u.forEach((i) => {
175
+ i.style.opacity = "0.3";
176
+ }), u.forEach((i, c) => {
177
+ const T = c * l, Z = setTimeout(() => {
178
+ i.style.opacity = "1";
179
+ const ee = setTimeout(() => {
180
+ i.style.opacity = "0.3";
181
+ }, d);
182
+ f.current.push(ee);
183
+ }, T);
184
+ f.current.push(Z);
185
+ });
186
+ }, [O]), X = h(() => {
187
+ if (!m.current) return;
188
+ const { isScrolling: r, direction: e, velocity: n, scrollDistance: o } = N, t = m.current.querySelectorAll(".cyber-arrow"), d = m.current.querySelectorAll(".cyber-line");
189
+ if (r && e) {
190
+ d.forEach((u) => {
191
+ u.style.opacity = "0";
192
+ });
193
+ const l = K(n, o);
194
+ if (l !== L.current) {
195
+ f.current.forEach((i) => clearTimeout(i)), f.current = [], t.forEach((i) => {
196
+ i.style.opacity = "0";
197
+ });
198
+ const u = Y(Array.from(t), e, l);
199
+ G(u, n, e), L.current = l;
200
+ }
201
+ } else
202
+ f.current.forEach((l) => clearTimeout(l)), f.current = [], L.current = 0, t.forEach((l) => {
203
+ l.style.opacity = "0";
204
+ }), x && d.forEach((l) => {
205
+ l.style.opacity = "0.6";
206
+ });
207
+ }, [N, x, G, K, Y]), g = b(null), j = h(() => {
208
+ if (w || !s && !a.current) return;
209
+ const r = Date.now(), e = s ? {
210
+ currentScrollTop: window.scrollY,
211
+ scrollHeight: document.body.scrollHeight,
212
+ clientHeight: window.innerHeight
213
+ } : {
214
+ currentScrollTop: a.current.scrollTop,
215
+ scrollHeight: a.current.scrollHeight,
216
+ clientHeight: a.current.clientHeight
217
+ }, n = r - C.current, o = e.currentScrollTop - _.current, d = Math.abs(o) / Math.max(n, 1) * p.VELOCITY_MULTIPLIER, l = o > 0 ? "down" : o < 0 ? "up" : null, u = e.currentScrollTop / (e.scrollHeight - e.clientHeight);
218
+ x || Q(!0);
219
+ const i = window.innerWidth < p.MOBILE_BREAKPOINT;
220
+ i && !M && P(!0), B((c) => ({
221
+ isScrolling: !0,
222
+ direction: l,
223
+ velocity: d,
224
+ position: u,
225
+ scrollDistance: c.direction !== l ? Math.abs(o) : c.scrollDistance + Math.abs(o)
226
+ })), E.current && clearTimeout(E.current), S.current && clearTimeout(S.current), E.current = setTimeout(() => {
227
+ f.current.forEach((c) => clearTimeout(c)), f.current = [], B((c) => ({
228
+ ...c,
229
+ isScrolling: !1,
230
+ velocity: 0,
231
+ scrollDistance: 0
232
+ })), i && (S.current = setTimeout(() => {
233
+ P(!1);
234
+ }, p.MOBILE_HIDE_DELAY));
235
+ }, p.STABLE_TIMEOUT), C.current = r, _.current = e.currentScrollTop;
236
+ }, [w, s, x, M]), D = h(() => {
237
+ g.current === null && (g.current = requestAnimationFrame(() => {
238
+ g.current = null, j();
239
+ }));
240
+ }, [j]);
241
+ return H(() => {
242
+ if (w || !s && !a.current) return;
243
+ const r = q(), e = s ? window : a.current;
244
+ return e.addEventListener("scroll", D, { passive: !0 }), () => {
245
+ e.removeEventListener("scroll", D), E.current && clearTimeout(E.current), S.current && clearTimeout(S.current), f.current.forEach((n) => clearTimeout(n)), g.current !== null && (cancelAnimationFrame(g.current), g.current = null), r?.();
246
+ };
247
+ }, [q, D, w, s]), H(() => {
248
+ X();
249
+ }, [X]), a;
250
+ };
251
+ export {
252
+ te as useCyberScrollbar
253
+ };
254
+ //# sourceMappingURL=useCyberScrollbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCyberScrollbar.js","sources":["../../src/hooks/useCyberScrollbar.ts"],"sourcesContent":["import { useEffect, useRef, useState, useCallback } from \"react\";\r\n\r\n/**\r\n * Scrollbar background/border style variants\r\n */\r\nexport type ScrollbarVariant = \"default\" | \"minimal\" | \"transparent\";\r\n\r\n/**\r\n * Configuration options for the cyberpunk scrollbar\r\n */\r\nexport interface UseCyberScrollbarOptions {\r\n /** Color theme for the scrollbar glow effects */\r\n glowColor?: \"primary\" | \"secondary\" | \"accent\";\r\n /** Scroll velocity sensitivity multiplier (higher = more responsive) */\r\n sensitivity?: number;\r\n /** Disable the scrollbar completely */\r\n disabled?: boolean;\r\n /** Apply to page-level scrolling instead of container scrolling */\r\n pageLevel?: boolean;\r\n /** Predefined style variant for the scrollbar background (auto-switches to transparent on mobile) */\r\n variant?: ScrollbarVariant;\r\n /** Custom CSS classes to apply to the scrollbar container */\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Internal scroll state tracking\r\n */\r\ninterface ScrollState {\r\n isScrolling: boolean;\r\n direction: \"up\" | \"down\" | null;\r\n velocity: number;\r\n position: number;\r\n scrollDistance: number;\r\n}\r\n\r\nconst CONFIG = {\r\n MOBILE_BREAKPOINT: 768,\r\n STABLE_TIMEOUT: 1000,\r\n MOBILE_HIDE_DELAY: 1000,\r\n VELOCITY_MULTIPLIER: 2,\r\n DISTANCE_THRESHOLD: 100,\r\n MAX_ANIMATION_SPEED: 5,\r\n MIN_GLOW_DURATION: 150,\r\n} as const;\r\n\r\n/**\r\n * Custom hook that creates a cyberpunk-themed scrollbar with animated arrows\r\n * that respond to scroll velocity and direction.\r\n * \r\n * @example\r\n * ```tsx\r\n * const scrollRef = useCyberScrollbar({\r\n * glowColor: 'accent',\r\n * sensitivity: 3,\r\n * variant: 'minimal'\r\n * });\r\n * \r\n * return <div ref={scrollRef} className=\"h-64 overflow-auto\">...</div>;\r\n * ```\r\n *\r\n * @param options Configuration options for the scrollbar\r\n * @returns Ref to attach to scrollable container (not used for pageLevel: true)\r\n */\r\nexport const useCyberScrollbar = (options: UseCyberScrollbarOptions = {}) => {\r\n const {\r\n glowColor = \"primary\",\r\n sensitivity = 2,\r\n disabled = false,\r\n pageLevel,\r\n variant = \"default\",\r\n className = \"\",\r\n } = options;\r\n\r\n const containerRef = useRef<HTMLDivElement>(null);\r\n const scrollbarRef = useRef<HTMLDivElement>(null);\r\n const lastScrollTime = useRef<number>(Date.now());\r\n const lastScrollTop = useRef<number>(0);\r\n const stableTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);\r\n const animationTimeoutsRef = useRef<ReturnType<typeof setTimeout>[]>([]);\r\n const hideTimeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);\r\n const [scrollState, setScrollState] = useState<ScrollState>({\r\n isScrolling: false,\r\n direction: null,\r\n velocity: 0,\r\n position: 0,\r\n scrollDistance: 0,\r\n });\r\n\r\n const [hasEverScrolled, setHasEverScrolled] = useState(false);\r\n const [showScrollbar, setShowScrollbar] = useState(() => {\r\n if (typeof window === \"undefined\") return false;\r\n return window.innerWidth >= CONFIG.MOBILE_BREAKPOINT;\r\n });\r\n const currentArrowCountRef = useRef(0);\r\n const [effectivePageLevel, setEffectivePageLevel] = useState(pageLevel ?? false);\r\n\r\n useEffect(() => {\r\n if (pageLevel !== undefined) {\r\n setEffectivePageLevel(pageLevel);\r\n } else {\r\n const timeoutId = setTimeout(() => {\r\n const isRefAttached = containerRef.current !== null;\r\n setEffectivePageLevel(!isRefAttached);\r\n }, 0);\r\n return () => clearTimeout(timeoutId);\r\n }\r\n }, [pageLevel]);\r\n\r\n const getVariantStyles = useCallback((variant: ScrollbarVariant) => {\r\n switch (variant) {\r\n case \"transparent\":\r\n return {\r\n background: \"transparent\",\r\n backdropFilter: \"none\",\r\n border: \"none\",\r\n boxShadow: \"none\",\r\n };\r\n case \"minimal\":\r\n return {\r\n background: \"rgba(26, 26, 46, 0.6)\",\r\n backdropFilter: \"blur(3px)\",\r\n border: \"1px solid rgba(255, 0, 93, 0.2)\",\r\n boxShadow: \"0 0 5px rgba(255, 0, 93, 0.2)\",\r\n };\r\n case \"default\":\r\n default:\r\n return {\r\n background: \"linear-gradient(180deg, rgba(26, 26, 46, 0.95), rgba(45, 45, 68, 0.95))\",\r\n backdropFilter: \"blur(6px)\",\r\n border: \"1px solid rgba(255, 0, 93, 0.3)\",\r\n boxShadow: \"0 0 10px rgba(255, 0, 93, 0.3), inset 0 0 10px rgba(255, 0, 93, 0.1)\",\r\n };\r\n }\r\n }, []);\r\n const getResponsiveSizes = useCallback(() => {\r\n const isMobile = window.innerWidth < CONFIG.MOBILE_BREAKPOINT;\r\n return {\r\n isMobile,\r\n scrollbarWidth: isMobile ? 12 : 16,\r\n arrowSize: isMobile ? 10 : 14,\r\n lineSize: isMobile ? 8 : 12,\r\n arrowGap: isMobile ? 2 : 4,\r\n };\r\n }, []);\r\n\r\n const calculateMaxArrows = useCallback((scrollbarHeight: number, arrowSize: number, arrowGap: number, lineSize: number) => {\r\n const spaceForLines = (lineSize + arrowGap) * 2;\r\n const paddingSpace = arrowGap * 4;\r\n const remainingHeight = scrollbarHeight - spaceForLines - paddingSpace;\r\n const spacePerDirection = remainingHeight / 2;\r\n return Math.floor(spacePerDirection / (arrowSize + arrowGap));\r\n }, []);\r\n\r\n const hideNativeScrollbars = useCallback((container?: HTMLElement) => {\r\n if (effectivePageLevel) {\r\n if (!document.querySelector(\"#cyber-page-scrollbar-styles\")) {\r\n const style = document.createElement(\"style\");\r\n style.id = \"cyber-page-scrollbar-styles\";\r\n style.textContent = `\r\n html::-webkit-scrollbar { display: none; }\r\n html { scrollbar-width: none; -ms-overflow-style: none; }\r\n `;\r\n document.head.appendChild(style);\r\n }\r\n } else if (container) {\r\n container.style.scrollbarWidth = \"none\";\r\n // @ts-expect-error IE/Edge property\r\n container.style.msOverflowStyle = \"none\";\r\n\r\n if (!document.querySelector(\"#cyber-scrollbar-styles\")) {\r\n const style = document.createElement(\"style\");\r\n style.id = \"cyber-scrollbar-styles\";\r\n style.textContent = `\r\n .cyber-scrollbar-container::-webkit-scrollbar { display: none; }\r\n `;\r\n document.head.appendChild(style);\r\n }\r\n container.classList.add(\"cyber-scrollbar-container\");\r\n }\r\n }, [effectivePageLevel]);\r\n\r\n const createElement = useCallback((\r\n type: \"arrow\" | \"line\",\r\n direction: \"up\" | \"down\" | undefined,\r\n index: number,\r\n sizes: ReturnType<typeof getResponsiveSizes>\r\n ) => {\r\n const element = document.createElement(\"div\");\r\n const isArrow = type === \"arrow\";\r\n\r\n if (isArrow && direction) {\r\n element.className = `cyber-arrow cyber-arrow-${direction} cyber-arrow-${index}`;\r\n element.innerHTML = direction === \"up\" ? \"▲\" : \"▼\";\r\n } else {\r\n element.className = `cyber-line cyber-line-${index}`;\r\n element.innerHTML = \"=\";\r\n }\r\n\r\n const filterCss = sizes.isMobile\r\n ? \"none\"\r\n : `drop-shadow(0 0 6px var(--color-${glowColor}))\r\n drop-shadow(0 0 12px var(--color-${glowColor}))\r\n drop-shadow(0 0 18px var(--color-${glowColor}))`;\r\n\r\n element.style.cssText = `\r\n font-size: ${isArrow ? sizes.arrowSize : sizes.lineSize}px;\r\n color: var(--color-${glowColor});\r\n opacity: 0;\r\n transition: all 0.2s ease;\r\n filter: ${filterCss};\r\n line-height: 1;\r\n font-weight: bold;\r\n `;\r\n return element;\r\n }, [glowColor]);\r\n\r\n const getScrollbarPosition = useCallback(() => {\r\n if (effectivePageLevel) {\r\n return {\r\n height: window.innerHeight,\r\n top: 0,\r\n right: 0,\r\n };\r\n } else {\r\n const container = containerRef.current!;\r\n const rect = container.getBoundingClientRect();\r\n return {\r\n height: rect.height,\r\n top: rect.top,\r\n right: window.innerWidth - rect.right,\r\n };\r\n }\r\n }, [effectivePageLevel]);\r\n\r\n const createScrollbarUI = useCallback(() => {\r\n if (disabled) return;\r\n if (!effectivePageLevel && !containerRef.current) return;\r\n\r\n if (scrollbarRef.current) {\r\n scrollbarRef.current.remove();\r\n }\r\n const needsScrollbar = effectivePageLevel\r\n ? document.body.scrollHeight > window.innerHeight\r\n : containerRef.current!.scrollHeight > containerRef.current!.clientHeight;\r\n\r\n if (!needsScrollbar) return;\r\n\r\n const sizes = getResponsiveSizes();\r\n const position = getScrollbarPosition();\r\n const maxArrows = calculateMaxArrows(position.height, sizes.arrowSize, sizes.arrowGap, sizes.lineSize);\r\n\r\n hideNativeScrollbars(effectivePageLevel ? undefined : containerRef.current || undefined);\r\n const scrollbarElement = document.createElement(\"div\");\r\n scrollbarElement.className = `cyber-scrollbar ${className}`.trim();\r\n\r\n const isMobile = sizes.isMobile;\r\n const effectiveVariant = isMobile ? \"transparent\" : variant;\r\n const variantStyles = getVariantStyles(effectiveVariant);\r\n\r\n scrollbarElement.style.cssText = `\r\n position: fixed;\r\n top: ${position.top}px;\r\n right: ${position.right}px;\r\n width: ${sizes.scrollbarWidth}px;\r\n height: ${position.height}px;\r\n pointer-events: none;\r\n z-index: 9999;\r\n display: ${showScrollbar ? \"flex\" : \"none\"};\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n gap: ${sizes.arrowGap}px;\r\n background: ${variantStyles.background};\r\n backdrop-filter: ${variantStyles.backdropFilter};\r\n border-radius: ${effectivePageLevel ? \"4px 0 0 4px\" : \"4px\"};\r\n border: ${variantStyles.border};\r\n box-shadow: ${variantStyles.boxShadow};\r\n `;\r\n\r\n // Add elements in visual order: up arrows → pause lines → down arrows\r\n for (let i = 0; i < maxArrows; i++) {\r\n scrollbarElement.appendChild(createElement(\"arrow\", \"up\", i, sizes));\r\n }\r\n for (let i = 0; i < 2; i++) {\r\n scrollbarElement.appendChild(createElement(\"line\", undefined, i, sizes));\r\n }\r\n for (let i = 0; i < maxArrows; i++) {\r\n scrollbarElement.appendChild(createElement(\"arrow\", \"down\", i, sizes));\r\n }\r\n\r\n document.body.appendChild(scrollbarElement);\r\n scrollbarRef.current = scrollbarElement;\r\n const updatePosition = effectivePageLevel ? undefined : () => {\r\n const container = containerRef.current;\r\n if (container) {\r\n const newRect = container.getBoundingClientRect();\r\n scrollbarElement.style.top = `${newRect.top}px`;\r\n scrollbarElement.style.right = `${window.innerWidth - newRect.right}px`;\r\n scrollbarElement.style.height = `${newRect.height}px`;\r\n }\r\n };\r\n\r\n if (updatePosition) {\r\n window.addEventListener(\"resize\", updatePosition);\r\n window.addEventListener(\"scroll\", updatePosition);\r\n }\r\n\r\n return () => {\r\n scrollbarElement.remove();\r\n if (!effectivePageLevel && containerRef.current) {\r\n containerRef.current.classList.remove(\"cyber-scrollbar-container\");\r\n }\r\n if (updatePosition) {\r\n window.removeEventListener(\"resize\", updatePosition);\r\n window.removeEventListener(\"scroll\", updatePosition);\r\n }\r\n };\r\n }, [disabled, effectivePageLevel, showScrollbar, hideNativeScrollbars, getScrollbarPosition, createElement, getResponsiveSizes, calculateMaxArrows, getVariantStyles, variant, className]);\r\n\r\n const calculateArrowCount = useCallback((velocity: number, scrollDistance: number) => {\r\n const baseArrowCount = Math.max(1, Math.min(3, Math.ceil(velocity * 0.8)));\r\n const distanceArrowCount = Math.floor(scrollDistance / CONFIG.DISTANCE_THRESHOLD);\r\n return baseArrowCount + distanceArrowCount;\r\n }, []);\r\n\r\n const selectRelevantArrows = useCallback((arrows: Element[], direction: string, totalArrowCount: number) => {\r\n const allDirectionArrows = Array.from(arrows).filter(arrow =>\r\n arrow.classList.contains(`cyber-arrow-${direction}`)\r\n );\r\n\r\n const count = Math.min(totalArrowCount, allDirectionArrows.length);\r\n return direction === 'up'\r\n ? allDirectionArrows.slice(-count)\r\n : allDirectionArrows.slice(0, count);\r\n }, []);\r\n\r\n const animateArrows = useCallback((arrowsToAnimate: Element[], velocity: number, direction: string) => {\r\n const animationSpeed = Math.min(velocity * sensitivity, CONFIG.MAX_ANIMATION_SPEED);\r\n const isMobile = window.innerWidth < CONFIG.MOBILE_BREAKPOINT;\r\n const glowDuration = Math.max(300 / animationSpeed, CONFIG.MIN_GLOW_DURATION) * (isMobile ? 1.5 : 1);\r\n const sequenceDelay = Math.max(40, 80 / animationSpeed) * (isMobile ? 1.25 : 1);\r\n\r\n const arrows = direction === \"up\" ? [...arrowsToAnimate].reverse() : arrowsToAnimate;\r\n\r\n arrows.forEach(arrow => {\r\n (arrow as HTMLElement).style.opacity = \"0.3\";\r\n });\r\n arrows.forEach((arrow, index) => {\r\n const startDelay = index * sequenceDelay;\r\n const glowTimeout = setTimeout(() => {\r\n (arrow as HTMLElement).style.opacity = \"1\";\r\n const fadeTimeout = setTimeout(() => {\r\n (arrow as HTMLElement).style.opacity = \"0.3\";\r\n }, glowDuration);\r\n animationTimeoutsRef.current.push(fadeTimeout);\r\n }, startDelay);\r\n animationTimeoutsRef.current.push(glowTimeout);\r\n });\r\n }, [sensitivity]);\r\n\r\n const updateScrollbarVisuals = useCallback(() => {\r\n if (!scrollbarRef.current) return;\r\n\r\n const { isScrolling, direction, velocity, scrollDistance } = scrollState;\r\n const arrows = scrollbarRef.current.querySelectorAll(\".cyber-arrow\");\r\n const lines = scrollbarRef.current.querySelectorAll(\".cyber-line\");\r\n\r\n if (isScrolling && direction) {\r\n lines.forEach(line => {\r\n (line as HTMLElement).style.opacity = \"0\";\r\n });\r\n\r\n const totalArrowCount = calculateArrowCount(velocity, scrollDistance);\r\n\r\n if (totalArrowCount !== currentArrowCountRef.current) {\r\n animationTimeoutsRef.current.forEach(timeout => clearTimeout(timeout));\r\n animationTimeoutsRef.current = [];\r\n\r\n arrows.forEach(arrow => {\r\n (arrow as HTMLElement).style.opacity = \"0\";\r\n });\r\n\r\n const relevantArrows = selectRelevantArrows(Array.from(arrows), direction, totalArrowCount);\r\n animateArrows(relevantArrows, velocity, direction);\r\n\r\n currentArrowCountRef.current = totalArrowCount;\r\n }\r\n\r\n } else {\r\n animationTimeoutsRef.current.forEach(timeout => clearTimeout(timeout));\r\n animationTimeoutsRef.current = [];\r\n currentArrowCountRef.current = 0;\r\n\r\n arrows.forEach(arrow => {\r\n (arrow as HTMLElement).style.opacity = \"0\";\r\n });\r\n\r\n if (hasEverScrolled) {\r\n lines.forEach(line => {\r\n (line as HTMLElement).style.opacity = \"0.6\";\r\n });\r\n }\r\n }\r\n }, [scrollState, hasEverScrolled, animateArrows, calculateArrowCount, selectRelevantArrows]);\r\n\r\n const rafIdRef = useRef<number | null>(null);\r\n\r\n const processScroll = useCallback(() => {\r\n if (disabled) return;\r\n if (!effectivePageLevel && !containerRef.current) return;\r\n\r\n const now = Date.now();\r\n const scrollInfo = effectivePageLevel\r\n ? {\r\n currentScrollTop: window.scrollY,\r\n scrollHeight: document.body.scrollHeight,\r\n clientHeight: window.innerHeight,\r\n }\r\n : {\r\n currentScrollTop: containerRef.current!.scrollTop,\r\n scrollHeight: containerRef.current!.scrollHeight,\r\n clientHeight: containerRef.current!.clientHeight,\r\n };\r\n\r\n const timeDelta = now - lastScrollTime.current;\r\n const scrollDelta = scrollInfo.currentScrollTop - lastScrollTop.current;\r\n\r\n const rawVelocity = Math.abs(scrollDelta) / Math.max(timeDelta, 1);\r\n const velocity = rawVelocity * CONFIG.VELOCITY_MULTIPLIER;\r\n const direction = scrollDelta > 0 ? \"down\" : scrollDelta < 0 ? \"up\" : null;\r\n const position = scrollInfo.currentScrollTop / (scrollInfo.scrollHeight - scrollInfo.clientHeight);\r\n\r\n if (!hasEverScrolled) {\r\n setHasEverScrolled(true);\r\n }\r\n\r\n const isMobile = window.innerWidth < CONFIG.MOBILE_BREAKPOINT;\r\n if (isMobile && !showScrollbar) {\r\n setShowScrollbar(true);\r\n }\r\n\r\n setScrollState(prev => ({\r\n isScrolling: true,\r\n direction,\r\n velocity,\r\n position,\r\n scrollDistance: prev.direction !== direction ? Math.abs(scrollDelta) : prev.scrollDistance + Math.abs(scrollDelta),\r\n }));\r\n\r\n if (stableTimeoutRef.current) clearTimeout(stableTimeoutRef.current);\r\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\r\n stableTimeoutRef.current = setTimeout(() => {\r\n animationTimeoutsRef.current.forEach(timeout => clearTimeout(timeout));\r\n animationTimeoutsRef.current = [];\r\n\r\n setScrollState(prev => ({\r\n ...prev,\r\n isScrolling: false,\r\n velocity: 0,\r\n scrollDistance: 0,\r\n }));\r\n\r\n if (isMobile) {\r\n hideTimeoutRef.current = setTimeout(() => {\r\n setShowScrollbar(false);\r\n }, CONFIG.MOBILE_HIDE_DELAY);\r\n }\r\n }, CONFIG.STABLE_TIMEOUT);\r\n\r\n lastScrollTime.current = now;\r\n lastScrollTop.current = scrollInfo.currentScrollTop;\r\n }, [disabled, effectivePageLevel, hasEverScrolled, showScrollbar]);\r\n\r\n // Throttle scroll handling to 1 per animation frame\r\n const handleScroll = useCallback(() => {\r\n if (rafIdRef.current !== null) return;\r\n rafIdRef.current = requestAnimationFrame(() => {\r\n rafIdRef.current = null;\r\n processScroll();\r\n });\r\n }, [processScroll]);\r\n useEffect(() => {\r\n if (disabled) return;\r\n if (!effectivePageLevel && !containerRef.current) return;\r\n\r\n const cleanup = createScrollbarUI();\r\n const target = effectivePageLevel ? window : containerRef.current!;\r\n\r\n target.addEventListener(\"scroll\", handleScroll, { passive: true });\r\n\r\n return () => {\r\n target.removeEventListener(\"scroll\", handleScroll);\r\n if (stableTimeoutRef.current) clearTimeout(stableTimeoutRef.current);\r\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\r\n animationTimeoutsRef.current.forEach(timeout => clearTimeout(timeout));\r\n if (rafIdRef.current !== null) {\r\n cancelAnimationFrame(rafIdRef.current);\r\n rafIdRef.current = null;\r\n }\r\n cleanup?.();\r\n };\r\n }, [createScrollbarUI, handleScroll, disabled, effectivePageLevel]);\r\n useEffect(() => {\r\n updateScrollbarVisuals();\r\n }, [updateScrollbarVisuals]);\r\n\r\n return containerRef;\r\n};\r\n"],"names":["CONFIG","useCyberScrollbar","options","glowColor","sensitivity","disabled","pageLevel","variant","className","containerRef","useRef","scrollbarRef","lastScrollTime","lastScrollTop","stableTimeoutRef","animationTimeoutsRef","hideTimeoutRef","scrollState","setScrollState","useState","hasEverScrolled","setHasEverScrolled","showScrollbar","setShowScrollbar","currentArrowCountRef","effectivePageLevel","setEffectivePageLevel","useEffect","timeoutId","isRefAttached","getVariantStyles","useCallback","getResponsiveSizes","isMobile","calculateMaxArrows","scrollbarHeight","arrowSize","arrowGap","lineSize","spaceForLines","paddingSpace","spacePerDirection","hideNativeScrollbars","container","style","createElement","type","direction","index","sizes","element","isArrow","filterCss","getScrollbarPosition","rect","createScrollbarUI","position","maxArrows","scrollbarElement","effectiveVariant","variantStyles","i","updatePosition","newRect","calculateArrowCount","velocity","scrollDistance","baseArrowCount","distanceArrowCount","selectRelevantArrows","arrows","totalArrowCount","allDirectionArrows","arrow","count","animateArrows","arrowsToAnimate","animationSpeed","glowDuration","sequenceDelay","startDelay","glowTimeout","fadeTimeout","updateScrollbarVisuals","isScrolling","lines","line","timeout","relevantArrows","rafIdRef","processScroll","now","scrollInfo","timeDelta","scrollDelta","prev","handleScroll","cleanup","target"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -40,4 +40,4 @@ export * from './components';
40
40
  *
41
41
  * Docs: https://patrickkuei.github.io/CyberUI/storybook/
42
42
  */
43
- export declare const version = "2.3.0";
43
+ export declare const version = "2.4.0";