@fab1o978/react-ui 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 (58) hide show
  1. package/README.md +73 -0
  2. package/dist/components/Badge/index.cjs +47 -0
  3. package/dist/components/Badge/index.cjs.map +1 -0
  4. package/dist/components/Badge/index.css +112 -0
  5. package/dist/components/Badge/index.css.map +1 -0
  6. package/dist/components/Badge/index.d.cts +14 -0
  7. package/dist/components/Badge/index.d.ts +14 -0
  8. package/dist/components/Badge/index.js +45 -0
  9. package/dist/components/Badge/index.js.map +1 -0
  10. package/dist/components/Button/index.cjs +64 -0
  11. package/dist/components/Button/index.cjs.map +1 -0
  12. package/dist/components/Button/index.css +159 -0
  13. package/dist/components/Button/index.css.map +1 -0
  14. package/dist/components/Button/index.d.cts +13 -0
  15. package/dist/components/Button/index.d.ts +13 -0
  16. package/dist/components/Button/index.js +58 -0
  17. package/dist/components/Button/index.js.map +1 -0
  18. package/dist/components/ColorPicker/index.cjs +523 -0
  19. package/dist/components/ColorPicker/index.cjs.map +1 -0
  20. package/dist/components/ColorPicker/index.css +308 -0
  21. package/dist/components/ColorPicker/index.css.map +1 -0
  22. package/dist/components/ColorPicker/index.d.cts +35 -0
  23. package/dist/components/ColorPicker/index.d.ts +35 -0
  24. package/dist/components/ColorPicker/index.js +521 -0
  25. package/dist/components/ColorPicker/index.js.map +1 -0
  26. package/dist/components/Input/index.cjs +86 -0
  27. package/dist/components/Input/index.cjs.map +1 -0
  28. package/dist/components/Input/index.css +170 -0
  29. package/dist/components/Input/index.css.map +1 -0
  30. package/dist/components/Input/index.d.cts +15 -0
  31. package/dist/components/Input/index.d.ts +15 -0
  32. package/dist/components/Input/index.js +80 -0
  33. package/dist/components/Input/index.js.map +1 -0
  34. package/dist/components/RainCanvas/index.cjs +227 -0
  35. package/dist/components/RainCanvas/index.cjs.map +1 -0
  36. package/dist/components/RainCanvas/index.css +32 -0
  37. package/dist/components/RainCanvas/index.css.map +1 -0
  38. package/dist/components/RainCanvas/index.d.cts +12 -0
  39. package/dist/components/RainCanvas/index.d.ts +12 -0
  40. package/dist/components/RainCanvas/index.js +225 -0
  41. package/dist/components/RainCanvas/index.js.map +1 -0
  42. package/dist/components/Timeline/index.cjs +169 -0
  43. package/dist/components/Timeline/index.cjs.map +1 -0
  44. package/dist/components/Timeline/index.css +247 -0
  45. package/dist/components/Timeline/index.css.map +1 -0
  46. package/dist/components/Timeline/index.d.cts +22 -0
  47. package/dist/components/Timeline/index.d.ts +22 -0
  48. package/dist/components/Timeline/index.js +167 -0
  49. package/dist/components/Timeline/index.js.map +1 -0
  50. package/dist/index.cjs +993 -0
  51. package/dist/index.cjs.map +1 -0
  52. package/dist/index.css +1019 -0
  53. package/dist/index.css.map +1 -0
  54. package/dist/index.d.cts +7 -0
  55. package/dist/index.d.ts +7 -0
  56. package/dist/index.js +982 -0
  57. package/dist/index.js.map +1 -0
  58. package/package.json +69 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/Input/Input.module.scss","../../../src/components/Input/Input.tsx"],"names":["wrapper","fullWidth","label","inputWrapper","input","error","sm","md","lg","adornment","adornmentEnd","withStart","withEnd","helperText","errorText"],"mappings":"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","file":"index.js","sourcesContent":["@import url(\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap\");\n:root {\n --accent: #3b82f6;\n --accent-dot: rgb(82.52, 145, 247.08);\n --accent-track: #3b82f6;\n --accent-ring: #3b82f6;\n --accent-glow: rgba(59, 130, 246, 0.3);\n --accent-light: rgb(157.485, 188.725, 239.765);\n --color-primary-50: rgb(169.3455, 194.6925, 236.1045);\n --color-primary-100: rgb(149.4545, 184.4575, 241.6455);\n --color-primary-400: rgb(82.52, 145, 247.08);\n --color-primary-500: #3b82f6;\n --color-primary-600: rgb(29.8390243902, 111.4024390244, 244.6609756098);\n --color-primary-700: rgb(10.712195122, 95.2195121951, 233.287804878);\n --color-neutral-0: #ffffff;\n --color-neutral-100: #f3f4f6;\n --color-neutral-200: #e5e7eb;\n --color-neutral-400: #9ca3af;\n --color-neutral-600: #4b5563;\n --color-neutral-900: #111827;\n --color-success-500: #22c55e;\n --color-success-600: #16a34a;\n --color-danger-500: #ef4444;\n --color-danger-600: #dc2626;\n --color-warning-500: #f59e0b;\n --color-warning-600: #d97706;\n --font-family-base: \"Inter\", system-ui, -apple-system, sans-serif;\n --font-size-xs: 0.75rem;\n --font-size-sm: 0.875rem;\n --font-size-md: 1rem;\n --font-size-lg: 1.125rem;\n --spacing-1: 0.25rem;\n --spacing-2: 0.5rem;\n --spacing-3: 0.75rem;\n --spacing-4: 1rem;\n --radius-sm: 0.25rem;\n --radius-md: 0.375rem;\n --radius-lg: 0.5rem;\n --radius-full: 9999px;\n --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);\n --transition-fast: 150ms ease;\n --color-surface: #ffffff;\n --color-surface-elevated: #ffffff;\n}\n\n[data-theme=dark] {\n --color-neutral-0: #0f172a;\n --color-neutral-100: #1e293b;\n --color-neutral-200: #334155;\n --color-neutral-400: #94a3b8;\n --color-neutral-600: #cbd5e1;\n --color-neutral-900: #f8fafc;\n --color-surface: #1e293b;\n --color-surface-elevated: #273549;\n --color-primary-50: #172554;\n --color-primary-100: #1e3a8a;\n --accent-light: #172554;\n --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.4);\n --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.5), 0 2px 4px -2px rgb(0 0 0 / 0.4);\n}\n\n.wrapper {\n display: inline-flex;\n flex-direction: column;\n gap: var(--spacing-1);\n}\n\n.fullWidth {\n width: 100%;\n}\n\n.label {\n font-family: var(--font-family-base);\n font-size: var(--font-size-sm);\n font-weight: 500;\n color: var(--color-neutral-900);\n letter-spacing: -0.01em;\n}\n\n.inputWrapper {\n position: relative;\n display: flex;\n align-items: center;\n}\n\n.input {\n width: 100%;\n font-family: var(--font-family-base);\n border: 1px solid var(--color-neutral-200);\n border-radius: var(--radius-md);\n background-color: var(--color-neutral-0);\n color: var(--color-neutral-900);\n outline: none;\n transition: border-color var(--transition-fast), box-shadow var(--transition-fast);\n}\n\n.input::placeholder {\n color: var(--color-neutral-400);\n}\n\n.input:focus {\n border-color: var(--color-primary-500);\n box-shadow: 0 0 0 3px var(--color-primary-100);\n}\n\n.input:disabled {\n background-color: var(--color-neutral-100);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.input.error {\n border-color: var(--color-danger-500);\n}\n\n.input.error:focus {\n box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.15);\n}\n\n/* Sizes */\n.sm .input {\n font-size: var(--font-size-xs);\n padding: var(--spacing-1) var(--spacing-2);\n height: 2rem;\n}\n\n.md .input {\n font-size: var(--font-size-sm);\n padding: var(--spacing-2) var(--spacing-3);\n height: 2.5rem;\n}\n\n.lg .input {\n font-size: var(--font-size-md);\n padding: var(--spacing-3) var(--spacing-4);\n height: 3rem;\n}\n\n/* Adornments */\n.adornment {\n position: absolute;\n left: var(--spacing-3);\n display: flex;\n align-items: center;\n color: var(--color-neutral-400);\n pointer-events: none;\n}\n\n.adornmentEnd {\n left: unset;\n right: var(--spacing-3);\n}\n\n.sm .withStart {\n padding-left: 2rem;\n}\n\n.md .withStart {\n padding-left: 2.25rem;\n}\n\n.lg .withStart {\n padding-left: 2.5rem;\n}\n\n.sm .withEnd {\n padding-right: 2rem;\n}\n\n.md .withEnd {\n padding-right: 2.25rem;\n}\n\n.lg .withEnd {\n padding-right: 2.5rem;\n}\n\n.helperText {\n font-family: var(--font-family-base);\n font-size: var(--font-size-xs);\n color: var(--color-neutral-400);\n}\n\n.errorText {\n font-family: var(--font-family-base);\n font-size: var(--font-size-xs);\n color: var(--color-danger-500);\n}\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3N0eWxlcy90b2tlbnMuc2NzcyIsIklucHV0Lm1vZHVsZS5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVRO0FBS1I7RUFFRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFHQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFHQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFHQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFHQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBR0E7RUFDQTtFQUNBO0VBQ0E7RUFHQTtFQUNBO0VBQ0E7RUFDQTtFQUdBO0VBQ0E7RUFHQTtFQUdBO0VBQ0E7OztBQVFGO0VBRUU7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBR0E7RUFDQTtFQUdBO0VBQ0E7RUFJQTtFQUdBO0VBQ0E7OztBQ2pHRjtFQUNFO0VBQ0E7RUFDQTs7O0FBR0Y7RUFDRTs7O0FBR0Y7RUFDRTtFQUNBO0VBQ0E7RUFDQTtFQUNBOzs7QUFHRjtFQUNFO0VBQ0E7RUFDQTs7O0FBR0Y7RUFDRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOzs7QUFHRjtFQUNFOzs7QUFHRjtFQUNFO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTtFQUNBOzs7QUFHRjtFQUNFOzs7QUFHRjtFQUNFOzs7QUFHRjtBQUNBO0VBQ0U7RUFDQTtFQUNBOzs7QUFHRjtFQUNFO0VBQ0E7RUFDQTs7O0FBR0Y7RUFDRTtFQUNBO0VBQ0E7OztBQUdGO0FBQ0E7RUFDRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTs7O0FBR0Y7RUFBaUI7OztBQUNqQjtFQUFpQjs7O0FBQ2pCO0VBQWlCOzs7QUFFakI7RUFBZTs7O0FBQ2Y7RUFBZTs7O0FBQ2Y7RUFBZTs7O0FBRWY7RUFDRTtFQUNBO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTtFQUNBIiwic291cmNlc0NvbnRlbnQiOlsiQHVzZSBcInNhc3M6Y29sb3JcIjtcblxuQGltcG9ydCB1cmwoXCJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2NzczI/ZmFtaWx5PUludGVyOndnaHRANDAwOzUwMDs2MDAmZGlzcGxheT1zd2FwXCIpO1xuXG4vLyBBY2NlbnQgZGkgZGVmYXVsdCDigJQgY2FtYmlhIHF1aSBwZXIgYWdnaW9ybmFyZSB0dXR0YSBsYSBsaWJyZXJpYVxuJGFjY2VudDogIzNiODJmNjtcblxuOnJvb3Qge1xuICAvLyBBY2NlbnQgc2NhbGUg4oCUIGRlcml2YXRhIGRhICRhY2NlbnQgYSBjb21waWxlIHRpbWVcbiAgLS1hY2NlbnQ6ICAgICAgICAjeyRhY2NlbnR9O1xuICAtLWFjY2VudC1kb3Q6ICAgICN7Y29sb3Iuc2NhbGUoJGFjY2VudCwgJGxpZ2h0bmVzczogMTIlKX07XG4gIC0tYWNjZW50LXRyYWNrOiAgI3skYWNjZW50fTtcbiAgLS1hY2NlbnQtcmluZzogICAjeyRhY2NlbnR9O1xuICAtLWFjY2VudC1nbG93OiAgICN7Y29sb3IuY2hhbmdlKCRhY2NlbnQsICRhbHBoYTogMC4zKX07XG4gIC0tYWNjZW50LWxpZ2h0OiAgI3tjb2xvci5zY2FsZSgkYWNjZW50LCAkbGlnaHRuZXNzOiA0NSUsICRzYXR1cmF0aW9uOiAtMjAlKX07XG5cbiAgLy8gUHJpbWFyeSBzY2FsZSAobWFudGVudXRhIHBlciByZXRyb2NvbXBhdGliaWxpdMOgIGNvbiBCdXR0b24sIEJhZGdlLCBJbnB1dClcbiAgLS1jb2xvci1wcmltYXJ5LTUwOiAgI3tjb2xvci5zY2FsZSgkYWNjZW50LCAkbGlnaHRuZXNzOiA0OSUsICRzYXR1cmF0aW9uOiAtMzAlKX07XG4gIC0tY29sb3ItcHJpbWFyeS0xMDA6ICN7Y29sb3Iuc2NhbGUoJGFjY2VudCwgJGxpZ2h0bmVzczogNDIlLCAkc2F0dXJhdGlvbjogLTE1JSl9O1xuICAtLWNvbG9yLXByaW1hcnktNDAwOiAje2NvbG9yLnNjYWxlKCRhY2NlbnQsICRsaWdodG5lc3M6IDEyJSl9O1xuICAtLWNvbG9yLXByaW1hcnktNTAwOiAjeyRhY2NlbnR9O1xuICAtLWNvbG9yLXByaW1hcnktNjAwOiAje2NvbG9yLnNjYWxlKCRhY2NlbnQsICRsaWdodG5lc3M6IC0xMCUpfTtcbiAgLS1jb2xvci1wcmltYXJ5LTcwMDogI3tjb2xvci5zY2FsZSgkYWNjZW50LCAkbGlnaHRuZXNzOiAtMjAlKX07XG5cbiAgLy8gTmV1dHJhbFxuICAtLWNvbG9yLW5ldXRyYWwtMDogICAjZmZmZmZmO1xuICAtLWNvbG9yLW5ldXRyYWwtMTAwOiAjZjNmNGY2O1xuICAtLWNvbG9yLW5ldXRyYWwtMjAwOiAjZTVlN2ViO1xuICAtLWNvbG9yLW5ldXRyYWwtNDAwOiAjOWNhM2FmO1xuICAtLWNvbG9yLW5ldXRyYWwtNjAwOiAjNGI1NTYzO1xuICAtLWNvbG9yLW5ldXRyYWwtOTAwOiAjMTExODI3O1xuXG4gIC8vIFNlbWFudGljXG4gIC0tY29sb3Itc3VjY2Vzcy01MDA6ICMyMmM1NWU7XG4gIC0tY29sb3Itc3VjY2Vzcy02MDA6ICMxNmEzNGE7XG4gIC0tY29sb3ItZGFuZ2VyLTUwMDogICNlZjQ0NDQ7XG4gIC0tY29sb3ItZGFuZ2VyLTYwMDogICNkYzI2MjY7XG4gIC0tY29sb3Itd2FybmluZy01MDA6ICNmNTllMGI7XG4gIC0tY29sb3Itd2FybmluZy02MDA6ICNkOTc3MDY7XG5cbiAgLy8gVHlwb2dyYXBoeVxuICAtLWZvbnQtZmFtaWx5LWJhc2U6IFwiSW50ZXJcIiwgc3lzdGVtLXVpLCAtYXBwbGUtc3lzdGVtLCBzYW5zLXNlcmlmO1xuICAtLWZvbnQtc2l6ZS14czogMC43NXJlbTtcbiAgLS1mb250LXNpemUtc206IDAuODc1cmVtO1xuICAtLWZvbnQtc2l6ZS1tZDogMXJlbTtcbiAgLS1mb250LXNpemUtbGc6IDEuMTI1cmVtO1xuXG4gIC8vIFNwYWNpbmdcbiAgLS1zcGFjaW5nLTE6IDAuMjVyZW07XG4gIC0tc3BhY2luZy0yOiAwLjVyZW07XG4gIC0tc3BhY2luZy0zOiAwLjc1cmVtO1xuICAtLXNwYWNpbmctNDogMXJlbTtcblxuICAvLyBSYWRpdXNcbiAgLS1yYWRpdXMtc206ICAgMC4yNXJlbTtcbiAgLS1yYWRpdXMtbWQ6ICAgMC4zNzVyZW07XG4gIC0tcmFkaXVzLWxnOiAgIDAuNXJlbTtcbiAgLS1yYWRpdXMtZnVsbDogOTk5OXB4O1xuXG4gIC8vIFNoYWRvd3NcbiAgLS1zaGFkb3ctc206IDAgMXB4IDJweCAwIHJnYigwIDAgMCAvIDAuMDUpO1xuICAtLXNoYWRvdy1tZDogMCA0cHggNnB4IC0xcHggcmdiKDAgMCAwIC8gMC4xKSwgMCAycHggNHB4IC0ycHggcmdiKDAgMCAwIC8gMC4xKTtcblxuICAvLyBUcmFuc2l0aW9uc1xuICAtLXRyYW5zaXRpb24tZmFzdDogMTUwbXMgZWFzZTtcblxuICAvLyBTdXJmYWNlIChiYWNrZ3JvdW5kIGRpIGNhcmQvcGFuZWwpXG4gIC0tY29sb3Itc3VyZmFjZTogICAgICAgICAgI2ZmZmZmZjtcbiAgLS1jb2xvci1zdXJmYWNlLWVsZXZhdGVkOiAjZmZmZmZmO1xufVxuXG4vLyDilIDilIDilIAgRGFyayB0aGVtZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIEFwcGxpY2F0byB2aWEgZGF0YS10aGVtZT1cImRhcmtcIiBzdWxsJ2VsZW1lbnRvIHJvb3QgKGdlc3RpdG8gZGEgU3Rvcnlib29rIGRlY29yYXRvclxuLy8gZSBkYWxsJ2FwcCBjb25zdW1lcikuIEkgY29tcG9uZW50aSBub24gZGV2b25vIGZhcmUgbnVsbGEgZGkgc3BlY2lhbGU6IGJhc3RhIGNoZVxuLy8gdXNpbm8gaSB0b2tlbiB2YXIoKSBlIHJpY2V2ZXJhbm5vIGF1dG9tYXRpY2FtZW50ZSBpIHZhbG9yaSBkYXJrLlxuXG5bZGF0YS10aGVtZT1cImRhcmtcIl0ge1xuICAvLyBOZXV0cmFsIChzY2FsYSBpbnZlcnRpdGEpXG4gIC0tY29sb3ItbmV1dHJhbC0wOiAgICMwZjE3MmE7XG4gIC0tY29sb3ItbmV1dHJhbC0xMDA6ICMxZTI5M2I7XG4gIC0tY29sb3ItbmV1dHJhbC0yMDA6ICMzMzQxNTU7XG4gIC0tY29sb3ItbmV1dHJhbC00MDA6ICM5NGEzYjg7XG4gIC0tY29sb3ItbmV1dHJhbC02MDA6ICNjYmQ1ZTE7XG4gIC0tY29sb3ItbmV1dHJhbC05MDA6ICNmOGZhZmM7XG5cbiAgLy8gU3VyZmFjZVxuICAtLWNvbG9yLXN1cmZhY2U6ICAgICAgICAgICMxZTI5M2I7XG4gIC0tY29sb3Itc3VyZmFjZS1lbGV2YXRlZDogIzI3MzU0OTtcblxuICAvLyBQcmltYXJ5IHNjYWxlIGRhcmsgKHBlciBpbCBkZWZhdWx0IGFjY2VudCBibHUg4oCUIGxlIHNmdW1hdHVyZSBjaGlhcmUgZGl2ZW50YW5vIHNjdXJlKVxuICAtLWNvbG9yLXByaW1hcnktNTA6ICAjMTcyNTU0O1xuICAtLWNvbG9yLXByaW1hcnktMTAwOiAjMWUzYThhO1xuICAvLyA0MDAgLyA1MDAgLyA2MDAgLyA3MDAgcmltYW5nb25vIGludmFyaWF0aSAoYWJiYXN0YW56YSBzYXR1cmkgc3UgYmcgc2N1cm8pXG5cbiAgLy8gQWNjZW50IGxpZ2h0OiB2YXJpYW50ZSBzY3VyYVxuICAtLWFjY2VudC1saWdodDogIzE3MjU1NDtcblxuICAvLyBTaGFkb3dzIChwacO5IGZvcnRpIHN1IGJnIHNjdXJvKVxuICAtLXNoYWRvdy1zbTogMCAxcHggMnB4IDAgcmdiKDAgMCAwIC8gMC40KTtcbiAgLS1zaGFkb3ctbWQ6IDAgNHB4IDZweCAtMXB4IHJnYigwIDAgMCAvIDAuNSksIDAgMnB4IDRweCAtMnB4IHJnYigwIDAgMCAvIDAuNCk7XG59XG4iLCJAaW1wb3J0IFwiLi4vLi4vc3R5bGVzL3Rva2Vucy5zY3NzXCI7XG5cbi53cmFwcGVyIHtcbiAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIGdhcDogdmFyKC0tc3BhY2luZy0xKTtcbn1cblxuLmZ1bGxXaWR0aCB7XG4gIHdpZHRoOiAxMDAlO1xufVxuXG4ubGFiZWwge1xuICBmb250LWZhbWlseTogdmFyKC0tZm9udC1mYW1pbHktYmFzZSk7XG4gIGZvbnQtc2l6ZTogdmFyKC0tZm9udC1zaXplLXNtKTtcbiAgZm9udC13ZWlnaHQ6IDUwMDtcbiAgY29sb3I6IHZhcigtLWNvbG9yLW5ldXRyYWwtOTAwKTtcbiAgbGV0dGVyLXNwYWNpbmc6IC0wLjAxZW07XG59XG5cbi5pbnB1dFdyYXBwZXIge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG59XG5cbi5pbnB1dCB7XG4gIHdpZHRoOiAxMDAlO1xuICBmb250LWZhbWlseTogdmFyKC0tZm9udC1mYW1pbHktYmFzZSk7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWNvbG9yLW5ldXRyYWwtMjAwKTtcbiAgYm9yZGVyLXJhZGl1czogdmFyKC0tcmFkaXVzLW1kKTtcbiAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tY29sb3ItbmV1dHJhbC0wKTtcbiAgY29sb3I6IHZhcigtLWNvbG9yLW5ldXRyYWwtOTAwKTtcbiAgb3V0bGluZTogbm9uZTtcbiAgdHJhbnNpdGlvbjogYm9yZGVyLWNvbG9yIHZhcigtLXRyYW5zaXRpb24tZmFzdCksIGJveC1zaGFkb3cgdmFyKC0tdHJhbnNpdGlvbi1mYXN0KTtcbn1cblxuLmlucHV0OjpwbGFjZWhvbGRlciB7XG4gIGNvbG9yOiB2YXIoLS1jb2xvci1uZXV0cmFsLTQwMCk7XG59XG5cbi5pbnB1dDpmb2N1cyB7XG4gIGJvcmRlci1jb2xvcjogdmFyKC0tY29sb3ItcHJpbWFyeS01MDApO1xuICBib3gtc2hhZG93OiAwIDAgMCAzcHggdmFyKC0tY29sb3ItcHJpbWFyeS0xMDApO1xufVxuXG4uaW5wdXQ6ZGlzYWJsZWQge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1jb2xvci1uZXV0cmFsLTEwMCk7XG4gIGN1cnNvcjogbm90LWFsbG93ZWQ7XG4gIG9wYWNpdHk6IDAuNjtcbn1cblxuLmlucHV0LmVycm9yIHtcbiAgYm9yZGVyLWNvbG9yOiB2YXIoLS1jb2xvci1kYW5nZXItNTAwKTtcbn1cblxuLmlucHV0LmVycm9yOmZvY3VzIHtcbiAgYm94LXNoYWRvdzogMCAwIDAgM3B4IHJnYigyMzkgNjggNjggLyAwLjE1KTtcbn1cblxuLyogU2l6ZXMgKi9cbi5zbSAuaW5wdXQge1xuICBmb250LXNpemU6IHZhcigtLWZvbnQtc2l6ZS14cyk7XG4gIHBhZGRpbmc6IHZhcigtLXNwYWNpbmctMSkgdmFyKC0tc3BhY2luZy0yKTtcbiAgaGVpZ2h0OiAycmVtO1xufVxuXG4ubWQgLmlucHV0IHtcbiAgZm9udC1zaXplOiB2YXIoLS1mb250LXNpemUtc20pO1xuICBwYWRkaW5nOiB2YXIoLS1zcGFjaW5nLTIpIHZhcigtLXNwYWNpbmctMyk7XG4gIGhlaWdodDogMi41cmVtO1xufVxuXG4ubGcgLmlucHV0IHtcbiAgZm9udC1zaXplOiB2YXIoLS1mb250LXNpemUtbWQpO1xuICBwYWRkaW5nOiB2YXIoLS1zcGFjaW5nLTMpIHZhcigtLXNwYWNpbmctNCk7XG4gIGhlaWdodDogM3JlbTtcbn1cblxuLyogQWRvcm5tZW50cyAqL1xuLmFkb3JubWVudCB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgbGVmdDogdmFyKC0tc3BhY2luZy0zKTtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgY29sb3I6IHZhcigtLWNvbG9yLW5ldXRyYWwtNDAwKTtcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG5cbi5hZG9ybm1lbnRFbmQge1xuICBsZWZ0OiB1bnNldDtcbiAgcmlnaHQ6IHZhcigtLXNwYWNpbmctMyk7XG59XG5cbi5zbSAud2l0aFN0YXJ0IHsgcGFkZGluZy1sZWZ0OiAycmVtOyB9XG4ubWQgLndpdGhTdGFydCB7IHBhZGRpbmctbGVmdDogMi4yNXJlbTsgfVxuLmxnIC53aXRoU3RhcnQgeyBwYWRkaW5nLWxlZnQ6IDIuNXJlbTsgfVxuXG4uc20gLndpdGhFbmQgeyBwYWRkaW5nLXJpZ2h0OiAycmVtOyB9XG4ubWQgLndpdGhFbmQgeyBwYWRkaW5nLXJpZ2h0OiAyLjI1cmVtOyB9XG4ubGcgLndpdGhFbmQgeyBwYWRkaW5nLXJpZ2h0OiAyLjVyZW07IH1cblxuLmhlbHBlclRleHQge1xuICBmb250LWZhbWlseTogdmFyKC0tZm9udC1mYW1pbHktYmFzZSk7XG4gIGZvbnQtc2l6ZTogdmFyKC0tZm9udC1zaXplLXhzKTtcbiAgY29sb3I6IHZhcigtLWNvbG9yLW5ldXRyYWwtNDAwKTtcbn1cblxuLmVycm9yVGV4dCB7XG4gIGZvbnQtZmFtaWx5OiB2YXIoLS1mb250LWZhbWlseS1iYXNlKTtcbiAgZm9udC1zaXplOiB2YXIoLS1mb250LXNpemUteHMpO1xuICBjb2xvcjogdmFyKC0tY29sb3ItZGFuZ2VyLTUwMCk7XG59XG4iXX0= */","import React from \"react\";\nimport styles from \"./Input.module.scss\";\n\nexport type InputSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface InputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"size\"> {\n label?: string;\n helperText?: string;\n errorText?: string;\n size?: InputSize;\n fullWidth?: boolean;\n startAdornment?: React.ReactNode;\n endAdornment?: React.ReactNode;\n}\n\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n (\n {\n label,\n helperText,\n errorText,\n size = \"md\",\n fullWidth = false,\n startAdornment,\n endAdornment,\n id,\n className,\n ...props\n },\n ref\n ) => {\n const inputId = id ?? (label ? label.toLowerCase().replace(/\\s+/g, \"-\") : undefined);\n const hasError = Boolean(errorText);\n\n return (\n <div\n className={[\n styles.wrapper,\n fullWidth ? styles.fullWidth : \"\",\n ]\n .filter(Boolean)\n .join(\" \")}\n >\n {label && (\n <label htmlFor={inputId} className={styles.label}>\n {label}\n </label>\n )}\n <div className={[styles.inputWrapper, styles[size]].join(\" \")}>\n {startAdornment && (\n <span className={styles.adornment}>{startAdornment}</span>\n )}\n <input\n ref={ref}\n id={inputId}\n className={[\n styles.input,\n hasError ? styles.error : \"\",\n startAdornment ? styles.withStart : \"\",\n endAdornment ? styles.withEnd : \"\",\n className ?? \"\",\n ]\n .filter(Boolean)\n .join(\" \")}\n aria-invalid={hasError}\n aria-describedby={\n errorText\n ? `${inputId}-error`\n : helperText\n ? `${inputId}-helper`\n : undefined\n }\n {...props}\n />\n {endAdornment && (\n <span className={[styles.adornment, styles.adornmentEnd].join(\" \")}>\n {endAdornment}\n </span>\n )}\n </div>\n {errorText && (\n <span id={`${inputId}-error`} className={styles.errorText}>\n {errorText}\n </span>\n )}\n {helperText && !errorText && (\n <span id={`${inputId}-helper`} className={styles.helperText}>\n {helperText}\n </span>\n )}\n </div>\n );\n }\n);\n\nInput.displayName = \"Input\";\n"]}
@@ -0,0 +1,227 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ // src/components/RainCanvas/RainCanvas.tsx
7
+
8
+ // src/components/RainCanvas/RainCanvas.module.scss
9
+ var RainCanvas_module_default = {
10
+ wrapper: "RainCanvas_module_wrapper2",
11
+ trailCanvas: "RainCanvas_module_trailCanvas2",
12
+ content: "RainCanvas_module_content2",
13
+ dropContainer: "RainCanvas_module_dropContainer2"
14
+ };
15
+ var _nextId = 0;
16
+ function randomBetween(a, b) {
17
+ return a + Math.random() * (b - a);
18
+ }
19
+ function createStaticDrop(width, height) {
20
+ return {
21
+ id: _nextId++,
22
+ kind: "static",
23
+ x: randomBetween(10, width - 10),
24
+ y: randomBetween(10, height - 10),
25
+ radius: randomBetween(4, 11),
26
+ age: 0,
27
+ maxAge: randomBetween(120, 400),
28
+ speed: 0,
29
+ trail: []
30
+ };
31
+ }
32
+ var RainCanvas = ({
33
+ dropCount = 55,
34
+ background = "linear-gradient(160deg, #0f172a 0%, #1e3a5f 60%, #0f2a4a 100%)",
35
+ children,
36
+ className,
37
+ style
38
+ }) => {
39
+ const wrapperRef = react.useRef(null);
40
+ const trailCanvasRef = react.useRef(null);
41
+ const dropContainerRef = react.useRef(null);
42
+ const dropsRef = react.useRef([]);
43
+ const nodeMapRef = react.useRef(/* @__PURE__ */ new Map());
44
+ const rafRef = react.useRef(0);
45
+ const filterIdRef = react.useRef(`rnf-${Math.random().toString(36).slice(2, 7)}`);
46
+ react.useEffect(() => {
47
+ const wrapper = wrapperRef.current;
48
+ const trailCanvas = trailCanvasRef.current;
49
+ const dropContainer = dropContainerRef.current;
50
+ if (!wrapper || !trailCanvas || !dropContainer) return;
51
+ const trailCtx = trailCanvas.getContext("2d");
52
+ if (!trailCtx) return;
53
+ const filterId2 = filterIdRef.current;
54
+ const resize = () => {
55
+ const w = wrapper.offsetWidth;
56
+ const h = wrapper.offsetHeight;
57
+ trailCanvas.width = w;
58
+ trailCanvas.height = h;
59
+ dropsRef.current = Array.from(
60
+ { length: dropCount },
61
+ () => createStaticDrop(w, h)
62
+ );
63
+ };
64
+ resize();
65
+ const ro = new ResizeObserver(resize);
66
+ ro.observe(wrapper);
67
+ function getOrCreateNode(drop) {
68
+ let node = nodeMapRef.current.get(drop.id);
69
+ if (!node) {
70
+ node = document.createElement("div");
71
+ node.style.cssText = `
72
+ position: absolute;
73
+ backdrop-filter: url(#${filterId2}) brightness(1.12);
74
+ -webkit-backdrop-filter: url(#${filterId2}) brightness(1.12);
75
+ box-shadow:
76
+ inset 0 0 0 1px rgba(255,255,255,0.4),
77
+ inset -2px -3px 6px rgba(255,255,255,0.18),
78
+ inset 2px 2px 4px rgba(0, 40, 120, 0.15);
79
+ background: radial-gradient(
80
+ circle at 32% 30%,
81
+ rgba(255,255,255,0.30) 0%,
82
+ rgba(255,255,255,0.05) 45%,
83
+ transparent 65%
84
+ );
85
+ pointer-events: none;
86
+ will-change: transform;
87
+ `;
88
+ dropContainer.appendChild(node);
89
+ nodeMapRef.current.set(drop.id, node);
90
+ }
91
+ return node;
92
+ }
93
+ function removeNode(id) {
94
+ const node = nodeMapRef.current.get(id);
95
+ if (node) {
96
+ node.remove();
97
+ nodeMapRef.current.delete(id);
98
+ }
99
+ }
100
+ function syncNode(drop) {
101
+ const node = getOrCreateNode(drop);
102
+ const isSliding = drop.kind === "sliding";
103
+ const h = isSliding ? drop.radius * 2.4 : drop.radius * 2;
104
+ const br = isSliding ? "50% 50% 55% 55%" : "50%";
105
+ node.style.left = `${drop.x - drop.radius}px`;
106
+ node.style.top = `${drop.y - drop.radius}px`;
107
+ node.style.width = `${drop.radius * 2}px`;
108
+ node.style.height = `${h}px`;
109
+ node.style.borderRadius = br;
110
+ }
111
+ const tick = () => {
112
+ const { width, height } = trailCanvas;
113
+ trailCtx.fillStyle = "rgba(0,0,0,0.04)";
114
+ trailCtx.fillRect(0, 0, width, height);
115
+ const next = [];
116
+ for (const drop of dropsRef.current) {
117
+ if (drop.kind === "static") {
118
+ drop.age++;
119
+ syncNode(drop);
120
+ if (drop.age >= drop.maxAge) {
121
+ removeNode(drop.id);
122
+ next.push({
123
+ ...drop,
124
+ id: _nextId++,
125
+ kind: "sliding",
126
+ speed: randomBetween(1.5, 3.5),
127
+ trail: []
128
+ });
129
+ } else {
130
+ next.push(drop);
131
+ }
132
+ } else {
133
+ drop.trail.push({ x: drop.x, y: drop.y });
134
+ if (drop.trail.length > 24) drop.trail.shift();
135
+ if (drop.trail.length > 1) {
136
+ trailCtx.beginPath();
137
+ trailCtx.moveTo(drop.trail[0].x, drop.trail[0].y);
138
+ for (let i = 1; i < drop.trail.length; i++) {
139
+ trailCtx.lineTo(drop.trail[i].x, drop.trail[i].y);
140
+ }
141
+ trailCtx.strokeStyle = "rgba(160, 200, 255, 0.18)";
142
+ trailCtx.lineWidth = drop.radius * 0.7;
143
+ trailCtx.lineCap = "round";
144
+ trailCtx.stroke();
145
+ }
146
+ drop.y += drop.speed;
147
+ drop.speed += 0.06;
148
+ syncNode(drop);
149
+ if (drop.y - drop.radius > height) {
150
+ removeNode(drop.id);
151
+ next.push(createStaticDrop(width, height));
152
+ } else {
153
+ next.push(drop);
154
+ }
155
+ }
156
+ }
157
+ dropsRef.current = next;
158
+ rafRef.current = requestAnimationFrame(tick);
159
+ };
160
+ rafRef.current = requestAnimationFrame(tick);
161
+ return () => {
162
+ cancelAnimationFrame(rafRef.current);
163
+ ro.disconnect();
164
+ nodeMapRef.current.forEach((node) => node.remove());
165
+ nodeMapRef.current.clear();
166
+ };
167
+ }, [dropCount]);
168
+ const filterId = filterIdRef.current;
169
+ return /* @__PURE__ */ jsxRuntime.jsxs(
170
+ "div",
171
+ {
172
+ ref: wrapperRef,
173
+ className: [RainCanvas_module_default.wrapper, className ?? ""].filter(Boolean).join(" "),
174
+ style: { background, ...style },
175
+ children: [
176
+ /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "0", height: "0", style: { position: "absolute" }, children: /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs(
177
+ "filter",
178
+ {
179
+ id: filterId,
180
+ x: "-20%",
181
+ y: "-20%",
182
+ width: "140%",
183
+ height: "140%",
184
+ colorInterpolationFilters: "sRGB",
185
+ children: [
186
+ /* @__PURE__ */ jsxRuntime.jsx(
187
+ "feTurbulence",
188
+ {
189
+ type: "turbulence",
190
+ baseFrequency: "0.07 0.04",
191
+ numOctaves: "2",
192
+ result: "noise",
193
+ children: /* @__PURE__ */ jsxRuntime.jsx(
194
+ "animate",
195
+ {
196
+ attributeName: "seed",
197
+ values: "1;20;1",
198
+ dur: "5s",
199
+ repeatCount: "indefinite"
200
+ }
201
+ )
202
+ }
203
+ ),
204
+ /* @__PURE__ */ jsxRuntime.jsx(
205
+ "feDisplacementMap",
206
+ {
207
+ in: "SourceGraphic",
208
+ in2: "noise",
209
+ scale: "22",
210
+ xChannelSelector: "R",
211
+ yChannelSelector: "G"
212
+ }
213
+ )
214
+ ]
215
+ }
216
+ ) }) }),
217
+ /* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: trailCanvasRef, className: RainCanvas_module_default.trailCanvas }),
218
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: RainCanvas_module_default.content, children }),
219
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref: dropContainerRef, className: RainCanvas_module_default.dropContainer })
220
+ ]
221
+ }
222
+ );
223
+ };
224
+
225
+ exports.RainCanvas = RainCanvas;
226
+ //# sourceMappingURL=index.cjs.map
227
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/RainCanvas/RainCanvas.module.scss","../../../src/components/RainCanvas/RainCanvas.tsx"],"names":["wrapper","trailCanvas","content","dropContainer","useRef","useEffect","filterId","jsxs","jsx"],"mappings":";;;;;;;;AAAA,IAAA,yBAAA,GAAA;AAAA,EACC,OAAA,EAAAA,4BAAAA;AAAA,EAQA,WAAA,EAAAC,gCAAAA;AAAA,EAWA,OAAA,EAAAC,4BAAAA;AAAA,EAUA,aAAA,EAAAC;AAAA,CAAA;ACXD,IAAI,OAAA,GAAU,CAAA;AAEd,SAAS,aAAA,CAAc,GAAW,CAAA,EAAW;AAC3C,EAAA,OAAO,CAAA,GAAI,IAAA,CAAK,MAAA,EAAO,IAAK,CAAA,GAAI,CAAA,CAAA;AAClC;AAEA,SAAS,gBAAA,CAAiB,OAAe,MAAA,EAAsB;AAC7D,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,OAAA,EAAA;AAAA,IACJ,IAAA,EAAM,QAAA;AAAA,IACN,CAAA,EAAG,aAAA,CAAc,EAAA,EAAI,KAAA,GAAQ,EAAE,CAAA;AAAA,IAC/B,CAAA,EAAG,aAAA,CAAc,EAAA,EAAI,MAAA,GAAS,EAAE,CAAA;AAAA,IAChC,MAAA,EAAQ,aAAA,CAAc,CAAA,EAAG,EAAE,CAAA;AAAA,IAC3B,GAAA,EAAK,CAAA;AAAA,IACL,MAAA,EAAQ,aAAA,CAAc,GAAA,EAAK,GAAG,CAAA;AAAA,IAC9B,KAAA,EAAO,CAAA;AAAA,IACP,OAAO;AAAC,GACV;AACF;AAYO,IAAM,aAAwC,CAAC;AAAA,EACpD,SAAA,GAAY,EAAA;AAAA,EACZ,UAAA,GAAa,gEAAA;AAAA,EACb,QAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,KAAM;AACJ,EAAA,MAAM,UAAA,GAAaC,aAAuB,IAAI,CAAA;AAC9C,EAAA,MAAM,cAAA,GAAiBA,aAA0B,IAAI,CAAA;AACrD,EAAA,MAAM,gBAAA,GAAmBA,aAAuB,IAAI,CAAA;AACpD,EAAA,MAAM,QAAA,GAAWA,YAAA,CAAe,EAAE,CAAA;AAClC,EAAA,MAAM,UAAA,GAAaA,YAAA,iBAAoC,IAAI,GAAA,EAAK,CAAA;AAChE,EAAA,MAAM,MAAA,GAASA,aAAe,CAAC,CAAA;AAE/B,EAAA,MAAM,WAAA,GAAcA,YAAA,CAAO,CAAA,IAAA,EAAO,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAC,CAAA,CAAE,CAAA;AAE1E,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,MAAM,UAAU,UAAA,CAAW,OAAA;AAC3B,IAAA,MAAM,cAAc,cAAA,CAAe,OAAA;AACnC,IAAA,MAAM,gBAAgB,gBAAA,CAAiB,OAAA;AACvC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,WAAA,IAAe,CAAC,aAAA,EAAe;AAEhD,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,UAAA,CAAW,IAAI,CAAA;AAC5C,IAAA,IAAI,CAAC,QAAA,EAAU;AAEf,IAAA,MAAMC,YAAW,WAAA,CAAY,OAAA;AAE7B,IAAA,MAAM,SAAS,MAAM;AACnB,MAAA,MAAM,IAAI,OAAA,CAAQ,WAAA;AAClB,MAAA,MAAM,IAAI,OAAA,CAAQ,YAAA;AAClB,MAAA,WAAA,CAAY,KAAA,GAAQ,CAAA;AACpB,MAAA,WAAA,CAAY,MAAA,GAAS,CAAA;AACrB,MAAA,QAAA,CAAS,UAAU,KAAA,CAAM,IAAA;AAAA,QAAK,EAAE,QAAQ,SAAA,EAAU;AAAA,QAAG,MACnD,gBAAA,CAAiB,CAAA,EAAG,CAAC;AAAA,OACvB;AAAA,IACF,CAAA;AAEA,IAAA,MAAA,EAAO;AACP,IAAA,MAAM,EAAA,GAAK,IAAI,cAAA,CAAe,MAAM,CAAA;AACpC,IAAA,EAAA,CAAG,QAAQ,OAAO,CAAA;AAGlB,IAAA,SAAS,gBAAgB,IAAA,EAA4B;AACnD,MAAA,IAAI,IAAA,GAAO,UAAA,CAAW,OAAA,CAAQ,GAAA,CAAI,KAAK,EAAE,CAAA;AACzC,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,IAAA,GAAO,QAAA,CAAS,cAAc,KAAK,CAAA;AAGnC,QAAA,IAAA,CAAK,MAAM,OAAA,GAAU;AAAA;AAAA,gCAAA,EAEKA,SAAQ,CAAA;AAAA,wCAAA,EACAA,SAAQ,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAAA,CAAA;AAc1C,QAAA,aAAA,CAAe,YAAY,IAAI,CAAA;AAC/B,QAAA,UAAA,CAAW,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,IAAI,CAAA;AAAA,MACtC;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,SAAS,WAAW,EAAA,EAAY;AAC9B,MAAA,MAAM,IAAA,GAAO,UAAA,CAAW,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AACtC,MAAA,IAAI,IAAA,EAAM;AACR,QAAA,IAAA,CAAK,MAAA,EAAO;AACZ,QAAA,UAAA,CAAW,OAAA,CAAQ,OAAO,EAAE,CAAA;AAAA,MAC9B;AAAA,IACF;AAEA,IAAA,SAAS,SAAS,IAAA,EAAY;AAC5B,MAAA,MAAM,IAAA,GAAO,gBAAgB,IAAI,CAAA;AACjC,MAAA,MAAM,SAAA,GAAY,KAAK,IAAA,KAAS,SAAA;AAChC,MAAA,MAAM,IAAI,SAAA,GAAY,IAAA,CAAK,MAAA,GAAS,GAAA,GAAM,KAAK,MAAA,GAAS,CAAA;AACxD,MAAA,MAAM,EAAA,GAAK,YAAY,iBAAA,GAAoB,KAAA;AAC3C,MAAA,IAAA,CAAK,MAAM,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,CAAA,GAAI,KAAK,MAAM,CAAA,EAAA,CAAA;AACzC,MAAA,IAAA,CAAK,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,CAAA,GAAI,KAAK,MAAM,CAAA,EAAA,CAAA;AACxC,MAAA,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,CAAA,EAAG,IAAA,CAAK,SAAS,CAAC,CAAA,EAAA,CAAA;AACrC,MAAA,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAC,CAAA,EAAA,CAAA;AACxB,MAAA,IAAA,CAAK,MAAM,YAAA,GAAe,EAAA;AAAA,IAC5B;AAEA,IAAA,MAAM,OAAO,MAAM;AACjB,MAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,WAAA;AAG1B,MAAA,QAAA,CAAS,SAAA,GAAY,kBAAA;AACrB,MAAA,QAAA,CAAS,QAAA,CAAS,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,MAAM,CAAA;AAErC,MAAA,MAAM,OAAe,EAAC;AAEtB,MAAA,KAAA,MAAW,IAAA,IAAQ,SAAS,OAAA,EAAS;AACnC,QAAA,IAAI,IAAA,CAAK,SAAS,QAAA,EAAU;AAC1B,UAAA,IAAA,CAAK,GAAA,EAAA;AACL,UAAA,QAAA,CAAS,IAAI,CAAA;AAEb,UAAA,IAAI,IAAA,CAAK,GAAA,IAAO,IAAA,CAAK,MAAA,EAAQ;AAE3B,YAAA,UAAA,CAAW,KAAK,EAAE,CAAA;AAClB,YAAA,IAAA,CAAK,IAAA,CAAK;AAAA,cACR,GAAG,IAAA;AAAA,cACH,EAAA,EAAI,OAAA,EAAA;AAAA,cACJ,IAAA,EAAM,SAAA;AAAA,cACN,KAAA,EAAO,aAAA,CAAc,GAAA,EAAK,GAAG,CAAA;AAAA,cAC7B,OAAO;AAAC,aACT,CAAA;AAAA,UACH,CAAA,MAAO;AACL,YAAA,IAAA,CAAK,KAAK,IAAI,CAAA;AAAA,UAChB;AAAA,QACF,CAAA,MAAO;AAEL,UAAA,IAAA,CAAK,KAAA,CAAM,KAAK,EAAE,CAAA,EAAG,KAAK,CAAA,EAAG,CAAA,EAAG,IAAA,CAAK,CAAA,EAAG,CAAA;AACxC,UAAA,IAAI,KAAK,KAAA,CAAM,MAAA,GAAS,EAAA,EAAI,IAAA,CAAK,MAAM,KAAA,EAAM;AAG7C,UAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG;AACzB,YAAA,QAAA,CAAS,SAAA,EAAU;AACnB,YAAA,QAAA,CAAS,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,CAAE,GAAG,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,CAAE,CAAC,CAAA;AAChD,YAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AAC1C,cAAA,QAAA,CAAS,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,CAAE,GAAG,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,CAAE,CAAC,CAAA;AAAA,YAClD;AACA,YAAA,QAAA,CAAS,WAAA,GAAc,2BAAA;AACvB,YAAA,QAAA,CAAS,SAAA,GAAY,KAAK,MAAA,GAAS,GAAA;AACnC,YAAA,QAAA,CAAS,OAAA,GAAU,OAAA;AACnB,YAAA,QAAA,CAAS,MAAA,EAAO;AAAA,UAClB;AAEA,UAAA,IAAA,CAAK,KAAK,IAAA,CAAK,KAAA;AACf,UAAA,IAAA,CAAK,KAAA,IAAS,IAAA;AACd,UAAA,QAAA,CAAS,IAAI,CAAA;AAEb,UAAA,IAAI,IAAA,CAAK,CAAA,GAAI,IAAA,CAAK,MAAA,GAAS,MAAA,EAAQ;AACjC,YAAA,UAAA,CAAW,KAAK,EAAE,CAAA;AAClB,YAAA,IAAA,CAAK,IAAA,CAAK,gBAAA,CAAiB,KAAA,EAAO,MAAM,CAAC,CAAA;AAAA,UAC3C,CAAA,MAAO;AACL,YAAA,IAAA,CAAK,KAAK,IAAI,CAAA;AAAA,UAChB;AAAA,QACF;AAAA,MACF;AAEA,MAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AACnB,MAAA,MAAA,CAAO,OAAA,GAAU,sBAAsB,IAAI,CAAA;AAAA,IAC7C,CAAA;AAEA,IAAA,MAAA,CAAO,OAAA,GAAU,sBAAsB,IAAI,CAAA;AAE3C,IAAA,OAAO,MAAM;AACX,MAAA,oBAAA,CAAqB,OAAO,OAAO,CAAA;AACnC,MAAA,EAAA,CAAG,UAAA,EAAW;AAEd,MAAA,UAAA,CAAW,QAAQ,OAAA,CAAQ,CAAC,IAAA,KAAS,IAAA,CAAK,QAAQ,CAAA;AAClD,MAAA,UAAA,CAAW,QAAQ,KAAA,EAAM;AAAA,IAC3B,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,MAAM,WAAW,WAAA,CAAY,OAAA;AAE7B,EAAA,uBACEC,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,UAAA;AAAA,MACL,SAAA,EAAW,CAAC,yBAAA,CAAO,OAAA,EAAS,SAAA,IAAa,EAAE,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAAA,MACrE,KAAA,EAAO,EAAE,UAAA,EAAY,GAAG,KAAA,EAAM;AAAA,MAQ9B,QAAA,EAAA;AAAA,wBAAAC,cAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,GAAA,EAAI,MAAA,EAAO,GAAA,EAAI,KAAA,EAAO,EAAE,QAAA,EAAU,UAAA,EAAW,EACtD,QAAA,kBAAAA,cAAA,CAAC,MAAA,EAAA,EACC,QAAA,kBAAAD,eAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,EAAA,EAAI,QAAA;AAAA,YACJ,CAAA,EAAE,MAAA;AAAA,YACF,CAAA,EAAE,MAAA;AAAA,YACF,KAAA,EAAM,MAAA;AAAA,YACN,MAAA,EAAO,MAAA;AAAA,YACP,yBAAA,EAA0B,MAAA;AAAA,YAE1B,QAAA,EAAA;AAAA,8BAAAC,cAAA;AAAA,gBAAC,cAAA;AAAA,gBAAA;AAAA,kBACC,IAAA,EAAK,YAAA;AAAA,kBACL,aAAA,EAAc,WAAA;AAAA,kBACd,UAAA,EAAW,GAAA;AAAA,kBACX,MAAA,EAAO,OAAA;AAAA,kBAEP,QAAA,kBAAAA,cAAA;AAAA,oBAAC,SAAA;AAAA,oBAAA;AAAA,sBACC,aAAA,EAAc,MAAA;AAAA,sBACd,MAAA,EAAO,QAAA;AAAA,sBACP,GAAA,EAAI,IAAA;AAAA,sBACJ,WAAA,EAAY;AAAA;AAAA;AACd;AAAA,eACF;AAAA,8BACAA,cAAA;AAAA,gBAAC,mBAAA;AAAA,gBAAA;AAAA,kBACC,EAAA,EAAG,eAAA;AAAA,kBACH,GAAA,EAAI,OAAA;AAAA,kBACJ,KAAA,EAAM,IAAA;AAAA,kBACN,gBAAA,EAAiB,GAAA;AAAA,kBACjB,gBAAA,EAAiB;AAAA;AAAA;AACnB;AAAA;AAAA,WAEJ,CAAA,EACF,CAAA;AAAA,uCAGC,QAAA,EAAA,EAAO,GAAA,EAAK,cAAA,EAAgB,SAAA,EAAW,0BAAO,WAAA,EAAa,CAAA;AAAA,wBAG5DA,cAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,yBAAA,CAAO,SAAU,QAAA,EAAS,CAAA;AAAA,uCAGzC,KAAA,EAAA,EAAI,GAAA,EAAK,gBAAA,EAAkB,SAAA,EAAW,0BAAO,aAAA,EAAe;AAAA;AAAA;AAAA,GAC/D;AAEJ","file":"index.cjs","sourcesContent":["@charset \"UTF-8\";\n.wrapper {\n position: relative;\n overflow: hidden;\n width: 100%;\n height: 100%;\n}\n\n/* Scie umide — sotto il contenuto */\n.trailCanvas {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n display: block;\n z-index: 1;\n pointer-events: none;\n}\n\n/* Form e contenuto — sopra le scie */\n.content {\n position: absolute;\n inset: 0;\n z-index: 2;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Le gocce DOM stanno sopra tutto, ma pointer-events: none (impostato inline) */\n.dropContainer {\n position: absolute;\n inset: 0;\n z-index: 3;\n}\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlJhaW5DYW52YXMubW9kdWxlLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7OztBQUdGO0FBQ0E7RUFDRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTs7O0FBR0Y7QUFDQTtFQUNFO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTs7O0FBR0Y7QUFDQTtFQUNFO0VBQ0E7RUFDQSIsInNvdXJjZXNDb250ZW50IjpbIi53cmFwcGVyIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xufVxuXG4vKiBTY2llIHVtaWRlIOKAlCBzb3R0byBpbCBjb250ZW51dG8gKi9cbi50cmFpbENhbnZhcyB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgaW5zZXQ6IDA7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICB6LWluZGV4OiAxO1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuLyogRm9ybSBlIGNvbnRlbnV0byDigJQgc29wcmEgbGUgc2NpZSAqL1xuLmNvbnRlbnQge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGluc2V0OiAwO1xuICB6LWluZGV4OiAyO1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbn1cblxuLyogTGUgZ29jY2UgRE9NIHN0YW5ubyBzb3ByYSB0dXR0bywgbWEgcG9pbnRlci1ldmVudHM6IG5vbmUgKGltcG9zdGF0byBpbmxpbmUpICovXG4uZHJvcENvbnRhaW5lciB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgaW5zZXQ6IDA7XG4gIHotaW5kZXg6IDM7XG59XG4iXX0= */","import React, { useEffect, useRef } from \"react\";\nimport styles from \"./RainCanvas.module.scss\";\n\n// --- Tipi ---\n\ninterface Drop {\n id: number;\n kind: \"static\" | \"sliding\";\n x: number;\n y: number;\n radius: number;\n age: number;\n maxAge: number;\n speed: number;\n trail: { x: number; y: number }[];\n}\n\n// --- Helpers ---\n\nlet _nextId = 0;\n\nfunction randomBetween(a: number, b: number) {\n return a + Math.random() * (b - a);\n}\n\nfunction createStaticDrop(width: number, height: number): Drop {\n return {\n id: _nextId++,\n kind: \"static\",\n x: randomBetween(10, width - 10),\n y: randomBetween(10, height - 10),\n radius: randomBetween(4, 11),\n age: 0,\n maxAge: randomBetween(120, 400),\n speed: 0,\n trail: [],\n };\n}\n\n// --- Componente ---\n\nexport interface RainCanvasProps {\n dropCount?: number;\n background?: string;\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const RainCanvas: React.FC<RainCanvasProps> = ({\n dropCount = 55,\n background = \"linear-gradient(160deg, #0f172a 0%, #1e3a5f 60%, #0f2a4a 100%)\",\n children,\n className,\n style,\n}) => {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const trailCanvasRef = useRef<HTMLCanvasElement>(null);\n const dropContainerRef = useRef<HTMLDivElement>(null);\n const dropsRef = useRef<Drop[]>([]);\n const nodeMapRef = useRef<Map<number, HTMLDivElement>>(new Map());\n const rafRef = useRef<number>(0);\n // Unique id per istanza per evitare conflitti se ci sono più RainCanvas nella pagina\n const filterIdRef = useRef(`rnf-${Math.random().toString(36).slice(2, 7)}`);\n\n useEffect(() => {\n const wrapper = wrapperRef.current;\n const trailCanvas = trailCanvasRef.current;\n const dropContainer = dropContainerRef.current;\n if (!wrapper || !trailCanvas || !dropContainer) return;\n\n const trailCtx = trailCanvas.getContext(\"2d\");\n if (!trailCtx) return;\n\n const filterId = filterIdRef.current;\n\n const resize = () => {\n const w = wrapper.offsetWidth;\n const h = wrapper.offsetHeight;\n trailCanvas.width = w;\n trailCanvas.height = h;\n dropsRef.current = Array.from({ length: dropCount }, () =>\n createStaticDrop(w, h)\n );\n };\n\n resize();\n const ro = new ResizeObserver(resize);\n ro.observe(wrapper);\n\n // Crea un nodo DOM per una goccia e lo aggiunge al container\n function getOrCreateNode(drop: Drop): HTMLDivElement {\n let node = nodeMapRef.current.get(drop.id);\n if (!node) {\n node = document.createElement(\"div\");\n // backdrop-filter: url(#id) applica il filtro SVG al contenuto DOM sottostante\n // Questo è ciò che crea la vera distorsione del contenuto reale\n node.style.cssText = `\n position: absolute;\n backdrop-filter: url(#${filterId}) brightness(1.12);\n -webkit-backdrop-filter: url(#${filterId}) brightness(1.12);\n box-shadow:\n inset 0 0 0 1px rgba(255,255,255,0.4),\n inset -2px -3px 6px rgba(255,255,255,0.18),\n inset 2px 2px 4px rgba(0, 40, 120, 0.15);\n background: radial-gradient(\n circle at 32% 30%,\n rgba(255,255,255,0.30) 0%,\n rgba(255,255,255,0.05) 45%,\n transparent 65%\n );\n pointer-events: none;\n will-change: transform;\n `;\n dropContainer!.appendChild(node);\n nodeMapRef.current.set(drop.id, node);\n }\n return node;\n }\n\n function removeNode(id: number) {\n const node = nodeMapRef.current.get(id);\n if (node) {\n node.remove();\n nodeMapRef.current.delete(id);\n }\n }\n\n function syncNode(drop: Drop) {\n const node = getOrCreateNode(drop);\n const isSliding = drop.kind === \"sliding\";\n const h = isSliding ? drop.radius * 2.4 : drop.radius * 2;\n const br = isSliding ? \"50% 50% 55% 55%\" : \"50%\";\n node.style.left = `${drop.x - drop.radius}px`;\n node.style.top = `${drop.y - drop.radius}px`;\n node.style.width = `${drop.radius * 2}px`;\n node.style.height = `${h}px`;\n node.style.borderRadius = br;\n }\n\n const tick = () => {\n const { width, height } = trailCanvas;\n\n // Fade della scia: riempiamo con un nero semi-trasparente ogni frame\n trailCtx.fillStyle = \"rgba(0,0,0,0.04)\";\n trailCtx.fillRect(0, 0, width, height);\n\n const next: Drop[] = [];\n\n for (const drop of dropsRef.current) {\n if (drop.kind === \"static\") {\n drop.age++;\n syncNode(drop);\n\n if (drop.age >= drop.maxAge) {\n // Diventa scorrevole: rimuovo il vecchio nodo e creo uno nuovo\n removeNode(drop.id);\n next.push({\n ...drop,\n id: _nextId++,\n kind: \"sliding\",\n speed: randomBetween(1.5, 3.5),\n trail: [],\n });\n } else {\n next.push(drop);\n }\n } else {\n // Aggiorna scia\n drop.trail.push({ x: drop.x, y: drop.y });\n if (drop.trail.length > 24) drop.trail.shift();\n\n // Disegna scia umida sul canvas\n if (drop.trail.length > 1) {\n trailCtx.beginPath();\n trailCtx.moveTo(drop.trail[0].x, drop.trail[0].y);\n for (let i = 1; i < drop.trail.length; i++) {\n trailCtx.lineTo(drop.trail[i].x, drop.trail[i].y);\n }\n trailCtx.strokeStyle = \"rgba(160, 200, 255, 0.18)\";\n trailCtx.lineWidth = drop.radius * 0.7;\n trailCtx.lineCap = \"round\";\n trailCtx.stroke();\n }\n\n drop.y += drop.speed;\n drop.speed += 0.06;\n syncNode(drop);\n\n if (drop.y - drop.radius > height) {\n removeNode(drop.id);\n next.push(createStaticDrop(width, height));\n } else {\n next.push(drop);\n }\n }\n }\n\n dropsRef.current = next;\n rafRef.current = requestAnimationFrame(tick);\n };\n\n rafRef.current = requestAnimationFrame(tick);\n\n return () => {\n cancelAnimationFrame(rafRef.current);\n ro.disconnect();\n // Pulizia nodi DOM\n nodeMapRef.current.forEach((node) => node.remove());\n nodeMapRef.current.clear();\n };\n }, [dropCount]);\n\n const filterId = filterIdRef.current;\n\n return (\n <div\n ref={wrapperRef}\n className={[styles.wrapper, className ?? \"\"].filter(Boolean).join(\" \")}\n style={{ background, ...style }}\n >\n {/*\n Definizione del filtro SVG:\n - feTurbulence genera rumore procedurale (pattern d'acqua)\n - feDisplacementMap usa quel rumore per spostare i pixel del backdrop\n L'animazione del seed fa \"muovere\" l'acqua nel tempo\n */}\n <svg width=\"0\" height=\"0\" style={{ position: \"absolute\" }}>\n <defs>\n <filter\n id={filterId}\n x=\"-20%\"\n y=\"-20%\"\n width=\"140%\"\n height=\"140%\"\n colorInterpolationFilters=\"sRGB\"\n >\n <feTurbulence\n type=\"turbulence\"\n baseFrequency=\"0.07 0.04\"\n numOctaves=\"2\"\n result=\"noise\"\n >\n <animate\n attributeName=\"seed\"\n values=\"1;20;1\"\n dur=\"5s\"\n repeatCount=\"indefinite\"\n />\n </feTurbulence>\n <feDisplacementMap\n in=\"SourceGraphic\"\n in2=\"noise\"\n scale=\"22\"\n xChannelSelector=\"R\"\n yChannelSelector=\"G\"\n />\n </filter>\n </defs>\n </svg>\n\n {/* Canvas per le scie umide (z-index basso) */}\n <canvas ref={trailCanvasRef} className={styles.trailCanvas} />\n\n {/* Contenuto (form, ecc.) */}\n <div className={styles.content}>{children}</div>\n\n {/* Container delle gocce DOM — sopra il contenuto, pointer-events none */}\n <div ref={dropContainerRef} className={styles.dropContainer} />\n </div>\n );\n};\n"]}
@@ -0,0 +1,32 @@
1
+ @charset "UTF-8";
2
+
3
+ /* src/components/RainCanvas/RainCanvas.module.scss */
4
+ .RainCanvas_module_wrapper2 {
5
+ position: relative;
6
+ overflow: hidden;
7
+ width: 100%;
8
+ height: 100%;
9
+ }
10
+ .RainCanvas_module_trailCanvas2 {
11
+ position: absolute;
12
+ inset: 0;
13
+ width: 100%;
14
+ height: 100%;
15
+ display: block;
16
+ z-index: 1;
17
+ pointer-events: none;
18
+ }
19
+ .RainCanvas_module_content2 {
20
+ position: absolute;
21
+ inset: 0;
22
+ z-index: 2;
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ }
27
+ .RainCanvas_module_dropContainer2 {
28
+ position: absolute;
29
+ inset: 0;
30
+ z-index: 3;
31
+ }
32
+ /*# sourceMappingURL=index.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/RainCanvas/RainCanvas.module.scss"],"sourcesContent":[".wrapper {\n position: relative;\n overflow: hidden;\n width: 100%;\n height: 100%;\n}\n\n/* Scie umide — sotto il contenuto */\n.trailCanvas {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n display: block;\n z-index: 1;\n pointer-events: none;\n}\n\n/* Form e contenuto — sopra le scie */\n.content {\n position: absolute;\n inset: 0;\n z-index: 2;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Le gocce DOM stanno sopra tutto, ma pointer-events: none (impostato inline) */\n.dropContainer {\n position: absolute;\n inset: 0;\n z-index: 3;\n}\n"],"mappings":";;;AAAA,CAAAA;AACE,YAAA;AACA,YAAA;AACA,SAAA;AACA,UAAA;;AAIF,CAAAC;AACE,YAAA;AACA,SAAA;AACA,SAAA;AACA,UAAA;AACA,WAAA;AACA,WAAA;AACA,kBAAA;;AAIF,CAAAC;AACE,YAAA;AACA,SAAA;AACA,WAAA;AACA,WAAA;AACA,eAAA;AACA,mBAAA;;AAIF,CAAAC;AACE,YAAA;AACA,SAAA;AACA,WAAA;;","names":["wrapper","trailCanvas","content","dropContainer"]}
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+
3
+ interface RainCanvasProps {
4
+ dropCount?: number;
5
+ background?: string;
6
+ children?: React.ReactNode;
7
+ className?: string;
8
+ style?: React.CSSProperties;
9
+ }
10
+ declare const RainCanvas: React.FC<RainCanvasProps>;
11
+
12
+ export { RainCanvas, type RainCanvasProps };
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+
3
+ interface RainCanvasProps {
4
+ dropCount?: number;
5
+ background?: string;
6
+ children?: React.ReactNode;
7
+ className?: string;
8
+ style?: React.CSSProperties;
9
+ }
10
+ declare const RainCanvas: React.FC<RainCanvasProps>;
11
+
12
+ export { RainCanvas, type RainCanvasProps };
@@ -0,0 +1,225 @@
1
+ import { useRef, useEffect } from 'react';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+
4
+ // src/components/RainCanvas/RainCanvas.tsx
5
+
6
+ // src/components/RainCanvas/RainCanvas.module.scss
7
+ var RainCanvas_module_default = {
8
+ wrapper: "RainCanvas_module_wrapper2",
9
+ trailCanvas: "RainCanvas_module_trailCanvas2",
10
+ content: "RainCanvas_module_content2",
11
+ dropContainer: "RainCanvas_module_dropContainer2"
12
+ };
13
+ var _nextId = 0;
14
+ function randomBetween(a, b) {
15
+ return a + Math.random() * (b - a);
16
+ }
17
+ function createStaticDrop(width, height) {
18
+ return {
19
+ id: _nextId++,
20
+ kind: "static",
21
+ x: randomBetween(10, width - 10),
22
+ y: randomBetween(10, height - 10),
23
+ radius: randomBetween(4, 11),
24
+ age: 0,
25
+ maxAge: randomBetween(120, 400),
26
+ speed: 0,
27
+ trail: []
28
+ };
29
+ }
30
+ var RainCanvas = ({
31
+ dropCount = 55,
32
+ background = "linear-gradient(160deg, #0f172a 0%, #1e3a5f 60%, #0f2a4a 100%)",
33
+ children,
34
+ className,
35
+ style
36
+ }) => {
37
+ const wrapperRef = useRef(null);
38
+ const trailCanvasRef = useRef(null);
39
+ const dropContainerRef = useRef(null);
40
+ const dropsRef = useRef([]);
41
+ const nodeMapRef = useRef(/* @__PURE__ */ new Map());
42
+ const rafRef = useRef(0);
43
+ const filterIdRef = useRef(`rnf-${Math.random().toString(36).slice(2, 7)}`);
44
+ useEffect(() => {
45
+ const wrapper = wrapperRef.current;
46
+ const trailCanvas = trailCanvasRef.current;
47
+ const dropContainer = dropContainerRef.current;
48
+ if (!wrapper || !trailCanvas || !dropContainer) return;
49
+ const trailCtx = trailCanvas.getContext("2d");
50
+ if (!trailCtx) return;
51
+ const filterId2 = filterIdRef.current;
52
+ const resize = () => {
53
+ const w = wrapper.offsetWidth;
54
+ const h = wrapper.offsetHeight;
55
+ trailCanvas.width = w;
56
+ trailCanvas.height = h;
57
+ dropsRef.current = Array.from(
58
+ { length: dropCount },
59
+ () => createStaticDrop(w, h)
60
+ );
61
+ };
62
+ resize();
63
+ const ro = new ResizeObserver(resize);
64
+ ro.observe(wrapper);
65
+ function getOrCreateNode(drop) {
66
+ let node = nodeMapRef.current.get(drop.id);
67
+ if (!node) {
68
+ node = document.createElement("div");
69
+ node.style.cssText = `
70
+ position: absolute;
71
+ backdrop-filter: url(#${filterId2}) brightness(1.12);
72
+ -webkit-backdrop-filter: url(#${filterId2}) brightness(1.12);
73
+ box-shadow:
74
+ inset 0 0 0 1px rgba(255,255,255,0.4),
75
+ inset -2px -3px 6px rgba(255,255,255,0.18),
76
+ inset 2px 2px 4px rgba(0, 40, 120, 0.15);
77
+ background: radial-gradient(
78
+ circle at 32% 30%,
79
+ rgba(255,255,255,0.30) 0%,
80
+ rgba(255,255,255,0.05) 45%,
81
+ transparent 65%
82
+ );
83
+ pointer-events: none;
84
+ will-change: transform;
85
+ `;
86
+ dropContainer.appendChild(node);
87
+ nodeMapRef.current.set(drop.id, node);
88
+ }
89
+ return node;
90
+ }
91
+ function removeNode(id) {
92
+ const node = nodeMapRef.current.get(id);
93
+ if (node) {
94
+ node.remove();
95
+ nodeMapRef.current.delete(id);
96
+ }
97
+ }
98
+ function syncNode(drop) {
99
+ const node = getOrCreateNode(drop);
100
+ const isSliding = drop.kind === "sliding";
101
+ const h = isSliding ? drop.radius * 2.4 : drop.radius * 2;
102
+ const br = isSliding ? "50% 50% 55% 55%" : "50%";
103
+ node.style.left = `${drop.x - drop.radius}px`;
104
+ node.style.top = `${drop.y - drop.radius}px`;
105
+ node.style.width = `${drop.radius * 2}px`;
106
+ node.style.height = `${h}px`;
107
+ node.style.borderRadius = br;
108
+ }
109
+ const tick = () => {
110
+ const { width, height } = trailCanvas;
111
+ trailCtx.fillStyle = "rgba(0,0,0,0.04)";
112
+ trailCtx.fillRect(0, 0, width, height);
113
+ const next = [];
114
+ for (const drop of dropsRef.current) {
115
+ if (drop.kind === "static") {
116
+ drop.age++;
117
+ syncNode(drop);
118
+ if (drop.age >= drop.maxAge) {
119
+ removeNode(drop.id);
120
+ next.push({
121
+ ...drop,
122
+ id: _nextId++,
123
+ kind: "sliding",
124
+ speed: randomBetween(1.5, 3.5),
125
+ trail: []
126
+ });
127
+ } else {
128
+ next.push(drop);
129
+ }
130
+ } else {
131
+ drop.trail.push({ x: drop.x, y: drop.y });
132
+ if (drop.trail.length > 24) drop.trail.shift();
133
+ if (drop.trail.length > 1) {
134
+ trailCtx.beginPath();
135
+ trailCtx.moveTo(drop.trail[0].x, drop.trail[0].y);
136
+ for (let i = 1; i < drop.trail.length; i++) {
137
+ trailCtx.lineTo(drop.trail[i].x, drop.trail[i].y);
138
+ }
139
+ trailCtx.strokeStyle = "rgba(160, 200, 255, 0.18)";
140
+ trailCtx.lineWidth = drop.radius * 0.7;
141
+ trailCtx.lineCap = "round";
142
+ trailCtx.stroke();
143
+ }
144
+ drop.y += drop.speed;
145
+ drop.speed += 0.06;
146
+ syncNode(drop);
147
+ if (drop.y - drop.radius > height) {
148
+ removeNode(drop.id);
149
+ next.push(createStaticDrop(width, height));
150
+ } else {
151
+ next.push(drop);
152
+ }
153
+ }
154
+ }
155
+ dropsRef.current = next;
156
+ rafRef.current = requestAnimationFrame(tick);
157
+ };
158
+ rafRef.current = requestAnimationFrame(tick);
159
+ return () => {
160
+ cancelAnimationFrame(rafRef.current);
161
+ ro.disconnect();
162
+ nodeMapRef.current.forEach((node) => node.remove());
163
+ nodeMapRef.current.clear();
164
+ };
165
+ }, [dropCount]);
166
+ const filterId = filterIdRef.current;
167
+ return /* @__PURE__ */ jsxs(
168
+ "div",
169
+ {
170
+ ref: wrapperRef,
171
+ className: [RainCanvas_module_default.wrapper, className ?? ""].filter(Boolean).join(" "),
172
+ style: { background, ...style },
173
+ children: [
174
+ /* @__PURE__ */ jsx("svg", { width: "0", height: "0", style: { position: "absolute" }, children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs(
175
+ "filter",
176
+ {
177
+ id: filterId,
178
+ x: "-20%",
179
+ y: "-20%",
180
+ width: "140%",
181
+ height: "140%",
182
+ colorInterpolationFilters: "sRGB",
183
+ children: [
184
+ /* @__PURE__ */ jsx(
185
+ "feTurbulence",
186
+ {
187
+ type: "turbulence",
188
+ baseFrequency: "0.07 0.04",
189
+ numOctaves: "2",
190
+ result: "noise",
191
+ children: /* @__PURE__ */ jsx(
192
+ "animate",
193
+ {
194
+ attributeName: "seed",
195
+ values: "1;20;1",
196
+ dur: "5s",
197
+ repeatCount: "indefinite"
198
+ }
199
+ )
200
+ }
201
+ ),
202
+ /* @__PURE__ */ jsx(
203
+ "feDisplacementMap",
204
+ {
205
+ in: "SourceGraphic",
206
+ in2: "noise",
207
+ scale: "22",
208
+ xChannelSelector: "R",
209
+ yChannelSelector: "G"
210
+ }
211
+ )
212
+ ]
213
+ }
214
+ ) }) }),
215
+ /* @__PURE__ */ jsx("canvas", { ref: trailCanvasRef, className: RainCanvas_module_default.trailCanvas }),
216
+ /* @__PURE__ */ jsx("div", { className: RainCanvas_module_default.content, children }),
217
+ /* @__PURE__ */ jsx("div", { ref: dropContainerRef, className: RainCanvas_module_default.dropContainer })
218
+ ]
219
+ }
220
+ );
221
+ };
222
+
223
+ export { RainCanvas };
224
+ //# sourceMappingURL=index.js.map
225
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/RainCanvas/RainCanvas.module.scss","../../../src/components/RainCanvas/RainCanvas.tsx"],"names":["wrapper","trailCanvas","content","dropContainer","filterId"],"mappings":"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","file":"index.js","sourcesContent":["@charset \"UTF-8\";\n.wrapper {\n position: relative;\n overflow: hidden;\n width: 100%;\n height: 100%;\n}\n\n/* Scie umide — sotto il contenuto */\n.trailCanvas {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n display: block;\n z-index: 1;\n pointer-events: none;\n}\n\n/* Form e contenuto — sopra le scie */\n.content {\n position: absolute;\n inset: 0;\n z-index: 2;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Le gocce DOM stanno sopra tutto, ma pointer-events: none (impostato inline) */\n.dropContainer {\n position: absolute;\n inset: 0;\n z-index: 3;\n}\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlJhaW5DYW52YXMubW9kdWxlLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7OztBQUdGO0FBQ0E7RUFDRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTs7O0FBR0Y7QUFDQTtFQUNFO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTs7O0FBR0Y7QUFDQTtFQUNFO0VBQ0E7RUFDQSIsInNvdXJjZXNDb250ZW50IjpbIi53cmFwcGVyIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAxMDAlO1xufVxuXG4vKiBTY2llIHVtaWRlIOKAlCBzb3R0byBpbCBjb250ZW51dG8gKi9cbi50cmFpbENhbnZhcyB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgaW5zZXQ6IDA7XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICB6LWluZGV4OiAxO1xuICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuLyogRm9ybSBlIGNvbnRlbnV0byDigJQgc29wcmEgbGUgc2NpZSAqL1xuLmNvbnRlbnQge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGluc2V0OiAwO1xuICB6LWluZGV4OiAyO1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbn1cblxuLyogTGUgZ29jY2UgRE9NIHN0YW5ubyBzb3ByYSB0dXR0bywgbWEgcG9pbnRlci1ldmVudHM6IG5vbmUgKGltcG9zdGF0byBpbmxpbmUpICovXG4uZHJvcENvbnRhaW5lciB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgaW5zZXQ6IDA7XG4gIHotaW5kZXg6IDM7XG59XG4iXX0= */","import React, { useEffect, useRef } from \"react\";\nimport styles from \"./RainCanvas.module.scss\";\n\n// --- Tipi ---\n\ninterface Drop {\n id: number;\n kind: \"static\" | \"sliding\";\n x: number;\n y: number;\n radius: number;\n age: number;\n maxAge: number;\n speed: number;\n trail: { x: number; y: number }[];\n}\n\n// --- Helpers ---\n\nlet _nextId = 0;\n\nfunction randomBetween(a: number, b: number) {\n return a + Math.random() * (b - a);\n}\n\nfunction createStaticDrop(width: number, height: number): Drop {\n return {\n id: _nextId++,\n kind: \"static\",\n x: randomBetween(10, width - 10),\n y: randomBetween(10, height - 10),\n radius: randomBetween(4, 11),\n age: 0,\n maxAge: randomBetween(120, 400),\n speed: 0,\n trail: [],\n };\n}\n\n// --- Componente ---\n\nexport interface RainCanvasProps {\n dropCount?: number;\n background?: string;\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\nexport const RainCanvas: React.FC<RainCanvasProps> = ({\n dropCount = 55,\n background = \"linear-gradient(160deg, #0f172a 0%, #1e3a5f 60%, #0f2a4a 100%)\",\n children,\n className,\n style,\n}) => {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const trailCanvasRef = useRef<HTMLCanvasElement>(null);\n const dropContainerRef = useRef<HTMLDivElement>(null);\n const dropsRef = useRef<Drop[]>([]);\n const nodeMapRef = useRef<Map<number, HTMLDivElement>>(new Map());\n const rafRef = useRef<number>(0);\n // Unique id per istanza per evitare conflitti se ci sono più RainCanvas nella pagina\n const filterIdRef = useRef(`rnf-${Math.random().toString(36).slice(2, 7)}`);\n\n useEffect(() => {\n const wrapper = wrapperRef.current;\n const trailCanvas = trailCanvasRef.current;\n const dropContainer = dropContainerRef.current;\n if (!wrapper || !trailCanvas || !dropContainer) return;\n\n const trailCtx = trailCanvas.getContext(\"2d\");\n if (!trailCtx) return;\n\n const filterId = filterIdRef.current;\n\n const resize = () => {\n const w = wrapper.offsetWidth;\n const h = wrapper.offsetHeight;\n trailCanvas.width = w;\n trailCanvas.height = h;\n dropsRef.current = Array.from({ length: dropCount }, () =>\n createStaticDrop(w, h)\n );\n };\n\n resize();\n const ro = new ResizeObserver(resize);\n ro.observe(wrapper);\n\n // Crea un nodo DOM per una goccia e lo aggiunge al container\n function getOrCreateNode(drop: Drop): HTMLDivElement {\n let node = nodeMapRef.current.get(drop.id);\n if (!node) {\n node = document.createElement(\"div\");\n // backdrop-filter: url(#id) applica il filtro SVG al contenuto DOM sottostante\n // Questo è ciò che crea la vera distorsione del contenuto reale\n node.style.cssText = `\n position: absolute;\n backdrop-filter: url(#${filterId}) brightness(1.12);\n -webkit-backdrop-filter: url(#${filterId}) brightness(1.12);\n box-shadow:\n inset 0 0 0 1px rgba(255,255,255,0.4),\n inset -2px -3px 6px rgba(255,255,255,0.18),\n inset 2px 2px 4px rgba(0, 40, 120, 0.15);\n background: radial-gradient(\n circle at 32% 30%,\n rgba(255,255,255,0.30) 0%,\n rgba(255,255,255,0.05) 45%,\n transparent 65%\n );\n pointer-events: none;\n will-change: transform;\n `;\n dropContainer!.appendChild(node);\n nodeMapRef.current.set(drop.id, node);\n }\n return node;\n }\n\n function removeNode(id: number) {\n const node = nodeMapRef.current.get(id);\n if (node) {\n node.remove();\n nodeMapRef.current.delete(id);\n }\n }\n\n function syncNode(drop: Drop) {\n const node = getOrCreateNode(drop);\n const isSliding = drop.kind === \"sliding\";\n const h = isSliding ? drop.radius * 2.4 : drop.radius * 2;\n const br = isSliding ? \"50% 50% 55% 55%\" : \"50%\";\n node.style.left = `${drop.x - drop.radius}px`;\n node.style.top = `${drop.y - drop.radius}px`;\n node.style.width = `${drop.radius * 2}px`;\n node.style.height = `${h}px`;\n node.style.borderRadius = br;\n }\n\n const tick = () => {\n const { width, height } = trailCanvas;\n\n // Fade della scia: riempiamo con un nero semi-trasparente ogni frame\n trailCtx.fillStyle = \"rgba(0,0,0,0.04)\";\n trailCtx.fillRect(0, 0, width, height);\n\n const next: Drop[] = [];\n\n for (const drop of dropsRef.current) {\n if (drop.kind === \"static\") {\n drop.age++;\n syncNode(drop);\n\n if (drop.age >= drop.maxAge) {\n // Diventa scorrevole: rimuovo il vecchio nodo e creo uno nuovo\n removeNode(drop.id);\n next.push({\n ...drop,\n id: _nextId++,\n kind: \"sliding\",\n speed: randomBetween(1.5, 3.5),\n trail: [],\n });\n } else {\n next.push(drop);\n }\n } else {\n // Aggiorna scia\n drop.trail.push({ x: drop.x, y: drop.y });\n if (drop.trail.length > 24) drop.trail.shift();\n\n // Disegna scia umida sul canvas\n if (drop.trail.length > 1) {\n trailCtx.beginPath();\n trailCtx.moveTo(drop.trail[0].x, drop.trail[0].y);\n for (let i = 1; i < drop.trail.length; i++) {\n trailCtx.lineTo(drop.trail[i].x, drop.trail[i].y);\n }\n trailCtx.strokeStyle = \"rgba(160, 200, 255, 0.18)\";\n trailCtx.lineWidth = drop.radius * 0.7;\n trailCtx.lineCap = \"round\";\n trailCtx.stroke();\n }\n\n drop.y += drop.speed;\n drop.speed += 0.06;\n syncNode(drop);\n\n if (drop.y - drop.radius > height) {\n removeNode(drop.id);\n next.push(createStaticDrop(width, height));\n } else {\n next.push(drop);\n }\n }\n }\n\n dropsRef.current = next;\n rafRef.current = requestAnimationFrame(tick);\n };\n\n rafRef.current = requestAnimationFrame(tick);\n\n return () => {\n cancelAnimationFrame(rafRef.current);\n ro.disconnect();\n // Pulizia nodi DOM\n nodeMapRef.current.forEach((node) => node.remove());\n nodeMapRef.current.clear();\n };\n }, [dropCount]);\n\n const filterId = filterIdRef.current;\n\n return (\n <div\n ref={wrapperRef}\n className={[styles.wrapper, className ?? \"\"].filter(Boolean).join(\" \")}\n style={{ background, ...style }}\n >\n {/*\n Definizione del filtro SVG:\n - feTurbulence genera rumore procedurale (pattern d'acqua)\n - feDisplacementMap usa quel rumore per spostare i pixel del backdrop\n L'animazione del seed fa \"muovere\" l'acqua nel tempo\n */}\n <svg width=\"0\" height=\"0\" style={{ position: \"absolute\" }}>\n <defs>\n <filter\n id={filterId}\n x=\"-20%\"\n y=\"-20%\"\n width=\"140%\"\n height=\"140%\"\n colorInterpolationFilters=\"sRGB\"\n >\n <feTurbulence\n type=\"turbulence\"\n baseFrequency=\"0.07 0.04\"\n numOctaves=\"2\"\n result=\"noise\"\n >\n <animate\n attributeName=\"seed\"\n values=\"1;20;1\"\n dur=\"5s\"\n repeatCount=\"indefinite\"\n />\n </feTurbulence>\n <feDisplacementMap\n in=\"SourceGraphic\"\n in2=\"noise\"\n scale=\"22\"\n xChannelSelector=\"R\"\n yChannelSelector=\"G\"\n />\n </filter>\n </defs>\n </svg>\n\n {/* Canvas per le scie umide (z-index basso) */}\n <canvas ref={trailCanvasRef} className={styles.trailCanvas} />\n\n {/* Contenuto (form, ecc.) */}\n <div className={styles.content}>{children}</div>\n\n {/* Container delle gocce DOM — sopra il contenuto, pointer-events none */}\n <div ref={dropContainerRef} className={styles.dropContainer} />\n </div>\n );\n};\n"]}