@opencosmos/ui 1.3.1

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 (260) hide show
  1. package/.claude/CLAUDE.md +239 -0
  2. package/README.md +161 -0
  3. package/dist/cli.mjs +151 -0
  4. package/dist/dates.d.mts +20 -0
  5. package/dist/dates.d.ts +20 -0
  6. package/dist/dates.js +240 -0
  7. package/dist/dates.js.map +1 -0
  8. package/dist/dates.mjs +203 -0
  9. package/dist/dates.mjs.map +1 -0
  10. package/dist/dnd.d.mts +126 -0
  11. package/dist/dnd.d.ts +126 -0
  12. package/dist/dnd.js +274 -0
  13. package/dist/dnd.js.map +1 -0
  14. package/dist/dnd.mjs +250 -0
  15. package/dist/dnd.mjs.map +1 -0
  16. package/dist/fontThemes-Dh8mtXES.d.mts +868 -0
  17. package/dist/fontThemes-Dh8mtXES.d.ts +868 -0
  18. package/dist/forms.d.mts +38 -0
  19. package/dist/forms.d.ts +38 -0
  20. package/dist/forms.js +198 -0
  21. package/dist/forms.js.map +1 -0
  22. package/dist/forms.mjs +159 -0
  23. package/dist/forms.mjs.map +1 -0
  24. package/dist/hooks-1b8WaQf1.d.mts +225 -0
  25. package/dist/hooks-CKW8vE9H.d.ts +225 -0
  26. package/dist/hooks.d.mts +3 -0
  27. package/dist/hooks.d.ts +3 -0
  28. package/dist/hooks.js +971 -0
  29. package/dist/hooks.js.map +1 -0
  30. package/dist/hooks.mjs +943 -0
  31. package/dist/hooks.mjs.map +1 -0
  32. package/dist/index-DscTIrZ2.d.mts +29 -0
  33. package/dist/index-DscTIrZ2.d.ts +29 -0
  34. package/dist/index.d.mts +3382 -0
  35. package/dist/index.d.ts +3382 -0
  36. package/dist/index.js +15146 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/index.mjs +14802 -0
  39. package/dist/index.mjs.map +1 -0
  40. package/dist/providers-CXPDMsl7.d.mts +30 -0
  41. package/dist/providers-Dn_Msjvz.d.ts +30 -0
  42. package/dist/providers.d.mts +3 -0
  43. package/dist/providers.d.ts +3 -0
  44. package/dist/providers.js +1885 -0
  45. package/dist/providers.js.map +1 -0
  46. package/dist/providers.mjs +1859 -0
  47. package/dist/providers.mjs.map +1 -0
  48. package/dist/tables.d.mts +10 -0
  49. package/dist/tables.d.ts +10 -0
  50. package/dist/tables.js +248 -0
  51. package/dist/tables.js.map +1 -0
  52. package/dist/tables.mjs +218 -0
  53. package/dist/tables.mjs.map +1 -0
  54. package/dist/tokens.d.mts +1065 -0
  55. package/dist/tokens.d.ts +1065 -0
  56. package/dist/tokens.js +2637 -0
  57. package/dist/tokens.js.map +1 -0
  58. package/dist/tokens.mjs +2555 -0
  59. package/dist/tokens.mjs.map +1 -0
  60. package/dist/utils-CIIM7dAC.d.ts +986 -0
  61. package/dist/utils-Cs04sxth.d.mts +986 -0
  62. package/dist/utils.d.mts +4 -0
  63. package/dist/utils.d.ts +4 -0
  64. package/dist/utils.js +874 -0
  65. package/dist/utils.js.map +1 -0
  66. package/dist/utils.mjs +806 -0
  67. package/dist/utils.mjs.map +1 -0
  68. package/dist/validation-Bj1ye-v_.d.mts +114 -0
  69. package/dist/validation-Bj1ye-v_.d.ts +114 -0
  70. package/dist/webgl.d.mts +104 -0
  71. package/dist/webgl.d.ts +104 -0
  72. package/dist/webgl.js +226 -0
  73. package/dist/webgl.js.map +1 -0
  74. package/dist/webgl.mjs +195 -0
  75. package/dist/webgl.mjs.map +1 -0
  76. package/package.json +267 -0
  77. package/src/cli.ts +206 -0
  78. package/src/component-registry.ts +183 -0
  79. package/src/components/actions/Button.test.tsx +61 -0
  80. package/src/components/actions/Button.tsx +70 -0
  81. package/src/components/actions/Link.tsx +78 -0
  82. package/src/components/actions/Magnetic.tsx +68 -0
  83. package/src/components/actions/Toggle.test.tsx +40 -0
  84. package/src/components/actions/Toggle.tsx +47 -0
  85. package/src/components/actions/ToggleGroup.tsx +70 -0
  86. package/src/components/actions/index.ts +5 -0
  87. package/src/components/backgrounds/FaultyTerminal.tsx +426 -0
  88. package/src/components/backgrounds/OrbBackground.tsx +424 -0
  89. package/src/components/backgrounds/WarpBackground.tsx +358 -0
  90. package/src/components/backgrounds/index.ts +3 -0
  91. package/src/components/blocks/Hero.tsx +142 -0
  92. package/src/components/blocks/social/OpenGraphCard.tsx +243 -0
  93. package/src/components/cursor/SplashCursor.tsx +1315 -0
  94. package/src/components/cursor/TargetCursor.tsx +187 -0
  95. package/src/components/cursor/index.ts +2 -0
  96. package/src/components/data-display/AspectImage.tsx +73 -0
  97. package/src/components/data-display/Avatar.test.tsx +35 -0
  98. package/src/components/data-display/Avatar.tsx +55 -0
  99. package/src/components/data-display/Badge.test.tsx +43 -0
  100. package/src/components/data-display/Badge.tsx +84 -0
  101. package/src/components/data-display/Brand.tsx +123 -0
  102. package/src/components/data-display/Calendar.tsx +70 -0
  103. package/src/components/data-display/Card.test.tsx +92 -0
  104. package/src/components/data-display/Card.tsx +115 -0
  105. package/src/components/data-display/Code.tsx +210 -0
  106. package/src/components/data-display/CollapsibleCodeBlock.tsx +238 -0
  107. package/src/components/data-display/DataTable.tsx +119 -0
  108. package/src/components/data-display/DescriptionList.tsx +41 -0
  109. package/src/components/data-display/GitHubIcon.tsx +44 -0
  110. package/src/components/data-display/Heading.test.tsx +36 -0
  111. package/src/components/data-display/Heading.tsx +83 -0
  112. package/src/components/data-display/StatCard.tsx +195 -0
  113. package/src/components/data-display/Table.tsx +133 -0
  114. package/src/components/data-display/Text.test.tsx +48 -0
  115. package/src/components/data-display/Text.tsx +144 -0
  116. package/src/components/data-display/Timeline.tsx +194 -0
  117. package/src/components/data-display/TreeView.tsx +226 -0
  118. package/src/components/data-display/Typewriter.tsx +119 -0
  119. package/src/components/data-display/VariableWeightText.tsx +130 -0
  120. package/src/components/data-display/index.ts +19 -0
  121. package/src/components/feedback/Alert.test.tsx +44 -0
  122. package/src/components/feedback/Alert.tsx +65 -0
  123. package/src/components/feedback/EmptyState.tsx +113 -0
  124. package/src/components/feedback/Progress.test.tsx +60 -0
  125. package/src/components/feedback/Progress.tsx +30 -0
  126. package/src/components/feedback/ProgressBar.tsx +158 -0
  127. package/src/components/feedback/Skeleton.test.tsx +39 -0
  128. package/src/components/feedback/Skeleton.tsx +45 -0
  129. package/src/components/feedback/Sonner.tsx +28 -0
  130. package/src/components/feedback/Spinner.test.tsx +33 -0
  131. package/src/components/feedback/Spinner.tsx +99 -0
  132. package/src/components/feedback/Stepper.tsx +307 -0
  133. package/src/components/feedback/Toast/Toast.tsx +243 -0
  134. package/src/components/feedback/Toast/index.ts +2 -0
  135. package/src/components/feedback/index.ts +9 -0
  136. package/src/components/forms/Checkbox.test.tsx +40 -0
  137. package/src/components/forms/Checkbox.tsx +31 -0
  138. package/src/components/forms/ColorPicker.tsx +118 -0
  139. package/src/components/forms/Combobox.tsx +96 -0
  140. package/src/components/forms/DragDrop.tsx +440 -0
  141. package/src/components/forms/FileUpload.tsx +252 -0
  142. package/src/components/forms/FilterButton.tsx +65 -0
  143. package/src/components/forms/Form.tsx +197 -0
  144. package/src/components/forms/Input.test.tsx +46 -0
  145. package/src/components/forms/Input.tsx +43 -0
  146. package/src/components/forms/InputOTP.tsx +81 -0
  147. package/src/components/forms/Label.test.tsx +20 -0
  148. package/src/components/forms/Label.tsx +25 -0
  149. package/src/components/forms/RadioGroup.tsx +51 -0
  150. package/src/components/forms/SearchBar.tsx +215 -0
  151. package/src/components/forms/Select.test.tsx +118 -0
  152. package/src/components/forms/Select.tsx +274 -0
  153. package/src/components/forms/Slider.tsx +29 -0
  154. package/src/components/forms/Switch.test.tsx +76 -0
  155. package/src/components/forms/Switch.tsx +30 -0
  156. package/src/components/forms/TextField.tsx +152 -0
  157. package/src/components/forms/Textarea.test.tsx +41 -0
  158. package/src/components/forms/Textarea.tsx +29 -0
  159. package/src/components/forms/ThemeSwitcher.tsx +290 -0
  160. package/src/components/forms/ThemeToggle.tsx +151 -0
  161. package/src/components/forms/index.ts +19 -0
  162. package/src/components/layout/Accordion.test.tsx +66 -0
  163. package/src/components/layout/Accordion.tsx +64 -0
  164. package/src/components/layout/AspectRatio.tsx +7 -0
  165. package/src/components/layout/Carousel.tsx +277 -0
  166. package/src/components/layout/Collapsible.test.tsx +40 -0
  167. package/src/components/layout/Collapsible.tsx +31 -0
  168. package/src/components/layout/Container.test.tsx +45 -0
  169. package/src/components/layout/Container.tsx +99 -0
  170. package/src/components/layout/CustomizerPanel.tsx +400 -0
  171. package/src/components/layout/DatePicker.tsx +57 -0
  172. package/src/components/layout/Footer/Footer.tsx +175 -0
  173. package/src/components/layout/Footer/index.ts +2 -0
  174. package/src/components/layout/GlassSurface.tsx +82 -0
  175. package/src/components/layout/Grid.test.tsx +31 -0
  176. package/src/components/layout/Grid.tsx +130 -0
  177. package/src/components/layout/Header/Header.tsx +450 -0
  178. package/src/components/layout/Header/index.ts +2 -0
  179. package/src/components/layout/PageLayout.tsx +180 -0
  180. package/src/components/layout/PageTemplate.tsx +158 -0
  181. package/src/components/layout/Resizable.tsx +48 -0
  182. package/src/components/layout/ScrollArea.tsx +53 -0
  183. package/src/components/layout/Separator.test.tsx +28 -0
  184. package/src/components/layout/Separator.tsx +29 -0
  185. package/src/components/layout/Sidebar.tsx +171 -0
  186. package/src/components/layout/Stack.test.tsx +41 -0
  187. package/src/components/layout/Stack.tsx +89 -0
  188. package/src/components/layout/glass-surface.css +60 -0
  189. package/src/components/layout/index.ts +18 -0
  190. package/src/components/motion/AnimatedBeam.tsx +159 -0
  191. package/src/components/navigation/Breadcrumb.test.tsx +57 -0
  192. package/src/components/navigation/Breadcrumb.tsx +119 -0
  193. package/src/components/navigation/Breadcrumbs.tsx +221 -0
  194. package/src/components/navigation/Command.tsx +159 -0
  195. package/src/components/navigation/Menubar.tsx +115 -0
  196. package/src/components/navigation/NavLink.tsx +55 -0
  197. package/src/components/navigation/NavigationMenu.tsx +125 -0
  198. package/src/components/navigation/Pagination.tsx +121 -0
  199. package/src/components/navigation/SecondaryNav.tsx +100 -0
  200. package/src/components/navigation/Tabs.test.tsx +47 -0
  201. package/src/components/navigation/Tabs.tsx +60 -0
  202. package/src/components/navigation/TertiaryNav.tsx +90 -0
  203. package/src/components/navigation/index.ts +10 -0
  204. package/src/components/overlays/AlertDialog.test.tsx +69 -0
  205. package/src/components/overlays/AlertDialog.tsx +166 -0
  206. package/src/components/overlays/ContextMenu.tsx +243 -0
  207. package/src/components/overlays/Dialog.test.tsx +79 -0
  208. package/src/components/overlays/Dialog.tsx +158 -0
  209. package/src/components/overlays/Drawer.tsx +128 -0
  210. package/src/components/overlays/Dropdown.tsx +253 -0
  211. package/src/components/overlays/DropdownMenu.tsx +242 -0
  212. package/src/components/overlays/HoverCard.tsx +32 -0
  213. package/src/components/overlays/Modal.tsx +250 -0
  214. package/src/components/overlays/NotificationCenter.tsx +364 -0
  215. package/src/components/overlays/Popover.test.tsx +40 -0
  216. package/src/components/overlays/Popover.tsx +46 -0
  217. package/src/components/overlays/Sheet.tsx +163 -0
  218. package/src/components/overlays/Tooltip.test.tsx +33 -0
  219. package/src/components/overlays/Tooltip.tsx +32 -0
  220. package/src/components/overlays/index.ts +12 -0
  221. package/src/dates.ts +2 -0
  222. package/src/dnd.ts +1 -0
  223. package/src/forms.ts +1 -0
  224. package/src/globals.css +187 -0
  225. package/src/hooks/index.ts +6 -0
  226. package/src/hooks/useForm.ts +247 -0
  227. package/src/hooks/useMotionPreference.test.ts +102 -0
  228. package/src/hooks/useMotionPreference.ts +78 -0
  229. package/src/hooks/useTheme.ts +58 -0
  230. package/src/hooks.ts +9 -0
  231. package/src/index.ts +168 -0
  232. package/src/lib/animations.ts +356 -0
  233. package/src/lib/breadcrumbs.ts +94 -0
  234. package/src/lib/colors.ts +493 -0
  235. package/src/lib/store/customizer.ts +482 -0
  236. package/src/lib/store/index.ts +3 -0
  237. package/src/lib/store/theme.ts +55 -0
  238. package/src/lib/syntax-parser/index.ts +50 -0
  239. package/src/lib/syntax-parser/patterns.ts +64 -0
  240. package/src/lib/syntax-parser/tokenizer.ts +117 -0
  241. package/src/lib/syntax-parser/types.ts +27 -0
  242. package/src/lib/utils.ts +6 -0
  243. package/src/lib/validation.ts +204 -0
  244. package/src/lib/webgl/Color.ts +11 -0
  245. package/src/lib/webgl/Mesh.ts +41 -0
  246. package/src/lib/webgl/Program.ts +118 -0
  247. package/src/lib/webgl/Renderer.ts +51 -0
  248. package/src/lib/webgl/Triangle.ts +27 -0
  249. package/src/lib/webgl/Vec3.ts +18 -0
  250. package/src/lib/webgl/index.ts +13 -0
  251. package/src/nativewind-env.d.ts +1 -0
  252. package/src/providers/ThemeProvider.tsx +461 -0
  253. package/src/providers/index.ts +1 -0
  254. package/src/providers.ts +7 -0
  255. package/src/tables.ts +1 -0
  256. package/src/test/setup.ts +39 -0
  257. package/src/theme.css +158 -0
  258. package/src/tokens.ts +7 -0
  259. package/src/utils.ts +12 -0
  260. package/src/webgl.ts +1 -0
@@ -0,0 +1,426 @@
1
+ 'use client';
2
+
3
+ import { Renderer, Program, Mesh, Color, Triangle } from '../../lib/webgl';
4
+ import { useEffect, useRef, useMemo, useCallback } from 'react';
5
+
6
+ const vertexShader = `
7
+ attribute vec2 position;
8
+ attribute vec2 uv;
9
+ varying vec2 vUv;
10
+ void main() {
11
+ vUv = uv;
12
+ gl_Position = vec4(position, 0.0, 1.0);
13
+ }
14
+ `;
15
+
16
+ const fragmentShader = `
17
+ precision mediump float;
18
+
19
+ varying vec2 vUv;
20
+
21
+ uniform float iTime;
22
+ uniform vec3 iResolution;
23
+ uniform float uScale;
24
+
25
+ uniform vec2 uGridMul;
26
+ uniform float uDigitSize;
27
+ uniform float uScanlineIntensity;
28
+ uniform float uGlitchAmount;
29
+ uniform float uFlickerAmount;
30
+ uniform float uNoiseAmp;
31
+ uniform float uChromaticAberration;
32
+ uniform float uDither;
33
+ uniform float uCurvature;
34
+ uniform vec3 uTint;
35
+ uniform vec2 uMouse;
36
+ uniform float uMouseStrength;
37
+ uniform float uUseMouse;
38
+ uniform float uPageLoadProgress;
39
+ uniform float uUsePageLoadAnimation;
40
+ uniform float uBrightness;
41
+
42
+ float time;
43
+
44
+ float hash21(vec2 p){
45
+ p = fract(p * 234.56);
46
+ p += dot(p, p + 34.56);
47
+ return fract(p.x * p.y);
48
+ }
49
+
50
+ float noise(vec2 p)
51
+ {
52
+ return sin(p.x * 10.0) * sin(p.y * (3.0 + sin(time * 0.090909))) + 0.2;
53
+ }
54
+
55
+ mat2 rotate(float angle)
56
+ {
57
+ float c = cos(angle);
58
+ float s = sin(angle);
59
+ return mat2(c, -s, s, c);
60
+ }
61
+
62
+ float fbm(vec2 p)
63
+ {
64
+ p *= 1.1;
65
+ float f = 0.0;
66
+ float amp = 0.5 * uNoiseAmp;
67
+
68
+ mat2 modify0 = rotate(time * 0.02);
69
+ f += amp * noise(p);
70
+ p = modify0 * p * 2.0;
71
+ amp *= 0.454545;
72
+
73
+ mat2 modify1 = rotate(time * 0.02);
74
+ f += amp * noise(p);
75
+ p = modify1 * p * 2.0;
76
+ amp *= 0.454545;
77
+
78
+ mat2 modify2 = rotate(time * 0.08);
79
+ f += amp * noise(p);
80
+
81
+ return f;
82
+ }
83
+
84
+ float pattern(vec2 p, out vec2 q, out vec2 r) {
85
+ vec2 offset1 = vec2(1.0);
86
+ vec2 offset0 = vec2(0.0);
87
+ mat2 rot01 = rotate(0.1 * time);
88
+ mat2 rot1 = rotate(0.1);
89
+
90
+ q = vec2(fbm(p + offset1), fbm(rot01 * p + offset1));
91
+ r = vec2(fbm(rot1 * q + offset0), fbm(q + offset0));
92
+ return fbm(p + r);
93
+ }
94
+
95
+ float digit(vec2 p){
96
+ vec2 grid = uGridMul * 15.0;
97
+ vec2 s = floor(p * grid) / grid;
98
+ p = p * grid;
99
+ vec2 q, r;
100
+ float intensity = pattern(s * 0.1, q, r) * 1.3 - 0.03;
101
+
102
+ if(uUseMouse > 0.5){
103
+ vec2 mouseWorld = uMouse * uScale;
104
+ float distToMouse = distance(s, mouseWorld);
105
+ float mouseInfluence = exp(-distToMouse * 8.0) * uMouseStrength * 10.0;
106
+ intensity += mouseInfluence;
107
+
108
+ float ripple = sin(distToMouse * 20.0 - iTime * 5.0) * 0.1 * mouseInfluence;
109
+ intensity += ripple;
110
+ }
111
+
112
+ if(uUsePageLoadAnimation > 0.5){
113
+ float cellRandom = fract(sin(dot(s, vec2(12.9898, 78.233))) * 43758.5453);
114
+ float cellDelay = cellRandom * 0.8;
115
+ float cellProgress = clamp((uPageLoadProgress - cellDelay) / 0.2, 0.0, 1.0);
116
+
117
+ float fadeAlpha = smoothstep(0.0, 1.0, cellProgress);
118
+ intensity *= fadeAlpha;
119
+ }
120
+
121
+ p = fract(p);
122
+ p *= uDigitSize;
123
+
124
+ float px5 = p.x * 5.0;
125
+ float py5 = (1.0 - p.y) * 5.0;
126
+ float x = fract(px5);
127
+ float y = fract(py5);
128
+
129
+ float i = floor(py5) - 2.0;
130
+ float j = floor(px5) - 2.0;
131
+ float n = i * i + j * j;
132
+ float f = n * 0.0625;
133
+
134
+ float isOn = step(0.1, intensity - f);
135
+ float brightness = isOn * (0.2 + y * 0.8) * (0.75 + x * 0.25);
136
+
137
+ return step(0.0, p.x) * step(p.x, 1.0) * step(0.0, p.y) * step(p.y, 1.0) * brightness;
138
+ }
139
+
140
+ float onOff(float a, float b, float c)
141
+ {
142
+ return step(c, sin(iTime + a * cos(iTime * b))) * uFlickerAmount;
143
+ }
144
+
145
+ float displace(vec2 look)
146
+ {
147
+ float y = look.y - mod(iTime * 0.25, 1.0);
148
+ float window = 1.0 / (1.0 + 50.0 * y * y);
149
+ return sin(look.y * 20.0 + iTime) * 0.0125 * onOff(4.0, 2.0, 0.8) * (1.0 + cos(iTime * 60.0)) * window;
150
+ }
151
+
152
+ vec3 getColor(vec2 p){
153
+
154
+ float bar = step(mod(p.y + time * 20.0, 1.0), 0.2) * 0.4 + 1.0;
155
+ bar *= uScanlineIntensity;
156
+
157
+ float displacement = displace(p);
158
+ p.x += displacement;
159
+
160
+ if (uGlitchAmount != 1.0) {
161
+ float extra = displacement * (uGlitchAmount - 1.0);
162
+ p.x += extra;
163
+ }
164
+
165
+ float middle = digit(p);
166
+
167
+ const float off = 0.002;
168
+ float sum = digit(p + vec2(-off, -off)) + digit(p + vec2(0.0, -off)) + digit(p + vec2(off, -off)) +
169
+ digit(p + vec2(-off, 0.0)) + digit(p + vec2(0.0, 0.0)) + digit(p + vec2(off, 0.0)) +
170
+ digit(p + vec2(-off, off)) + digit(p + vec2(0.0, off)) + digit(p + vec2(off, off));
171
+
172
+ vec3 baseColor = vec3(0.9) * middle + sum * 0.1 * vec3(1.0) * bar;
173
+ return baseColor;
174
+ }
175
+
176
+ vec2 barrel(vec2 uv){
177
+ vec2 c = uv * 2.0 - 1.0;
178
+ float r2 = dot(c, c);
179
+ c *= 1.0 + uCurvature * r2;
180
+ return c * 0.5 + 0.5;
181
+ }
182
+
183
+ void main() {
184
+ time = iTime * 0.333333;
185
+ vec2 uv = vUv;
186
+
187
+ if(uCurvature != 0.0){
188
+ uv = barrel(uv);
189
+ }
190
+
191
+ vec2 p = uv * uScale;
192
+ vec3 col = getColor(p);
193
+
194
+ if(uChromaticAberration != 0.0){
195
+ vec2 ca = vec2(uChromaticAberration) / iResolution.xy;
196
+ col.r = getColor(p + ca).r;
197
+ col.b = getColor(p - ca).b;
198
+ }
199
+
200
+ col *= uTint;
201
+ col *= uBrightness;
202
+
203
+ if(uDither > 0.0){
204
+ float rnd = hash21(gl_FragCoord.xy);
205
+ col += (rnd - 0.5) * (uDither * 0.003922);
206
+ }
207
+
208
+ gl_FragColor = vec4(col, 1.0);
209
+ }
210
+ `;
211
+
212
+ function hexToRgb(hex: string) {
213
+ let h = hex.replace('#', '').trim();
214
+ if (h.length === 3)
215
+ h = h
216
+ .split('')
217
+ .map(c => c + c)
218
+ .join('');
219
+ const num = parseInt(h, 16);
220
+ return [((num >> 16) & 255) / 255, ((num >> 8) & 255) / 255, (num & 255) / 255];
221
+ }
222
+
223
+ interface FaultyTerminalProps {
224
+ scale?: number;
225
+ gridMul?: [number, number];
226
+ digitSize?: number;
227
+ timeScale?: number;
228
+ pause?: boolean;
229
+ scanlineIntensity?: number;
230
+ glitchAmount?: number;
231
+ flickerAmount?: number;
232
+ noiseAmp?: number;
233
+ chromaticAberration?: number;
234
+ dither?: number | boolean;
235
+ curvature?: number;
236
+ tint?: string;
237
+ mouseReact?: boolean;
238
+ mouseStrength?: number;
239
+ dpr?: number;
240
+ pageLoadAnimation?: boolean;
241
+ brightness?: number;
242
+ className?: string;
243
+ style?: React.CSSProperties;
244
+ [key: string]: any;
245
+ }
246
+
247
+ export function FaultyTerminal({
248
+ scale = 1,
249
+ gridMul = [2, 1],
250
+ digitSize = 1.5,
251
+ timeScale = 0.3,
252
+ pause = false,
253
+ scanlineIntensity = 0.3,
254
+ glitchAmount = 1,
255
+ flickerAmount = 1,
256
+ noiseAmp = 0,
257
+ chromaticAberration = 0,
258
+ dither = 0,
259
+ curvature = 0.2,
260
+ tint = '#ffffff',
261
+ mouseReact = true,
262
+ mouseStrength = 0.2,
263
+ dpr = 1, // Defaulting loosely, avoid window access in default param if SSR
264
+ pageLoadAnimation = true,
265
+ brightness = 1,
266
+ className = '',
267
+ style,
268
+ ...rest
269
+ }: FaultyTerminalProps) {
270
+ const containerRef = useRef<HTMLDivElement>(null);
271
+ const programRef = useRef<Program | null>(null);
272
+ const rendererRef = useRef<Renderer | null>(null);
273
+ const mouseRef = useRef({ x: 0.5, y: 0.5 });
274
+ const smoothMouseRef = useRef({ x: 0.5, y: 0.5 });
275
+ const frozenTimeRef = useRef(0);
276
+ const rafRef = useRef(0);
277
+ const loadAnimationStartRef = useRef(0);
278
+ const timeOffsetRef = useRef(Math.random() * 100);
279
+
280
+ const tintVec = useMemo(() => hexToRgb(tint), [tint]);
281
+
282
+ const ditherValue = useMemo(() => (typeof dither === 'boolean' ? (dither ? 1 : 0) : dither), [dither]);
283
+
284
+ const handleMouseMove = useCallback((e: MouseEvent) => {
285
+ const ctn = containerRef.current;
286
+ if (!ctn) return;
287
+ const rect = ctn.getBoundingClientRect();
288
+ const x = (e.clientX - rect.left) / rect.width;
289
+ const y = 1 - (e.clientY - rect.top) / rect.height;
290
+ mouseRef.current = { x, y };
291
+ }, []);
292
+
293
+ useEffect(() => {
294
+ const ctn = containerRef.current;
295
+ if (!ctn) return;
296
+
297
+ const renderer = new Renderer({ dpr });
298
+ rendererRef.current = renderer;
299
+ const gl = renderer.gl;
300
+ gl.clearColor(0, 0, 0, 1);
301
+
302
+ const geometry = new Triangle(gl);
303
+
304
+ const program = new Program(gl, {
305
+ vertex: vertexShader,
306
+ fragment: fragmentShader,
307
+ uniforms: {
308
+ iTime: { value: 0 },
309
+ iResolution: {
310
+ value: new Color(gl.canvas.width, gl.canvas.height, gl.canvas.width / gl.canvas.height)
311
+ },
312
+ uScale: { value: scale },
313
+
314
+ uGridMul: { value: new Float32Array(gridMul) },
315
+ uDigitSize: { value: digitSize },
316
+ uScanlineIntensity: { value: scanlineIntensity },
317
+ uGlitchAmount: { value: glitchAmount },
318
+ uFlickerAmount: { value: flickerAmount },
319
+ uNoiseAmp: { value: noiseAmp },
320
+ uChromaticAberration: { value: chromaticAberration },
321
+ uDither: { value: ditherValue },
322
+ uCurvature: { value: curvature },
323
+ uTint: { value: new Color(tintVec[0], tintVec[1], tintVec[2]) },
324
+ uMouse: {
325
+ value: new Float32Array([smoothMouseRef.current.x, smoothMouseRef.current.y])
326
+ },
327
+ uMouseStrength: { value: mouseStrength },
328
+ uUseMouse: { value: mouseReact ? 1 : 0 },
329
+ uPageLoadProgress: { value: pageLoadAnimation ? 0 : 1 },
330
+ uUsePageLoadAnimation: { value: 1 },
331
+ uBrightness: { value: brightness }
332
+ }
333
+ });
334
+ programRef.current = program;
335
+
336
+ const mesh = new Mesh(gl, { geometry, program });
337
+
338
+ function resize() {
339
+ if (!ctn || !renderer) return;
340
+ renderer.setSize(ctn.offsetWidth, ctn.offsetHeight);
341
+ program.uniforms.iResolution.value = new Color(
342
+ gl.canvas.width,
343
+ gl.canvas.height,
344
+ gl.canvas.width / gl.canvas.height
345
+ );
346
+ }
347
+
348
+ const resizeObserver = new ResizeObserver(() => resize());
349
+ resizeObserver.observe(ctn);
350
+ resize();
351
+
352
+ const update = (t: number) => {
353
+ rafRef.current = requestAnimationFrame(update);
354
+
355
+ if (pageLoadAnimation) {
356
+ if (loadAnimationStartRef.current === 0) {
357
+ loadAnimationStartRef.current = t;
358
+ }
359
+ const animationDuration = 2000;
360
+ const animationElapsed = t - loadAnimationStartRef.current;
361
+ const progress = Math.min(animationElapsed / animationDuration, 1);
362
+ program.uniforms.uPageLoadProgress.value = progress;
363
+ } else {
364
+ program.uniforms.uPageLoadProgress.value = 1.0;
365
+ }
366
+
367
+ if (!pause) {
368
+ const elapsed = (t * 0.001 + timeOffsetRef.current) * timeScale;
369
+ program.uniforms.iTime.value = elapsed;
370
+ frozenTimeRef.current = elapsed;
371
+ } else {
372
+ program.uniforms.iTime.value = frozenTimeRef.current;
373
+ }
374
+
375
+ if (mouseReact) {
376
+ const dampingFactor = 0.08;
377
+ const smoothMouse = smoothMouseRef.current;
378
+ const mouse = mouseRef.current;
379
+ smoothMouse.x += (mouse.x - smoothMouse.x) * dampingFactor;
380
+ smoothMouse.y += (mouse.y - smoothMouse.y) * dampingFactor;
381
+
382
+ const mouseUniform = program.uniforms.uMouse.value;
383
+ mouseUniform[0] = smoothMouse.x;
384
+ mouseUniform[1] = smoothMouse.y;
385
+ }
386
+
387
+ renderer.render({ scene: mesh });
388
+ };
389
+ rafRef.current = requestAnimationFrame(update);
390
+ ctn.appendChild(gl.canvas);
391
+
392
+ if (mouseReact) ctn.addEventListener('mousemove', handleMouseMove);
393
+
394
+ return () => {
395
+ cancelAnimationFrame(rafRef.current);
396
+ resizeObserver.disconnect();
397
+ if (mouseReact) ctn.removeEventListener('mousemove', handleMouseMove);
398
+ if (gl.canvas.parentElement === ctn) ctn.removeChild(gl.canvas);
399
+ gl.getExtension('WEBGL_lose_context')?.loseContext();
400
+ loadAnimationStartRef.current = 0;
401
+ timeOffsetRef.current = Math.random() * 100;
402
+ };
403
+ }, [
404
+ dpr,
405
+ pause,
406
+ timeScale,
407
+ scale,
408
+ gridMul,
409
+ digitSize,
410
+ scanlineIntensity,
411
+ glitchAmount,
412
+ flickerAmount,
413
+ noiseAmp,
414
+ chromaticAberration,
415
+ ditherValue,
416
+ curvature,
417
+ tintVec,
418
+ mouseReact,
419
+ mouseStrength,
420
+ pageLoadAnimation,
421
+ brightness,
422
+ handleMouseMove
423
+ ]);
424
+
425
+ return <div ref={containerRef} className={`w-full h-full relative overflow-hidden ${className}`} style={style} {...rest} />;
426
+ }