create-weave-frontend-app 0.1.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 (272) hide show
  1. package/README.md +11 -0
  2. package/dist/chunk-HZJMO45D.js +437 -0
  3. package/dist/create-app.d.ts +14 -0
  4. package/dist/create-app.js +6 -0
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.js +106 -0
  7. package/package.json +65 -0
  8. package/template/+nextjs+azure-web-pubsub/README.md +36 -0
  9. package/template/+nextjs+azure-web-pubsub/api/del-image.ts +8 -0
  10. package/template/+nextjs+azure-web-pubsub/api/get-images.ts +15 -0
  11. package/template/+nextjs+azure-web-pubsub/api/post-image.ts +14 -0
  12. package/template/+nextjs+azure-web-pubsub/api/post-remove-background.ts +10 -0
  13. package/template/+nextjs+azure-web-pubsub/app/error/page.tsx +10 -0
  14. package/template/+nextjs+azure-web-pubsub/app/favicon.ico +0 -0
  15. package/template/+nextjs+azure-web-pubsub/app/globals.css +193 -0
  16. package/template/+nextjs+azure-web-pubsub/app/layout.tsx +46 -0
  17. package/template/+nextjs+azure-web-pubsub/app/page.tsx +7 -0
  18. package/template/+nextjs+azure-web-pubsub/app/providers.tsx +18 -0
  19. package/template/+nextjs+azure-web-pubsub/app/room/[roomId]/page.tsx +5 -0
  20. package/template/+nextjs+azure-web-pubsub/assets/images/home.png +0 -0
  21. package/template/+nextjs+azure-web-pubsub/assets/images/logo.png +0 -0
  22. package/template/+nextjs+azure-web-pubsub/components/actions/align-elements-tool/align-elements-tool.ts +94 -0
  23. package/template/+nextjs+azure-web-pubsub/components/actions/color-token-tool/color-token-tool.ts +164 -0
  24. package/template/+nextjs+azure-web-pubsub/components/actions/color-token-tool/constants.ts +5 -0
  25. package/template/+nextjs+azure-web-pubsub/components/actions/color-token-tool/types.ts +12 -0
  26. package/template/+nextjs+azure-web-pubsub/components/error/error.tsx +62 -0
  27. package/template/+nextjs+azure-web-pubsub/components/error/errors.ts +35 -0
  28. package/template/+nextjs+azure-web-pubsub/components/home/home.tsx +92 -0
  29. package/template/+nextjs+azure-web-pubsub/components/home-components/home-showcase-animation.tsx +119 -0
  30. package/template/+nextjs+azure-web-pubsub/components/home-components/login-form.tsx +117 -0
  31. package/template/+nextjs+azure-web-pubsub/components/nodes/color-token/color-token.ts +171 -0
  32. package/template/+nextjs+azure-web-pubsub/components/room/room.layout.tsx +115 -0
  33. package/template/+nextjs+azure-web-pubsub/components/room/room.tsx +125 -0
  34. package/template/+nextjs+azure-web-pubsub/components/room-components/color-tokens-library/color-token.tsx +31 -0
  35. package/template/+nextjs+azure-web-pubsub/components/room-components/color-tokens-library/color-tokens-library.tsx +64 -0
  36. package/template/+nextjs+azure-web-pubsub/components/room-components/connected-users.tsx +152 -0
  37. package/template/+nextjs+azure-web-pubsub/components/room-components/connection-status.tsx +52 -0
  38. package/template/+nextjs+azure-web-pubsub/components/room-components/context-menu.tsx +152 -0
  39. package/template/+nextjs+azure-web-pubsub/components/room-components/frames-library/frames-library.image.tsx +48 -0
  40. package/template/+nextjs+azure-web-pubsub/components/room-components/frames-library/frames-library.presentation-image.tsx +61 -0
  41. package/template/+nextjs+azure-web-pubsub/components/room-components/frames-library/frames-library.tsx +316 -0
  42. package/template/+nextjs+azure-web-pubsub/components/room-components/frames-library/utils.ts +27 -0
  43. package/template/+nextjs+azure-web-pubsub/components/room-components/help/help-arrange.tsx +69 -0
  44. package/template/+nextjs+azure-web-pubsub/components/room-components/help/help-drawer.tsx +140 -0
  45. package/template/+nextjs+azure-web-pubsub/components/room-components/help/help-edit.tsx +80 -0
  46. package/template/+nextjs+azure-web-pubsub/components/room-components/help/help-selection.tsx +30 -0
  47. package/template/+nextjs+azure-web-pubsub/components/room-components/help/help-shortcut-element.tsx +24 -0
  48. package/template/+nextjs+azure-web-pubsub/components/room-components/help/help-tools.tsx +89 -0
  49. package/template/+nextjs+azure-web-pubsub/components/room-components/help/help-view.tsx +30 -0
  50. package/template/+nextjs+azure-web-pubsub/components/room-components/help/help-zoom.tsx +46 -0
  51. package/template/+nextjs+azure-web-pubsub/components/room-components/help/shortcut-element.tsx +42 -0
  52. package/template/+nextjs+azure-web-pubsub/components/room-components/hooks/use-context-menu.tsx +514 -0
  53. package/template/+nextjs+azure-web-pubsub/components/room-components/hooks/use-get-azure-web-pubsub-provider.ts +78 -0
  54. package/template/+nextjs+azure-web-pubsub/components/room-components/hooks/use-get-os.ts +12 -0
  55. package/template/+nextjs+azure-web-pubsub/components/room-components/hooks/use-get-weave-js-props.tsx +120 -0
  56. package/template/+nextjs+azure-web-pubsub/components/room-components/hooks/use-handle-route-params.ts +30 -0
  57. package/template/+nextjs+azure-web-pubsub/components/room-components/hooks/use-key-down.ts +29 -0
  58. package/template/+nextjs+azure-web-pubsub/components/room-components/hooks/use-keyboard-handler.tsx +557 -0
  59. package/template/+nextjs+azure-web-pubsub/components/room-components/images-library/images-library.tsx +146 -0
  60. package/template/+nextjs+azure-web-pubsub/components/room-components/inputs/input-color.tsx +101 -0
  61. package/template/+nextjs+azure-web-pubsub/components/room-components/inputs/input-font-family.tsx +99 -0
  62. package/template/+nextjs+azure-web-pubsub/components/room-components/inputs/input-number.tsx +61 -0
  63. package/template/+nextjs+azure-web-pubsub/components/room-components/inputs/input-text.tsx +51 -0
  64. package/template/+nextjs+azure-web-pubsub/components/room-components/inputs/number-input.tsx +107 -0
  65. package/template/+nextjs+azure-web-pubsub/components/room-components/node-properties/appearance-properties.tsx +119 -0
  66. package/template/+nextjs+azure-web-pubsub/components/room-components/node-properties/color-token-properties.tsx +108 -0
  67. package/template/+nextjs+azure-web-pubsub/components/room-components/node-properties/crop-properties.tsx +156 -0
  68. package/template/+nextjs+azure-web-pubsub/components/room-components/node-properties/fill-properties.tsx +115 -0
  69. package/template/+nextjs+azure-web-pubsub/components/room-components/node-properties/frame-properties.tsx +100 -0
  70. package/template/+nextjs+azure-web-pubsub/components/room-components/node-properties/image-properties.tsx +57 -0
  71. package/template/+nextjs+azure-web-pubsub/components/room-components/node-properties/position-properties.tsx +156 -0
  72. package/template/+nextjs+azure-web-pubsub/components/room-components/node-properties/size-properties.tsx +131 -0
  73. package/template/+nextjs+azure-web-pubsub/components/room-components/node-properties/stroke-properties.tsx +327 -0
  74. package/template/+nextjs+azure-web-pubsub/components/room-components/node-properties/text-properties.tsx +467 -0
  75. package/template/+nextjs+azure-web-pubsub/components/room-components/overlay/multiuse-overlay.tsx +127 -0
  76. package/template/+nextjs+azure-web-pubsub/components/room-components/overlay/node-properties.tsx +98 -0
  77. package/template/+nextjs+azure-web-pubsub/components/room-components/overlay/overlay-animation-wrapper.tsx +31 -0
  78. package/template/+nextjs+azure-web-pubsub/components/room-components/overlay/room-information-overlay.tsx +247 -0
  79. package/template/+nextjs+azure-web-pubsub/components/room-components/overlay/room-users-overlay.tsx +31 -0
  80. package/template/+nextjs+azure-web-pubsub/components/room-components/overlay/tools-overlay.tsx +289 -0
  81. package/template/+nextjs+azure-web-pubsub/components/room-components/overlay/variants.ts +58 -0
  82. package/template/+nextjs+azure-web-pubsub/components/room-components/overlay/zoom-handler-overlay.tsx +447 -0
  83. package/template/+nextjs+azure-web-pubsub/components/room-components/room-error.tsx +37 -0
  84. package/template/+nextjs+azure-web-pubsub/components/room-components/room-loader/room-loader.tsx +98 -0
  85. package/template/+nextjs+azure-web-pubsub/components/room-components/selection-information.tsx +74 -0
  86. package/template/+nextjs+azure-web-pubsub/components/room-components/toggle-icon-button.tsx +60 -0
  87. package/template/+nextjs+azure-web-pubsub/components/room-components/toolbar/toolbar-button.tsx +60 -0
  88. package/template/+nextjs+azure-web-pubsub/components/room-components/toolbar/toolbar-toggle-button.tsx +40 -0
  89. package/template/+nextjs+azure-web-pubsub/components/room-components/toolbar/toolbar.tsx +28 -0
  90. package/template/+nextjs+azure-web-pubsub/components/room-components/upload-file.tsx +130 -0
  91. package/template/+nextjs+azure-web-pubsub/components/room-components/with-instance-node.tsx +53 -0
  92. package/template/+nextjs+azure-web-pubsub/components/ui/accordion.tsx +66 -0
  93. package/template/+nextjs+azure-web-pubsub/components/ui/avatar.tsx +53 -0
  94. package/template/+nextjs+azure-web-pubsub/components/ui/button.tsx +58 -0
  95. package/template/+nextjs+azure-web-pubsub/components/ui/card.tsx +68 -0
  96. package/template/+nextjs+azure-web-pubsub/components/ui/checkbox.tsx +32 -0
  97. package/template/+nextjs+azure-web-pubsub/components/ui/color-picker/color-picker-component.tsx +69 -0
  98. package/template/+nextjs+azure-web-pubsub/components/ui/color-picker/context/color-picker-context.tsx +28 -0
  99. package/template/+nextjs+azure-web-pubsub/components/ui/color-picker/editor/color-picker-format-editor.tsx +34 -0
  100. package/template/+nextjs+azure-web-pubsub/components/ui/color-picker/index.ts +7 -0
  101. package/template/+nextjs+azure-web-pubsub/components/ui/color-picker/selector/color-picker-alpha.tsx +79 -0
  102. package/template/+nextjs+azure-web-pubsub/components/ui/color-picker/selector/color-picker-eyedropper.tsx +95 -0
  103. package/template/+nextjs+azure-web-pubsub/components/ui/color-picker/selector/color-picker-format-selector.tsx +50 -0
  104. package/template/+nextjs+azure-web-pubsub/components/ui/color-picker/selector/color-picker-hue.tsx +67 -0
  105. package/template/+nextjs+azure-web-pubsub/components/ui/color-picker/selector/color-picker-saturation.tsx +145 -0
  106. package/template/+nextjs+azure-web-pubsub/components/ui/color-picker/text-inputs/color-picker-alpha-percentage.tsx +60 -0
  107. package/template/+nextjs+azure-web-pubsub/components/ui/color-picker/text-inputs/color-picker-hexa.tsx +65 -0
  108. package/template/+nextjs+azure-web-pubsub/components/ui/color-picker/text-inputs/color-picker-rgba.tsx +62 -0
  109. package/template/+nextjs+azure-web-pubsub/components/ui/command.tsx +177 -0
  110. package/template/+nextjs+azure-web-pubsub/components/ui/dialog.tsx +135 -0
  111. package/template/+nextjs+azure-web-pubsub/components/ui/drawer.tsx +132 -0
  112. package/template/+nextjs+azure-web-pubsub/components/ui/dropdown-menu.tsx +201 -0
  113. package/template/+nextjs+azure-web-pubsub/components/ui/form.tsx +167 -0
  114. package/template/+nextjs+azure-web-pubsub/components/ui/input.tsx +21 -0
  115. package/template/+nextjs+azure-web-pubsub/components/ui/label.tsx +24 -0
  116. package/template/+nextjs+azure-web-pubsub/components/ui/popover.tsx +48 -0
  117. package/template/+nextjs+azure-web-pubsub/components/ui/reactbits/Backgrounds/Dither/Dither.tsx +350 -0
  118. package/template/+nextjs+azure-web-pubsub/components/ui/reactbits/Backgrounds/Threads/Threads.tsx +239 -0
  119. package/template/+nextjs+azure-web-pubsub/components/ui/reactbits/TextAnimations/RotatingText/RotatingText.tsx +276 -0
  120. package/template/+nextjs+azure-web-pubsub/components/ui/scroll-area.tsx +58 -0
  121. package/template/+nextjs+azure-web-pubsub/components/ui/select.tsx +185 -0
  122. package/template/+nextjs+azure-web-pubsub/components/ui/sheet.tsx +139 -0
  123. package/template/+nextjs+azure-web-pubsub/components/ui/sonner.tsx +25 -0
  124. package/template/+nextjs+azure-web-pubsub/components/ui/tabs.tsx +66 -0
  125. package/template/+nextjs+azure-web-pubsub/components/ui/tooltip.tsx +61 -0
  126. package/template/+nextjs+azure-web-pubsub/components/utils/constants.ts +118 -0
  127. package/template/+nextjs+azure-web-pubsub/components/utils/logo.tsx +34 -0
  128. package/template/+nextjs+azure-web-pubsub/components.json +21 -0
  129. package/template/+nextjs+azure-web-pubsub/example.env +2 -0
  130. package/template/+nextjs+azure-web-pubsub/example.gitignore +44 -0
  131. package/template/+nextjs+azure-web-pubsub/jsrepo.json +11 -0
  132. package/template/+nextjs+azure-web-pubsub/lib/utils.ts +43 -0
  133. package/template/+nextjs+azure-web-pubsub/new-types.d.ts +8 -0
  134. package/template/+nextjs+azure-web-pubsub/next-env.d.ts +5 -0
  135. package/template/+nextjs+azure-web-pubsub/next.config.js +52 -0
  136. package/template/+nextjs+azure-web-pubsub/postcss.config.mjs +5 -0
  137. package/template/+nextjs+azure-web-pubsub/store/store.ts +241 -0
  138. package/template/+nextjs+azure-web-pubsub/tsconfig.json +37 -0
  139. package/template/+nextjs+azure-web-pubsub/vitest.config.mts +10 -0
  140. package/template/+nextjs+websockets/README.md +39 -0
  141. package/template/+nextjs+websockets/api/del-image.ts +8 -0
  142. package/template/+nextjs+websockets/api/get-images.ts +15 -0
  143. package/template/+nextjs+websockets/api/post-image.ts +14 -0
  144. package/template/+nextjs+websockets/api/post-remove-background.ts +10 -0
  145. package/template/+nextjs+websockets/app/error/page.tsx +10 -0
  146. package/template/+nextjs+websockets/app/favicon.ico +0 -0
  147. package/template/+nextjs+websockets/app/globals.css +193 -0
  148. package/template/+nextjs+websockets/app/layout.tsx +46 -0
  149. package/template/+nextjs+websockets/app/page.tsx +7 -0
  150. package/template/+nextjs+websockets/app/providers.tsx +18 -0
  151. package/template/+nextjs+websockets/app/room/[roomId]/page.tsx +5 -0
  152. package/template/+nextjs+websockets/assets/images/home.png +0 -0
  153. package/template/+nextjs+websockets/assets/images/logo.png +0 -0
  154. package/template/+nextjs+websockets/components/actions/align-elements-tool/align-elements-tool.ts +94 -0
  155. package/template/+nextjs+websockets/components/actions/color-token-tool/color-token-tool.ts +164 -0
  156. package/template/+nextjs+websockets/components/actions/color-token-tool/constants.ts +5 -0
  157. package/template/+nextjs+websockets/components/actions/color-token-tool/types.ts +12 -0
  158. package/template/+nextjs+websockets/components/error/error.tsx +62 -0
  159. package/template/+nextjs+websockets/components/error/errors.ts +35 -0
  160. package/template/+nextjs+websockets/components/home/home.tsx +92 -0
  161. package/template/+nextjs+websockets/components/home-components/home-showcase-animation.tsx +119 -0
  162. package/template/+nextjs+websockets/components/home-components/login-form.tsx +117 -0
  163. package/template/+nextjs+websockets/components/nodes/color-token/color-token.ts +171 -0
  164. package/template/+nextjs+websockets/components/room/room.layout.tsx +115 -0
  165. package/template/+nextjs+websockets/components/room/room.tsx +125 -0
  166. package/template/+nextjs+websockets/components/room-components/color-tokens-library/color-token.tsx +31 -0
  167. package/template/+nextjs+websockets/components/room-components/color-tokens-library/color-tokens-library.tsx +64 -0
  168. package/template/+nextjs+websockets/components/room-components/connected-users.tsx +152 -0
  169. package/template/+nextjs+websockets/components/room-components/connection-status.tsx +52 -0
  170. package/template/+nextjs+websockets/components/room-components/context-menu.tsx +152 -0
  171. package/template/+nextjs+websockets/components/room-components/frames-library/frames-library.image.tsx +48 -0
  172. package/template/+nextjs+websockets/components/room-components/frames-library/frames-library.presentation-image.tsx +61 -0
  173. package/template/+nextjs+websockets/components/room-components/frames-library/frames-library.tsx +316 -0
  174. package/template/+nextjs+websockets/components/room-components/frames-library/utils.ts +27 -0
  175. package/template/+nextjs+websockets/components/room-components/help/help-arrange.tsx +69 -0
  176. package/template/+nextjs+websockets/components/room-components/help/help-drawer.tsx +140 -0
  177. package/template/+nextjs+websockets/components/room-components/help/help-edit.tsx +80 -0
  178. package/template/+nextjs+websockets/components/room-components/help/help-selection.tsx +30 -0
  179. package/template/+nextjs+websockets/components/room-components/help/help-shortcut-element.tsx +24 -0
  180. package/template/+nextjs+websockets/components/room-components/help/help-tools.tsx +89 -0
  181. package/template/+nextjs+websockets/components/room-components/help/help-view.tsx +30 -0
  182. package/template/+nextjs+websockets/components/room-components/help/help-zoom.tsx +46 -0
  183. package/template/+nextjs+websockets/components/room-components/help/shortcut-element.tsx +42 -0
  184. package/template/+nextjs+websockets/components/room-components/hooks/use-context-menu.tsx +514 -0
  185. package/template/+nextjs+websockets/components/room-components/hooks/use-get-os.ts +12 -0
  186. package/template/+nextjs+websockets/components/room-components/hooks/use-get-weave-js-props.tsx +120 -0
  187. package/template/+nextjs+websockets/components/room-components/hooks/use-get-websockets-provider.ts +79 -0
  188. package/template/+nextjs+websockets/components/room-components/hooks/use-handle-route-params.ts +30 -0
  189. package/template/+nextjs+websockets/components/room-components/hooks/use-key-down.ts +29 -0
  190. package/template/+nextjs+websockets/components/room-components/hooks/use-keyboard-handler.tsx +557 -0
  191. package/template/+nextjs+websockets/components/room-components/images-library/images-library.tsx +146 -0
  192. package/template/+nextjs+websockets/components/room-components/inputs/input-color.tsx +101 -0
  193. package/template/+nextjs+websockets/components/room-components/inputs/input-font-family.tsx +99 -0
  194. package/template/+nextjs+websockets/components/room-components/inputs/input-number.tsx +61 -0
  195. package/template/+nextjs+websockets/components/room-components/inputs/input-text.tsx +51 -0
  196. package/template/+nextjs+websockets/components/room-components/inputs/number-input.tsx +107 -0
  197. package/template/+nextjs+websockets/components/room-components/node-properties/appearance-properties.tsx +119 -0
  198. package/template/+nextjs+websockets/components/room-components/node-properties/color-token-properties.tsx +108 -0
  199. package/template/+nextjs+websockets/components/room-components/node-properties/crop-properties.tsx +156 -0
  200. package/template/+nextjs+websockets/components/room-components/node-properties/fill-properties.tsx +115 -0
  201. package/template/+nextjs+websockets/components/room-components/node-properties/frame-properties.tsx +100 -0
  202. package/template/+nextjs+websockets/components/room-components/node-properties/image-properties.tsx +57 -0
  203. package/template/+nextjs+websockets/components/room-components/node-properties/position-properties.tsx +156 -0
  204. package/template/+nextjs+websockets/components/room-components/node-properties/size-properties.tsx +131 -0
  205. package/template/+nextjs+websockets/components/room-components/node-properties/stroke-properties.tsx +327 -0
  206. package/template/+nextjs+websockets/components/room-components/node-properties/text-properties.tsx +467 -0
  207. package/template/+nextjs+websockets/components/room-components/overlay/multiuse-overlay.tsx +127 -0
  208. package/template/+nextjs+websockets/components/room-components/overlay/node-properties.tsx +98 -0
  209. package/template/+nextjs+websockets/components/room-components/overlay/overlay-animation-wrapper.tsx +31 -0
  210. package/template/+nextjs+websockets/components/room-components/overlay/room-information-overlay.tsx +247 -0
  211. package/template/+nextjs+websockets/components/room-components/overlay/room-users-overlay.tsx +31 -0
  212. package/template/+nextjs+websockets/components/room-components/overlay/tools-overlay.tsx +289 -0
  213. package/template/+nextjs+websockets/components/room-components/overlay/variants.ts +58 -0
  214. package/template/+nextjs+websockets/components/room-components/overlay/zoom-handler-overlay.tsx +447 -0
  215. package/template/+nextjs+websockets/components/room-components/room-error.tsx +37 -0
  216. package/template/+nextjs+websockets/components/room-components/room-loader/room-loader.tsx +98 -0
  217. package/template/+nextjs+websockets/components/room-components/selection-information.tsx +74 -0
  218. package/template/+nextjs+websockets/components/room-components/toggle-icon-button.tsx +60 -0
  219. package/template/+nextjs+websockets/components/room-components/toolbar/toolbar-button.tsx +60 -0
  220. package/template/+nextjs+websockets/components/room-components/toolbar/toolbar-toggle-button.tsx +40 -0
  221. package/template/+nextjs+websockets/components/room-components/toolbar/toolbar.tsx +28 -0
  222. package/template/+nextjs+websockets/components/room-components/upload-file.tsx +130 -0
  223. package/template/+nextjs+websockets/components/room-components/with-instance-node.tsx +53 -0
  224. package/template/+nextjs+websockets/components/ui/accordion.tsx +66 -0
  225. package/template/+nextjs+websockets/components/ui/avatar.tsx +53 -0
  226. package/template/+nextjs+websockets/components/ui/button.tsx +58 -0
  227. package/template/+nextjs+websockets/components/ui/card.tsx +68 -0
  228. package/template/+nextjs+websockets/components/ui/checkbox.tsx +32 -0
  229. package/template/+nextjs+websockets/components/ui/color-picker/color-picker-component.tsx +69 -0
  230. package/template/+nextjs+websockets/components/ui/color-picker/context/color-picker-context.tsx +28 -0
  231. package/template/+nextjs+websockets/components/ui/color-picker/editor/color-picker-format-editor.tsx +34 -0
  232. package/template/+nextjs+websockets/components/ui/color-picker/index.ts +7 -0
  233. package/template/+nextjs+websockets/components/ui/color-picker/selector/color-picker-alpha.tsx +79 -0
  234. package/template/+nextjs+websockets/components/ui/color-picker/selector/color-picker-eyedropper.tsx +95 -0
  235. package/template/+nextjs+websockets/components/ui/color-picker/selector/color-picker-format-selector.tsx +50 -0
  236. package/template/+nextjs+websockets/components/ui/color-picker/selector/color-picker-hue.tsx +67 -0
  237. package/template/+nextjs+websockets/components/ui/color-picker/selector/color-picker-saturation.tsx +145 -0
  238. package/template/+nextjs+websockets/components/ui/color-picker/text-inputs/color-picker-alpha-percentage.tsx +60 -0
  239. package/template/+nextjs+websockets/components/ui/color-picker/text-inputs/color-picker-hexa.tsx +65 -0
  240. package/template/+nextjs+websockets/components/ui/color-picker/text-inputs/color-picker-rgba.tsx +62 -0
  241. package/template/+nextjs+websockets/components/ui/command.tsx +177 -0
  242. package/template/+nextjs+websockets/components/ui/dialog.tsx +135 -0
  243. package/template/+nextjs+websockets/components/ui/drawer.tsx +132 -0
  244. package/template/+nextjs+websockets/components/ui/dropdown-menu.tsx +201 -0
  245. package/template/+nextjs+websockets/components/ui/form.tsx +167 -0
  246. package/template/+nextjs+websockets/components/ui/input.tsx +21 -0
  247. package/template/+nextjs+websockets/components/ui/label.tsx +24 -0
  248. package/template/+nextjs+websockets/components/ui/popover.tsx +48 -0
  249. package/template/+nextjs+websockets/components/ui/reactbits/Backgrounds/Dither/Dither.tsx +350 -0
  250. package/template/+nextjs+websockets/components/ui/reactbits/Backgrounds/Threads/Threads.tsx +239 -0
  251. package/template/+nextjs+websockets/components/ui/reactbits/TextAnimations/RotatingText/RotatingText.tsx +276 -0
  252. package/template/+nextjs+websockets/components/ui/scroll-area.tsx +58 -0
  253. package/template/+nextjs+websockets/components/ui/select.tsx +185 -0
  254. package/template/+nextjs+websockets/components/ui/sheet.tsx +139 -0
  255. package/template/+nextjs+websockets/components/ui/sonner.tsx +25 -0
  256. package/template/+nextjs+websockets/components/ui/tabs.tsx +66 -0
  257. package/template/+nextjs+websockets/components/ui/tooltip.tsx +61 -0
  258. package/template/+nextjs+websockets/components/utils/constants.ts +118 -0
  259. package/template/+nextjs+websockets/components/utils/logo.tsx +34 -0
  260. package/template/+nextjs+websockets/components.json +21 -0
  261. package/template/+nextjs+websockets/example.env +2 -0
  262. package/template/+nextjs+websockets/example.gitignore +44 -0
  263. package/template/+nextjs+websockets/jsrepo.json +11 -0
  264. package/template/+nextjs+websockets/lib/utils.ts +43 -0
  265. package/template/+nextjs+websockets/new-types.d.ts +8 -0
  266. package/template/+nextjs+websockets/next-env.d.ts +5 -0
  267. package/template/+nextjs+websockets/next.config.js +52 -0
  268. package/template/+nextjs+websockets/postcss.config.mjs +5 -0
  269. package/template/+nextjs+websockets/store/store.ts +241 -0
  270. package/template/+nextjs+websockets/tsconfig.json +37 -0
  271. package/template/+nextjs+websockets/vitest.config.mts +10 -0
  272. package/template/package.json +81 -0
@@ -0,0 +1,350 @@
1
+ "use client";
2
+
3
+ /*
4
+ Installed from https://reactbits.dev/ts/tailwind/
5
+ */
6
+
7
+ /* eslint-disable react/no-unknown-property */
8
+ import React, { useRef, useState, useEffect } from "react";
9
+ import { Canvas, useFrame, useThree, ThreeEvent } from "@react-three/fiber";
10
+ import { EffectComposer, wrapEffect } from "@react-three/postprocessing";
11
+ import { Effect } from "postprocessing";
12
+ import * as THREE from "three";
13
+
14
+ const waveVertexShader = `
15
+ precision highp float;
16
+ varying vec2 vUv;
17
+ void main() {
18
+ vUv = uv;
19
+ vec4 modelPosition = modelMatrix * vec4(position, 1.0);
20
+ vec4 viewPosition = viewMatrix * modelPosition;
21
+ gl_Position = projectionMatrix * viewPosition;
22
+ }
23
+ `;
24
+
25
+ const waveFragmentShader = `
26
+ precision highp float;
27
+ uniform vec2 resolution;
28
+ uniform float time;
29
+ uniform float waveSpeed;
30
+ uniform float waveFrequency;
31
+ uniform float waveAmplitude;
32
+ uniform vec3 waveColor;
33
+ uniform vec2 mousePos;
34
+ uniform int enableMouseInteraction;
35
+ uniform float mouseRadius;
36
+
37
+ vec4 mod289(vec4 x) { return x - floor(x * (1.0/289.0)) * 289.0; }
38
+ vec4 permute(vec4 x) { return mod289(((x * 34.0) + 1.0) * x); }
39
+ vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }
40
+ vec2 fade(vec2 t) { return t*t*t*(t*(t*6.0-15.0)+10.0); }
41
+
42
+ float cnoise(vec2 P) {
43
+ vec4 Pi = floor(P.xyxy) + vec4(0.0,0.0,1.0,1.0);
44
+ vec4 Pf = fract(P.xyxy) - vec4(0.0,0.0,1.0,1.0);
45
+ Pi = mod289(Pi);
46
+ vec4 ix = Pi.xzxz;
47
+ vec4 iy = Pi.yyww;
48
+ vec4 fx = Pf.xzxz;
49
+ vec4 fy = Pf.yyww;
50
+ vec4 i = permute(permute(ix) + iy);
51
+ vec4 gx = fract(i * (1.0/41.0)) * 2.0 - 1.0;
52
+ vec4 gy = abs(gx) - 0.5;
53
+ vec4 tx = floor(gx + 0.5);
54
+ gx = gx - tx;
55
+ vec2 g00 = vec2(gx.x, gy.x);
56
+ vec2 g10 = vec2(gx.y, gy.y);
57
+ vec2 g01 = vec2(gx.z, gy.z);
58
+ vec2 g11 = vec2(gx.w, gy.w);
59
+ vec4 norm = taylorInvSqrt(vec4(dot(g00,g00), dot(g01,g01), dot(g10,g10), dot(g11,g11)));
60
+ g00 *= norm.x; g01 *= norm.y; g10 *= norm.z; g11 *= norm.w;
61
+ float n00 = dot(g00, vec2(fx.x, fy.x));
62
+ float n10 = dot(g10, vec2(fx.y, fy.y));
63
+ float n01 = dot(g01, vec2(fx.z, fy.z));
64
+ float n11 = dot(g11, vec2(fx.w, fy.w));
65
+ vec2 fade_xy = fade(Pf.xy);
66
+ vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);
67
+ return 2.3 * mix(n_x.x, n_x.y, fade_xy.y);
68
+ }
69
+
70
+ const int OCTAVES = 8;
71
+ float fbm(vec2 p) {
72
+ float value = 0.0;
73
+ float amp = 1.0;
74
+ float freq = waveFrequency;
75
+ for (int i = 0; i < OCTAVES; i++) {
76
+ value += amp * abs(cnoise(p));
77
+ p *= freq;
78
+ amp *= waveAmplitude;
79
+ }
80
+ return value;
81
+ }
82
+
83
+ float pattern(vec2 p) {
84
+ vec2 p2 = p - time * waveSpeed;
85
+ return fbm(p - fbm(p + fbm(p2)));
86
+ }
87
+
88
+ void main() {
89
+ vec2 uv = gl_FragCoord.xy / resolution.xy;
90
+ uv -= 0.5;
91
+ uv.x *= resolution.x / resolution.y;
92
+ float f = pattern(uv);
93
+ if (enableMouseInteraction == 1) {
94
+ vec2 mouseNDC = (mousePos / resolution - 0.5) * vec2(1.0, -1.0);
95
+ mouseNDC.x *= resolution.x / resolution.y;
96
+ float dist = length(uv - mouseNDC);
97
+ float effect = 1.0 - smoothstep(0.0, mouseRadius, dist);
98
+ f -= 0.5 * effect;
99
+ }
100
+ vec3 col = mix(vec3(0.0), waveColor, f);
101
+ gl_FragColor = vec4(col, 1.0);
102
+ }
103
+ `;
104
+
105
+ const ditherFragmentShader = `
106
+ precision highp float;
107
+ uniform float colorNum;
108
+ uniform float pixelSize;
109
+ const float bayerMatrix8x8[64] = float[64](
110
+ 0.0/64.0, 48.0/64.0, 12.0/64.0, 60.0/64.0, 3.0/64.0, 51.0/64.0, 15.0/64.0, 63.0/64.0,
111
+ 32.0/64.0,16.0/64.0, 44.0/64.0, 28.0/64.0, 35.0/64.0,19.0/64.0, 47.0/64.0, 31.0/64.0,
112
+ 8.0/64.0, 56.0/64.0, 4.0/64.0, 52.0/64.0, 11.0/64.0,59.0/64.0, 7.0/64.0, 55.0/64.0,
113
+ 40.0/64.0,24.0/64.0, 36.0/64.0, 20.0/64.0, 43.0/64.0,27.0/64.0, 39.0/64.0, 23.0/64.0,
114
+ 2.0/64.0, 50.0/64.0, 14.0/64.0, 62.0/64.0, 1.0/64.0,49.0/64.0, 13.0/64.0, 61.0/64.0,
115
+ 34.0/64.0,18.0/64.0, 46.0/64.0, 30.0/64.0, 33.0/64.0,17.0/64.0, 45.0/64.0, 29.0/64.0,
116
+ 10.0/64.0,58.0/64.0, 6.0/64.0, 54.0/64.0, 9.0/64.0,57.0/64.0, 5.0/64.0, 53.0/64.0,
117
+ 42.0/64.0,26.0/64.0, 38.0/64.0, 22.0/64.0, 41.0/64.0,25.0/64.0, 37.0/64.0, 21.0/64.0
118
+ );
119
+
120
+ vec3 dither(vec2 uv, vec3 color) {
121
+ int x = int(uv.x * resolution.x) % 8;
122
+ int y = int(uv.y * resolution.y) % 8;
123
+ float threshold = bayerMatrix8x8[y * 8 + x] - 0.25;
124
+ color += threshold;
125
+ return floor(color * (colorNum - 1.0) + 0.5) / (colorNum - 1.0);
126
+ }
127
+
128
+ void mainImage(in vec4 inputColor, in vec2 uv, out vec4 outputColor) {
129
+ vec2 normalizedPixelSize = pixelSize / resolution;
130
+ vec2 uvPixel = normalizedPixelSize * floor(uv / normalizedPixelSize);
131
+ vec4 color = texture2D(inputBuffer, uvPixel);
132
+ color.rgb = dither(uvPixel, color.rgb);
133
+ outputColor = color;
134
+ }
135
+ `;
136
+
137
+ class RetroEffectImpl extends Effect {
138
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
139
+ public uniforms: Map<string, THREE.Uniform<any>>;
140
+ constructor() {
141
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
142
+ const uniforms = new Map<string, THREE.Uniform<any>>([
143
+ ["colorNum", new THREE.Uniform(4.0)],
144
+ ["pixelSize", new THREE.Uniform(2.0)],
145
+ ]);
146
+ super("RetroEffect", ditherFragmentShader, { uniforms });
147
+ this.uniforms = uniforms;
148
+ }
149
+ set colorNum(value: number) {
150
+ this.uniforms.get("colorNum")!.value = value;
151
+ }
152
+ get colorNum(): number {
153
+ return this.uniforms.get("colorNum")!.value;
154
+ }
155
+ set pixelSize(value: number) {
156
+ this.uniforms.get("pixelSize")!.value = value;
157
+ }
158
+ get pixelSize(): number {
159
+ return this.uniforms.get("pixelSize")!.value;
160
+ }
161
+ }
162
+
163
+ const RetroEffect = wrapEffect(
164
+ RetroEffectImpl
165
+ ) as React.ForwardRefExoticComponent<React.RefAttributes<RetroEffectImpl>>;
166
+
167
+ interface WaveUniforms {
168
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
169
+ [key: string]: THREE.Uniform<any>;
170
+ time: THREE.Uniform<number>;
171
+ resolution: THREE.Uniform<THREE.Vector2>;
172
+ waveSpeed: THREE.Uniform<number>;
173
+ waveFrequency: THREE.Uniform<number>;
174
+ waveAmplitude: THREE.Uniform<number>;
175
+ waveColor: THREE.Uniform<THREE.Color>;
176
+ mousePos: THREE.Uniform<THREE.Vector2>;
177
+ enableMouseInteraction: THREE.Uniform<number>;
178
+ mouseRadius: THREE.Uniform<number>;
179
+ }
180
+
181
+ interface DitheredWavesProps {
182
+ waveSpeed: number;
183
+ waveFrequency: number;
184
+ waveAmplitude: number;
185
+ waveColor: [number, number, number];
186
+ colorNum: number;
187
+ pixelSize: number;
188
+ disableAnimation: boolean;
189
+ enableMouseInteraction: boolean;
190
+ mouseRadius: number;
191
+ }
192
+
193
+ function DitheredWaves({
194
+ waveSpeed,
195
+ waveFrequency,
196
+ waveAmplitude,
197
+ waveColor,
198
+ colorNum,
199
+ pixelSize,
200
+ disableAnimation,
201
+ enableMouseInteraction,
202
+ mouseRadius,
203
+ }: DitheredWavesProps) {
204
+ const mesh = useRef<THREE.Mesh>(null);
205
+ const effect = useRef<RetroEffectImpl>(null);
206
+ const [mousePos, setMousePos] = useState<{ x: number; y: number }>({
207
+ x: 0,
208
+ y: 0,
209
+ });
210
+ const { viewport, size, gl } = useThree();
211
+
212
+ const waveUniformsRef = useRef<WaveUniforms>({
213
+ time: new THREE.Uniform(0),
214
+ resolution: new THREE.Uniform(new THREE.Vector2(0, 0)),
215
+ waveSpeed: new THREE.Uniform(waveSpeed),
216
+ waveFrequency: new THREE.Uniform(waveFrequency),
217
+ waveAmplitude: new THREE.Uniform(waveAmplitude),
218
+ waveColor: new THREE.Uniform(new THREE.Color(...waveColor)),
219
+ mousePos: new THREE.Uniform(new THREE.Vector2(0, 0)),
220
+ enableMouseInteraction: new THREE.Uniform(enableMouseInteraction ? 1 : 0),
221
+ mouseRadius: new THREE.Uniform(mouseRadius),
222
+ });
223
+
224
+ useEffect(() => {
225
+ const dpr = gl.getPixelRatio();
226
+ const newWidth = Math.floor(size.width * dpr);
227
+ const newHeight = Math.floor(size.height * dpr);
228
+ const currentRes = waveUniformsRef.current.resolution.value;
229
+ if (currentRes.x !== newWidth || currentRes.y !== newHeight) {
230
+ currentRes.set(newWidth, newHeight);
231
+ if (
232
+ effect.current &&
233
+ effect.current.uniforms.get("resolution") &&
234
+ effect.current.uniforms.get("resolution")!.value
235
+ ) {
236
+ effect.current.uniforms
237
+ .get("resolution")!
238
+ .value.set(newWidth, newHeight);
239
+ }
240
+ }
241
+ }, [size, gl]);
242
+
243
+ useFrame(({ clock }) => {
244
+ if (!disableAnimation) {
245
+ waveUniformsRef.current.time.value = clock.getElapsedTime();
246
+ }
247
+ waveUniformsRef.current.waveSpeed.value = waveSpeed;
248
+ waveUniformsRef.current.waveFrequency.value = waveFrequency;
249
+ waveUniformsRef.current.waveAmplitude.value = waveAmplitude;
250
+ waveUniformsRef.current.waveColor.value.set(...waveColor);
251
+ waveUniformsRef.current.enableMouseInteraction.value =
252
+ enableMouseInteraction ? 1 : 0;
253
+ waveUniformsRef.current.mouseRadius.value = mouseRadius;
254
+ if (enableMouseInteraction) {
255
+ waveUniformsRef.current.mousePos.value.set(mousePos.x, mousePos.y);
256
+ }
257
+ if (effect.current) {
258
+ effect.current.colorNum = colorNum;
259
+ effect.current.pixelSize = pixelSize;
260
+ }
261
+ });
262
+
263
+ const handlePointerMove = (e: ThreeEvent<PointerEvent>) => {
264
+ if (!enableMouseInteraction) return;
265
+ const rect = gl.domElement.getBoundingClientRect();
266
+ const dpr = gl.getPixelRatio();
267
+ const x = (e.clientX - rect.left) * dpr;
268
+ const y = (e.clientY - rect.top) * dpr;
269
+ setMousePos({ x, y });
270
+ };
271
+
272
+ return (
273
+ <>
274
+ <mesh ref={mesh} scale={[viewport.width, viewport.height, 1]}>
275
+ <planeGeometry args={[1, 1]} />
276
+ <shaderMaterial
277
+ vertexShader={waveVertexShader}
278
+ fragmentShader={waveFragmentShader}
279
+ uniforms={waveUniformsRef.current}
280
+ />
281
+ </mesh>
282
+ <EffectComposer>
283
+ <RetroEffect ref={effect} />
284
+ </EffectComposer>
285
+ <mesh
286
+ onPointerMove={handlePointerMove}
287
+ position={[0, 0, 0.01]}
288
+ scale={[viewport.width, viewport.height, 1]}
289
+ visible={false}
290
+ >
291
+ <planeGeometry args={[1, 1]} />
292
+ <meshBasicMaterial transparent opacity={0} />
293
+ </mesh>
294
+ </>
295
+ );
296
+ }
297
+
298
+ interface DitherProps {
299
+ waveSpeed?: number;
300
+ waveFrequency?: number;
301
+ waveAmplitude?: number;
302
+ waveColor?: [number, number, number];
303
+ colorNum?: number;
304
+ pixelSize?: number;
305
+ disableAnimation?: boolean;
306
+ enableMouseInteraction?: boolean;
307
+ mouseRadius?: number;
308
+ }
309
+
310
+ export default function Dither({
311
+ waveSpeed = 0.05,
312
+ waveFrequency = 3,
313
+ waveAmplitude = 0.3,
314
+ waveColor = [0.5, 0.5, 0.5],
315
+ colorNum = 4,
316
+ pixelSize = 2,
317
+ disableAnimation = false,
318
+ enableMouseInteraction = true,
319
+ mouseRadius = 1,
320
+ }: DitherProps) {
321
+ const [devicePixelRatio, setDevicePixelRatio] = useState(1);
322
+ // const [isMac, setIsMac] = useState(false);
323
+
324
+ React.useEffect(() => {
325
+ // setIsMac(platforms.macos);
326
+ setDevicePixelRatio(window.devicePixelRatio);
327
+ }, []);
328
+
329
+ return (
330
+ <Canvas
331
+ className="w-full h-full relative"
332
+ // style={{ padding: 0 }}
333
+ camera={{ position: [0, 0, 6] }}
334
+ dpr={devicePixelRatio}
335
+ gl={{ antialias: true, preserveDrawingBuffer: true }}
336
+ >
337
+ <DitheredWaves
338
+ waveSpeed={waveSpeed}
339
+ waveFrequency={waveFrequency}
340
+ waveAmplitude={waveAmplitude}
341
+ waveColor={waveColor}
342
+ colorNum={colorNum}
343
+ pixelSize={pixelSize}
344
+ disableAnimation={disableAnimation}
345
+ enableMouseInteraction={enableMouseInteraction}
346
+ mouseRadius={mouseRadius}
347
+ />
348
+ </Canvas>
349
+ );
350
+ }
@@ -0,0 +1,239 @@
1
+ /*
2
+ Installed from https://reactbits.dev/ts/tailwind/
3
+ */
4
+
5
+ import React, { useEffect, useRef } from "react";
6
+ import { Renderer, Program, Mesh, Triangle, Color } from "ogl";
7
+
8
+ interface ThreadsProps {
9
+ color?: [number, number, number];
10
+ amplitude?: number;
11
+ distance?: number;
12
+ enableMouseInteraction?: boolean;
13
+ }
14
+
15
+ const vertexShader = `
16
+ attribute vec2 position;
17
+ attribute vec2 uv;
18
+ varying vec2 vUv;
19
+ void main() {
20
+ vUv = uv;
21
+ gl_Position = vec4(position, 0.0, 1.0);
22
+ }
23
+ `;
24
+
25
+ const fragmentShader = `
26
+ precision highp float;
27
+
28
+ uniform float iTime;
29
+ uniform vec3 iResolution;
30
+ uniform vec3 uColor;
31
+ uniform float uAmplitude;
32
+ uniform float uDistance;
33
+ uniform vec2 uMouse;
34
+
35
+ #define PI 3.1415926538
36
+
37
+ const int u_line_count = 40;
38
+ const float u_line_width = 7.0;
39
+ const float u_line_blur = 10.0;
40
+
41
+ float Perlin2D(vec2 P) {
42
+ vec2 Pi = floor(P);
43
+ vec4 Pf_Pfmin1 = P.xyxy - vec4(Pi, Pi + 1.0);
44
+ vec4 Pt = vec4(Pi.xy, Pi.xy + 1.0);
45
+ Pt = Pt - floor(Pt * (1.0 / 71.0)) * 71.0;
46
+ Pt += vec2(26.0, 161.0).xyxy;
47
+ Pt *= Pt;
48
+ Pt = Pt.xzxz * Pt.yyww;
49
+ vec4 hash_x = fract(Pt * (1.0 / 951.135664));
50
+ vec4 hash_y = fract(Pt * (1.0 / 642.949883));
51
+ vec4 grad_x = hash_x - 0.49999;
52
+ vec4 grad_y = hash_y - 0.49999;
53
+ vec4 grad_results = inversesqrt(grad_x * grad_x + grad_y * grad_y)
54
+ * (grad_x * Pf_Pfmin1.xzxz + grad_y * Pf_Pfmin1.yyww);
55
+ grad_results *= 1.4142135623730950;
56
+ vec2 blend = Pf_Pfmin1.xy * Pf_Pfmin1.xy * Pf_Pfmin1.xy
57
+ * (Pf_Pfmin1.xy * (Pf_Pfmin1.xy * 6.0 - 15.0) + 10.0);
58
+ vec4 blend2 = vec4(blend, vec2(1.0 - blend));
59
+ return dot(grad_results, blend2.zxzx * blend2.wwyy);
60
+ }
61
+
62
+ float pixel(float count, vec2 resolution) {
63
+ return (1.0 / max(resolution.x, resolution.y)) * count;
64
+ }
65
+
66
+ float lineFn(vec2 st, float width, float perc, float offset, vec2 mouse, float time, float amplitude, float distance) {
67
+ float split_offset = (perc * 0.4);
68
+ float split_point = 0.1 + split_offset;
69
+
70
+ float amplitude_normal = smoothstep(split_point, 0.7, st.x);
71
+ float amplitude_strength = 0.5;
72
+ float finalAmplitude = amplitude_normal * amplitude_strength
73
+ * amplitude * (1.0 + (mouse.y - 0.5) * 0.2);
74
+
75
+ float time_scaled = time / 10.0 + (mouse.x - 0.5) * 1.0;
76
+ float blur = smoothstep(split_point, split_point + 0.05, st.x) * perc;
77
+
78
+ float xnoise = mix(
79
+ Perlin2D(vec2(time_scaled, st.x + perc) * 2.5),
80
+ Perlin2D(vec2(time_scaled, st.x + time_scaled) * 3.5) / 1.5,
81
+ st.x * 0.3
82
+ );
83
+
84
+ float y = 0.5 + (perc - 0.5) * distance + xnoise / 2.0 * finalAmplitude;
85
+
86
+ float line_start = smoothstep(
87
+ y + (width / 2.0) + (u_line_blur * pixel(1.0, iResolution.xy) * blur),
88
+ y,
89
+ st.y
90
+ );
91
+
92
+ float line_end = smoothstep(
93
+ y,
94
+ y - (width / 2.0) - (u_line_blur * pixel(1.0, iResolution.xy) * blur),
95
+ st.y
96
+ );
97
+
98
+ return clamp(
99
+ (line_start - line_end) * (1.0 - smoothstep(0.0, 1.0, pow(perc, 0.3))),
100
+ 0.0,
101
+ 1.0
102
+ );
103
+ }
104
+
105
+ void mainImage(out vec4 fragColor, in vec2 fragCoord) {
106
+ vec2 uv = fragCoord / iResolution.xy;
107
+
108
+ float line_strength = 1.0;
109
+ for (int i = 0; i < u_line_count; i++) {
110
+ float p = float(i) / float(u_line_count);
111
+ line_strength *= (1.0 - lineFn(
112
+ uv,
113
+ u_line_width * pixel(1.0, iResolution.xy) * (1.0 - p),
114
+ p,
115
+ (PI * 1.0) * p,
116
+ uMouse,
117
+ iTime,
118
+ uAmplitude,
119
+ uDistance
120
+ ));
121
+ }
122
+
123
+ float colorVal = 1.0 - line_strength;
124
+ fragColor = vec4(uColor * colorVal, colorVal);
125
+ }
126
+
127
+ void main() {
128
+ mainImage(gl_FragColor, gl_FragCoord.xy);
129
+ }
130
+ `;
131
+
132
+ const Threads: React.FC<ThreadsProps> = ({
133
+ color = [1, 1, 1],
134
+ amplitude = 1,
135
+ distance = 0,
136
+ enableMouseInteraction = false,
137
+ ...rest
138
+ }) => {
139
+ const containerRef = useRef<HTMLDivElement>(null);
140
+ const animationFrameId = useRef<number>();
141
+
142
+ useEffect(() => {
143
+ if (!containerRef.current) return;
144
+ const container = containerRef.current;
145
+
146
+ const renderer = new Renderer({ alpha: true });
147
+ const gl = renderer.gl;
148
+ gl.clearColor(0, 0, 0, 0);
149
+ gl.enable(gl.BLEND);
150
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
151
+ container.appendChild(gl.canvas);
152
+
153
+ const geometry = new Triangle(gl);
154
+ const program = new Program(gl, {
155
+ vertex: vertexShader,
156
+ fragment: fragmentShader,
157
+ uniforms: {
158
+ iTime: { value: 0 },
159
+ iResolution: {
160
+ value: new Color(
161
+ gl.canvas.width,
162
+ gl.canvas.height,
163
+ gl.canvas.width / gl.canvas.height
164
+ ),
165
+ },
166
+ uColor: { value: new Color(...color) },
167
+ uAmplitude: { value: amplitude },
168
+ uDistance: { value: distance },
169
+ uMouse: { value: new Float32Array([0.5, 0.5]) },
170
+ },
171
+ });
172
+
173
+ const mesh = new Mesh(gl, { geometry, program });
174
+
175
+ function resize() {
176
+ const { clientWidth, clientHeight } = container;
177
+ renderer.setSize(clientWidth, clientHeight);
178
+ program.uniforms.iResolution.value.r = clientWidth;
179
+ program.uniforms.iResolution.value.g = clientHeight;
180
+ program.uniforms.iResolution.value.b = clientWidth / clientHeight;
181
+ }
182
+ window.addEventListener("resize", resize);
183
+ resize();
184
+
185
+ const currentMouse = [0.5, 0.5];
186
+ let targetMouse = [0.5, 0.5];
187
+
188
+ function handleMouseMove(e: MouseEvent) {
189
+ const rect = container.getBoundingClientRect();
190
+ const x = (e.clientX - rect.left) / rect.width;
191
+ const y = 1.0 - (e.clientY - rect.top) / rect.height;
192
+ targetMouse = [x, y];
193
+ }
194
+ function handleMouseLeave() {
195
+ targetMouse = [0.5, 0.5];
196
+ }
197
+ if (enableMouseInteraction) {
198
+ container.addEventListener("mousemove", handleMouseMove);
199
+ container.addEventListener("mouseleave", handleMouseLeave);
200
+ }
201
+
202
+ function update(t: number) {
203
+ if (enableMouseInteraction) {
204
+ const smoothing = 0.05;
205
+ currentMouse[0] += smoothing * (targetMouse[0] - currentMouse[0]);
206
+ currentMouse[1] += smoothing * (targetMouse[1] - currentMouse[1]);
207
+ program.uniforms.uMouse.value[0] = currentMouse[0];
208
+ program.uniforms.uMouse.value[1] = currentMouse[1];
209
+ } else {
210
+ program.uniforms.uMouse.value[0] = 0.5;
211
+ program.uniforms.uMouse.value[1] = 0.5;
212
+ }
213
+ program.uniforms.iTime.value = t * 0.001;
214
+
215
+ renderer.render({ scene: mesh });
216
+ animationFrameId.current = requestAnimationFrame(update);
217
+ }
218
+ animationFrameId.current = requestAnimationFrame(update);
219
+
220
+ return () => {
221
+ if (animationFrameId.current)
222
+ cancelAnimationFrame(animationFrameId.current);
223
+ window.removeEventListener("resize", resize);
224
+
225
+ if (enableMouseInteraction) {
226
+ container.removeEventListener("mousemove", handleMouseMove);
227
+ container.removeEventListener("mouseleave", handleMouseLeave);
228
+ }
229
+ if (container.contains(gl.canvas)) container.removeChild(gl.canvas);
230
+ gl.getExtension("WEBGL_lose_context")?.loseContext();
231
+ };
232
+ }, [color, amplitude, distance, enableMouseInteraction]);
233
+
234
+ return (
235
+ <div ref={containerRef} className="w-full h-full relative" {...rest} />
236
+ );
237
+ };
238
+
239
+ export default Threads;