blocks-dusted 0.1.10 → 0.1.11

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 (246) hide show
  1. package/README.md +35 -0
  2. package/package.json +1 -1
  3. package/src/utils/paths.js +13 -13
  4. package/templates/blocks/DD-Accordion/Component.tsx +229 -0
  5. package/templates/blocks/DD-Accordion/README.md +3 -0
  6. package/templates/blocks/DD-Accordion/config.ts +73 -0
  7. package/templates/blocks/DD-Accordion/manifest.json +75 -0
  8. package/templates/blocks/DD-AnimText/Component.tsx +788 -0
  9. package/templates/blocks/DD-AnimText/README.md +3 -0
  10. package/templates/blocks/DD-AnimText/config.ts +295 -0
  11. package/templates/blocks/DD-AnimText/manifest.json +85 -0
  12. package/templates/blocks/DD-AsideNav/Component.tsx +321 -0
  13. package/templates/blocks/DD-AsideNav/config.ts +204 -0
  14. package/templates/blocks/DD-AsideNav/manifest.json +80 -0
  15. package/templates/blocks/DD-Banner/Component.tsx +51 -0
  16. package/templates/blocks/DD-Banner/config.ts +57 -0
  17. package/templates/blocks/DD-Banner/manifest.json +72 -0
  18. package/templates/blocks/DD-BgLightning/Component.tsx +44 -0
  19. package/templates/blocks/DD-BgLightning/README.md +3 -0
  20. package/templates/blocks/DD-BgLightning/config.ts +97 -0
  21. package/templates/blocks/DD-BgLightning/manifest.json +79 -0
  22. package/templates/blocks/DD-BookCall/Component.tsx +10 -11
  23. package/templates/blocks/DD-BookCall/config.ts +238 -238
  24. package/templates/blocks/DD-ButtonPop/Component.tsx +117 -0
  25. package/templates/blocks/DD-ButtonPop/config.ts +105 -0
  26. package/templates/blocks/DD-ButtonPop/manifest.json +88 -0
  27. package/templates/blocks/DD-ButtonPop/svg-icons/Dust2.tsx +167 -0
  28. package/templates/blocks/DD-Card/Component.tsx +251 -0
  29. package/templates/blocks/DD-Card/README.md +4 -0
  30. package/templates/blocks/DD-Card/config.ts +154 -0
  31. package/templates/blocks/DD-Card/manifest.json +82 -0
  32. package/templates/blocks/DD-CardTemplate01/Component.tsx +5 -6
  33. package/templates/blocks/DD-CardTemplate01/config.ts +106 -106
  34. package/templates/blocks/DD-Carousel-A/Component.tsx +249 -249
  35. package/templates/blocks/DD-Carousel-B/Component.tsx +403 -403
  36. package/templates/blocks/DD-Chip/Component.tsx +250 -0
  37. package/templates/blocks/DD-Chip/EXAMPLES.md +313 -0
  38. package/templates/blocks/DD-Chip/README.md +202 -0
  39. package/templates/blocks/DD-Chip/config.ts +369 -0
  40. package/templates/blocks/DD-Chip/manifest.json +74 -0
  41. package/templates/blocks/DD-ComparisonTable/Component.tsx +256 -256
  42. package/templates/blocks/DD-Contact/Component.tsx +434 -434
  43. package/templates/blocks/DD-Contact/config.ts +22 -22
  44. package/templates/blocks/DD-Counter/Component.tsx +190 -0
  45. package/templates/blocks/DD-Counter/README.md +4 -0
  46. package/templates/blocks/DD-Counter/config.ts +291 -0
  47. package/templates/blocks/DD-Counter/manifest.json +74 -0
  48. package/templates/blocks/DD-CustomCSS/Component.tsx +8 -0
  49. package/templates/blocks/DD-CustomCSS/README.md +4 -0
  50. package/templates/blocks/DD-CustomCSS/addToLayout.md +5 -0
  51. package/templates/blocks/DD-CustomCSS/config.ts +22 -0
  52. package/templates/blocks/DD-CustomCSS/manifest.json +72 -0
  53. package/templates/blocks/DD-CustomCSS/renderCustomCSS.md +7 -0
  54. package/templates/blocks/DD-FeatCat/Component.tsx +302 -302
  55. package/templates/blocks/DD-FeatCat/config.ts +201 -201
  56. package/templates/blocks/DD-FeatStrip/Component.tsx +585 -585
  57. package/templates/blocks/DD-FeatStrip/config.ts +134 -134
  58. package/templates/blocks/DD-FluidBtn/ButtonsEyeCatching.tsx +628 -0
  59. package/templates/blocks/DD-FluidBtn/Component.tsx +43 -0
  60. package/templates/blocks/DD-FluidBtn/README.md +6 -0
  61. package/templates/blocks/DD-FluidBtn/config.ts +102 -0
  62. package/templates/blocks/DD-FluidBtn/manifest.json +86 -0
  63. package/templates/blocks/DD-GooeyInfo/Component.tsx +149 -0
  64. package/templates/blocks/DD-GooeyInfo/config.ts +135 -0
  65. package/templates/blocks/DD-GooeyInfo/manifest.json +72 -0
  66. package/templates/blocks/DD-Hero/Component.tsx +40 -17
  67. package/templates/blocks/DD-Hero/config.ts +267 -267
  68. package/templates/blocks/DD-HorizontalScroll/Component.tsx +4 -2
  69. package/templates/blocks/DD-HorizontalScroll/config.ts +231 -231
  70. package/templates/blocks/DD-Icon/Component.tsx +287 -0
  71. package/templates/blocks/DD-Icon/README.md +4 -0
  72. package/templates/blocks/DD-Icon/config.ts +258 -0
  73. package/templates/blocks/DD-Icon/hooks/revalidateBlockIds.ts +66 -0
  74. package/templates/blocks/DD-Icon/manifest.json +82 -0
  75. package/templates/blocks/DD-IconButton/Component.tsx +455 -0
  76. package/templates/blocks/DD-IconButton/README.md +326 -0
  77. package/templates/blocks/DD-IconButton/config.ts +239 -0
  78. package/templates/blocks/DD-IconButton/manifest.json +85 -0
  79. package/templates/blocks/DD-IdTag/Component.tsx +21 -0
  80. package/templates/blocks/DD-IdTag/README.md +4 -0
  81. package/templates/blocks/DD-IdTag/config.ts +41 -0
  82. package/templates/blocks/DD-IdTag/manifest.json +72 -0
  83. package/templates/blocks/DD-Iframe/Component.tsx +45 -0
  84. package/templates/blocks/DD-Iframe/README.md +4 -0
  85. package/templates/blocks/DD-Iframe/config.ts +47 -0
  86. package/templates/blocks/DD-Iframe/manifest.json +72 -0
  87. package/templates/blocks/DD-IframeMedia/Component.tsx +129 -0
  88. package/templates/blocks/DD-IframeMedia/README.md +4 -0
  89. package/templates/blocks/DD-IframeMedia/config.ts +79 -0
  90. package/templates/blocks/DD-IframeMedia/manifest.json +72 -0
  91. package/templates/blocks/DD-LineAnim/Component.tsx +36 -0
  92. package/templates/blocks/DD-LineAnim/README.md +4 -0
  93. package/templates/blocks/DD-LineAnim/config.ts +90 -0
  94. package/templates/blocks/DD-LineAnim/manifest.json +80 -0
  95. package/templates/blocks/DD-LinkGrid/Component.tsx +119 -0
  96. package/templates/blocks/DD-LinkGrid/README.md +4 -0
  97. package/templates/blocks/DD-LinkGrid/config.ts +51 -0
  98. package/templates/blocks/DD-LinkGrid/manifest.json +74 -0
  99. package/templates/blocks/DD-LogoMarq/Component.tsx +132 -0
  100. package/templates/blocks/DD-LogoMarq/README.md +4 -0
  101. package/templates/blocks/DD-LogoMarq/config.ts +264 -0
  102. package/templates/blocks/DD-LogoMarq/manifest.json +82 -0
  103. package/templates/blocks/DD-Lottie/Component.tsx +459 -0
  104. package/templates/blocks/DD-Lottie/README.md +4 -0
  105. package/templates/blocks/DD-Lottie/config.ts +379 -0
  106. package/templates/blocks/DD-Lottie/index.tsx +28 -0
  107. package/templates/blocks/DD-Lottie/manifest.json +83 -0
  108. package/templates/blocks/DD-MagicBento/Component.tsx +777 -0
  109. package/templates/blocks/DD-MagicBento/README.md +4 -0
  110. package/templates/blocks/DD-MagicBento/config.ts +264 -0
  111. package/templates/blocks/DD-MagicBento/manifest.json +74 -0
  112. package/templates/blocks/DD-MasonaryMedia/Component.tsx +547 -545
  113. package/templates/blocks/DD-MasonaryMedia/config.ts +2 -2
  114. package/templates/blocks/DD-MasonaryMedia/vendor.d.ts +2 -2
  115. package/templates/blocks/DD-Masonry/Component.tsx +645 -0
  116. package/templates/blocks/DD-Masonry/README.md +4 -0
  117. package/templates/blocks/DD-Masonry/config.ts +475 -0
  118. package/templates/blocks/DD-Masonry/manifest.json +82 -0
  119. package/templates/blocks/DD-Pricing/Component.tsx +372 -372
  120. package/templates/blocks/DD-Process/Component.tsx +149 -149
  121. package/templates/blocks/DD-Process/config.ts +150 -150
  122. package/templates/blocks/DD-Progress/Component.tsx +141 -0
  123. package/templates/blocks/DD-Progress/README.md +4 -0
  124. package/templates/blocks/DD-Progress/config.ts +175 -0
  125. package/templates/blocks/DD-Progress/manifest.json +74 -0
  126. package/templates/blocks/DD-ProjHeader/Component.tsx +91 -0
  127. package/templates/blocks/DD-ProjHeader/README.md +4 -0
  128. package/templates/blocks/DD-ProjHeader/config.ts +96 -0
  129. package/templates/blocks/DD-ProjHeader/manifest.json +72 -0
  130. package/templates/blocks/DD-ProjSlider/Component.tsx +123 -0
  131. package/templates/blocks/DD-ProjSlider/README.md +4 -0
  132. package/templates/blocks/DD-ProjSlider/config.ts +64 -0
  133. package/templates/blocks/DD-ProjSlider/manifest.json +72 -0
  134. package/templates/blocks/DD-ScrollText/Component.tsx +114 -0
  135. package/templates/blocks/DD-ScrollText/README.md +4 -0
  136. package/templates/blocks/DD-ScrollText/config.ts +58 -0
  137. package/templates/blocks/DD-ScrollText/manifest.json +72 -0
  138. package/templates/blocks/DD-Section/Component.tsx +266 -266
  139. package/templates/blocks/DD-Separator/Component.tsx +66 -0
  140. package/templates/blocks/DD-Separator/README.md +4 -0
  141. package/templates/blocks/DD-Separator/config.ts +58 -0
  142. package/templates/blocks/DD-Separator/manifest.json +72 -0
  143. package/templates/blocks/DD-Services/Component.tsx +176 -176
  144. package/templates/blocks/DD-Services/config.ts +149 -149
  145. package/templates/blocks/DD-ShowcaseGrid/Component.tsx +307 -307
  146. package/templates/blocks/DD-Slider-A/Component.tsx +237 -237
  147. package/templates/blocks/DD-StackCards/Component.tsx +473 -473
  148. package/templates/blocks/DD-StackCards/config.ts +399 -399
  149. package/templates/blocks/DD-Team/Component.tsx +247 -247
  150. package/templates/blocks/DD-Team/config.ts +173 -173
  151. package/templates/blocks/DD-TeamCards/Component.tsx +251 -0
  152. package/templates/blocks/DD-TeamCards/README.md +4 -0
  153. package/templates/blocks/DD-TeamCards/config.ts +302 -0
  154. package/templates/blocks/DD-TeamCards/manifest.json +74 -0
  155. package/templates/blocks/DD-TechStack/Component.tsx +168 -162
  156. package/templates/blocks/DD-TechStack/config.ts +153 -153
  157. package/templates/blocks/DD-TestMarq/Component.tsx +132 -0
  158. package/templates/blocks/DD-TestMarq/README.md +4 -0
  159. package/templates/blocks/DD-TestMarq/RowLabel.tsx +9 -0
  160. package/templates/blocks/DD-TestMarq/config.ts +88 -0
  161. package/templates/blocks/DD-TestMarq/manifest.json +72 -0
  162. package/templates/blocks/DD-Testim/Component.tsx +247 -0
  163. package/templates/blocks/DD-Testim/README.md +4 -0
  164. package/templates/blocks/DD-Testim/config.ts +101 -0
  165. package/templates/blocks/DD-Testim/manifest.json +75 -0
  166. package/templates/blocks/DD-Testim2/Component.tsx +256 -0
  167. package/templates/blocks/DD-Testim2/README.md +4 -0
  168. package/templates/blocks/DD-Testim2/config.ts +100 -0
  169. package/templates/blocks/DD-Testim2/manifest.json +74 -0
  170. package/templates/blocks/DD-Testimonials/Component.tsx +147 -147
  171. package/templates/blocks/DD-Testimonials/config.ts +120 -120
  172. package/templates/blocks/DD-TextMarq/Component.tsx +157 -0
  173. package/templates/blocks/DD-TextMarq/README.md +4 -0
  174. package/templates/blocks/DD-TextMarq/config.ts +237 -0
  175. package/templates/blocks/DD-TextMarq/manifest.json +82 -0
  176. package/templates/blocks/DD-Thanks/Component.tsx +500 -0
  177. package/templates/blocks/DD-Thanks/README.md +4 -0
  178. package/templates/blocks/DD-Thanks/config.ts +224 -0
  179. package/templates/blocks/DD-Thanks/manifest.json +72 -0
  180. package/templates/blocks/DD-VertMarq/Component.tsx +154 -0
  181. package/templates/blocks/DD-VertMarq/README.md +4 -0
  182. package/templates/blocks/DD-VertMarq/config.ts +236 -0
  183. package/templates/blocks/DD-VertMarq/dist/index.css +6 -0
  184. package/templates/blocks/DD-VertMarq/dist/index.min.css +1 -0
  185. package/templates/blocks/DD-VertMarq/manifest.json +74 -0
  186. package/templates/blocks/DD-Work/Component.tsx +318 -315
  187. package/templates/blocks/DD-Work/config.ts +165 -165
  188. package/templates/blocks/DD-Work-B/Component.tsx +294 -294
  189. package/templates/blocks/DDHG-CTASection2/Component.tsx +185 -0
  190. package/templates/blocks/DDHG-CTASection2/config.ts +140 -0
  191. package/templates/blocks/DDHG-CTASection2/manifest.json +45 -0
  192. package/templates/blocks/DDHG-HighlightArc/Component.tsx +243 -0
  193. package/templates/blocks/DDHG-HighlightArc/config.ts +85 -0
  194. package/templates/blocks/DDHG-HighlightArc/manifest.json +46 -0
  195. package/templates/blocks/DDHG-LogoMarquee/Component.tsx +93 -0
  196. package/templates/blocks/DDHG-LogoMarquee/config.ts +66 -0
  197. package/templates/blocks/DDHG-LogoMarquee/manifest.json +39 -0
  198. package/templates/blocks/DDHG-NavCodeGrid/Component.tsx +213 -0
  199. package/templates/blocks/DDHG-NavCodeGrid/config.ts +64 -0
  200. package/templates/blocks/DDHG-NavCodeGrid/manifest.json +45 -0
  201. package/templates/blocks/DDHG-ProcessSec/Component.tsx +575 -0
  202. package/templates/blocks/DDHG-ProcessSec/config.ts +170 -0
  203. package/templates/blocks/DDHG-ProcessSec/manifest.json +56 -0
  204. package/templates/blocks/DDHG-ServiceDetails/Component.tsx +164 -0
  205. package/templates/blocks/DDHG-ServiceDetails/ServiceDetailCard.tsx +394 -0
  206. package/templates/blocks/DDHG-ServiceDetails/config.ts +77 -0
  207. package/templates/blocks/DDHG-ServiceDetails/manifest.json +50 -0
  208. package/templates/blocks/DDHG-ServiceHero/Component.tsx +234 -0
  209. package/templates/blocks/DDHG-ServiceHero/config.ts +49 -0
  210. package/templates/blocks/DDHG-ServiceHero/manifest.json +26 -0
  211. package/templates/blocks/DDHG-ServiceOverview/Component.tsx +277 -0
  212. package/templates/blocks/DDHG-ServiceOverview/config.ts +64 -0
  213. package/templates/blocks/DDHG-ServiceOverview/manifest.json +44 -0
  214. package/templates/blocks/DDHG-StatsFAQ/Component.tsx +389 -0
  215. package/templates/blocks/DDHG-StatsFAQ/config.ts +204 -0
  216. package/templates/blocks/DDHG-StatsFAQ/manifest.json +45 -0
  217. package/templates/blocks/DDHG-TeamCards/Component.tsx +131 -0
  218. package/templates/blocks/DDHG-TeamCards/config.ts +48 -0
  219. package/templates/blocks/DDHG-TeamCards/manifest.json +29 -0
  220. package/templates/shared/src/components/BgLightning/index.tsx +242 -0
  221. package/templates/shared/src/components/ui/ShareButton/index.tsx +80 -0
  222. package/templates/shared/src/components/ui/anims/FadeOnScroll.tsx +48 -0
  223. package/templates/shared/src/components/ui/anims/FadeUpOnInView.tsx +63 -0
  224. package/templates/shared/src/components/ui/anims/GlareHover.tsx +111 -0
  225. package/templates/shared/src/components/ui/anims/LineAnims.tsx +81 -0
  226. package/templates/shared/src/components/ui/anims/TitleAnims01.tsx +54 -0
  227. package/templates/shared/src/components/ui/anims/animation-container.tsx +29 -0
  228. package/templates/shared/src/components/ui/anims/blur-in.tsx +26 -0
  229. package/templates/shared/src/components/ui/anims/counter.tsx +53 -0
  230. package/templates/shared/src/components/ui/anims/fade.tsx +83 -0
  231. package/templates/shared/src/components/ui/anims/gradual-spacing.tsx +39 -0
  232. package/templates/shared/src/components/ui/anims/pull-up.tsx +93 -0
  233. package/templates/shared/src/components/ui/anims/reveal-text.tsx +76 -0
  234. package/templates/shared/src/components/ui/anims/rotate-words.tsx +43 -0
  235. package/templates/shared/src/components/ui/anims/shiny-text.tsx +58 -0
  236. package/templates/shared/src/components/ui/anims/shuffle-text.tsx +85 -0
  237. package/templates/shared/src/components/ui/anims/split-text.tsx +211 -0
  238. package/templates/shared/src/components/ui/anims/staggered-fade.tsx +133 -0
  239. package/templates/shared/src/components/ui/anims/text-scroll.tsx +111 -0
  240. package/templates/shared/src/components/ui/anims/typing-effect.tsx +112 -0
  241. package/templates/shared/src/components/ui/button-dusted-fluid/index.tsx +1521 -0
  242. package/templates/shared/src/components/ui/separator.tsx +85 -0
  243. package/templates/shared/src/hooks/useBodyScrollLock.ts +97 -0
  244. package/templates/shared/src/hooks/useClickOutside.ts +28 -0
  245. package/templates/shared/src/utilities/renderCustomCSS.ts +5 -0
  246. package/templates/shared/src/utilities/smoothScroll.ts +65 -0
@@ -0,0 +1,111 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-expressions */
2
+ 'use client'
3
+ import React, { useRef } from 'react'
4
+
5
+ interface GlareHoverProps {
6
+ width?: string
7
+ height?: string
8
+ background?: string
9
+ borderRadius?: string
10
+ borderColor?: string
11
+ children?: React.ReactNode
12
+ glareColor?: string
13
+ glareOpacity?: number
14
+ glareAngle?: number
15
+ glareSize?: number
16
+ transitionDuration?: number
17
+ playOnce?: boolean
18
+ className?: string
19
+ style?: React.CSSProperties
20
+ }
21
+
22
+ const GlareHover: React.FC<GlareHoverProps> = ({
23
+ width = 'auto',
24
+ height = 'auto',
25
+ background = 'transparent',
26
+ borderRadius = '0',
27
+ borderColor = 'transparent',
28
+ children,
29
+ glareColor = '#ffffff69',
30
+ glareOpacity = 0.5,
31
+ glareAngle = -45,
32
+ glareSize = 250,
33
+ transitionDuration = 650,
34
+ playOnce = false,
35
+ className = '',
36
+ style = {},
37
+ }) => {
38
+ const hex = glareColor.replace('#', '')
39
+ let rgba = glareColor
40
+ if (/^[\dA-Fa-f]{6}$/.test(hex)) {
41
+ const r = parseInt(hex.slice(0, 2), 16)
42
+ const g = parseInt(hex.slice(2, 4), 16)
43
+ const b = parseInt(hex.slice(4, 6), 16)
44
+ rgba = `rgba(${r}, ${g}, ${b}, ${glareOpacity})`
45
+ } else if (/^[\dA-Fa-f]{3}$/.test(hex) && hex.length === 3) {
46
+ const r = parseInt(hex[0]! + hex[0]!, 16)
47
+ const g = parseInt(hex[1]! + hex[1]!, 16)
48
+ const b = parseInt(hex[2]! + hex[2]!, 16)
49
+ rgba = `rgba(${r}, ${g}, ${b}, ${glareOpacity})`
50
+ }
51
+
52
+ const overlayRef = useRef<HTMLDivElement | null>(null)
53
+
54
+ const animateIn = () => {
55
+ const el = overlayRef.current
56
+ if (!el) return
57
+
58
+ el.style.transition = 'none'
59
+ el.style.backgroundPosition = '-100% -100%, 0 0'
60
+ el.offsetHeight
61
+ el.style.transition = `${transitionDuration}ms ease`
62
+ el.style.backgroundPosition = '100% 100%, 0 0'
63
+ }
64
+
65
+ const animateOut = () => {
66
+ const el = overlayRef.current
67
+ if (!el) return
68
+
69
+ if (playOnce) {
70
+ el.style.transition = 'none'
71
+ el.style.backgroundPosition = '-100% -100%, 0 0'
72
+ } else {
73
+ el.style.transition = `${transitionDuration}ms ease`
74
+ el.style.backgroundPosition = '-100% -100%, 0 0'
75
+ }
76
+ }
77
+
78
+ const overlayStyle: React.CSSProperties = {
79
+ position: 'absolute',
80
+ inset: 0,
81
+ background: `linear-gradient(${glareAngle}deg,
82
+ hsla(0,0%,0%,0) 60%,
83
+ ${rgba} 70%,
84
+ hsla(0,0%,0%,0) 100%)`,
85
+ backgroundSize: `${glareSize}% ${glareSize}%, 100% 100%`,
86
+ backgroundRepeat: 'no-repeat',
87
+ backgroundPosition: '-100% -100%, 0 0',
88
+ pointerEvents: 'none',
89
+ }
90
+
91
+ return (
92
+ <div
93
+ className={`relative grid place-items-center overflow-hidden border cursor-pointer ${className}`}
94
+ style={{
95
+ width,
96
+ height,
97
+ background,
98
+ borderRadius,
99
+ borderColor,
100
+ ...style,
101
+ }}
102
+ onMouseEnter={animateIn}
103
+ onMouseLeave={animateOut}
104
+ >
105
+ <div ref={overlayRef} style={overlayStyle} />
106
+ {children}
107
+ </div>
108
+ )
109
+ }
110
+
111
+ export default GlareHover
@@ -0,0 +1,81 @@
1
+ 'use client'
2
+ import React, { useEffect, useRef } from 'react'
3
+ import { gsap } from 'gsap'
4
+ import { ScrollTrigger } from 'gsap/ScrollTrigger'
5
+
6
+ gsap.registerPlugin(ScrollTrigger)
7
+
8
+ interface LineAnimProps {
9
+ direction: 'left-to-right' | 'right-to-left' | 'top-to-bottom' | 'bottom-to-top'
10
+ className?: string
11
+ trigger?: 'scroll' | 'immediate'
12
+ duration?: number
13
+ delay?: number
14
+ }
15
+
16
+ const LineAnim: React.FC<LineAnimProps> = ({
17
+ direction,
18
+ className = '',
19
+ trigger = 'scroll',
20
+ duration = 1,
21
+ delay = 0
22
+ }) => {
23
+ const lineRef = useRef<HTMLDivElement>(null)
24
+
25
+ useEffect(() => {
26
+ if (!lineRef.current) return
27
+
28
+ const isVertical = direction.includes('top') || direction.includes('bottom')
29
+ const scale = isVertical ? 'scaleY' : 'scaleX'
30
+
31
+ const animation = gsap.fromTo(
32
+ lineRef.current,
33
+ { [scale]: 0, opacity: 1 },
34
+ {
35
+ [scale]: 1,
36
+ opacity: 1,
37
+ duration,
38
+ delay,
39
+ ease: 'power2.out',
40
+ ...(trigger === 'scroll' && {
41
+ scrollTrigger: {
42
+ trigger: lineRef.current,
43
+ start: 'top 100%'
44
+ }
45
+ })
46
+ }
47
+ )
48
+
49
+ return () => {
50
+ animation.kill()
51
+ ScrollTrigger.getAll().forEach((trigger) => trigger.kill())
52
+ }
53
+ }, [direction, trigger, duration, delay])
54
+
55
+ const getLineClasses = () => {
56
+ const baseClasses = 'bg-transparent opacity-0'
57
+
58
+ switch (direction) {
59
+ case 'left-to-right':
60
+ return `h-[1px] w-screen origin-left ${baseClasses}`
61
+ case 'right-to-left':
62
+ return `h-[1px] w-screen origin-right ${baseClasses}`
63
+ case 'top-to-bottom':
64
+ return `w-[1px] h-screen origin-top ${baseClasses}`
65
+ case 'bottom-to-top':
66
+ return `w-[1px] h-screen origin-bottom ${baseClasses}`
67
+ default:
68
+ return baseClasses
69
+ }
70
+ }
71
+
72
+ return (
73
+ <div
74
+ ref={lineRef}
75
+ className={`${getLineClasses()} ${className}`}
76
+ style={{ transition: 'all 0.3s' }}
77
+ />
78
+ )
79
+ }
80
+
81
+ export default LineAnim
@@ -0,0 +1,54 @@
1
+ import React, { useEffect, useRef, ReactNode } from 'react'
2
+ import { motion } from 'framer-motion'
3
+
4
+ interface TitleAnims01Props {
5
+ children: ReactNode
6
+ }
7
+
8
+ const TitleAnims01: React.FC<TitleAnims01Props> = ({ children }) => {
9
+ const ref = useRef<HTMLDivElement>(null)
10
+
11
+ useEffect(() => {
12
+ const spanText = (text: HTMLElement) => {
13
+ const string = text.innerText
14
+ let spaned = ''
15
+ for (let i = 0; i < string.length; i++) {
16
+ if (string.substring(i, i + 1) === ' ') spaned += string.substring(i, i + 1)
17
+ else spaned += '<span>' + string.substring(i, i + 1) + '</span>'
18
+ }
19
+ text.innerHTML = spaned
20
+ }
21
+
22
+ const headline = ref.current
23
+ if (!headline) return
24
+ spanText(headline)
25
+
26
+ const animations = headline.querySelectorAll('.animation')
27
+
28
+ animations.forEach((animation) => {
29
+ const letters = animation.querySelectorAll('span')
30
+ letters.forEach((letter, i) => {
31
+ ;(letter as HTMLElement).style.animationDelay = i * 0.1 + 's'
32
+ })
33
+ })
34
+ }, [])
35
+
36
+ return (
37
+ <motion.div
38
+ ref={ref}
39
+ initial={{ opacity: 0, y: 50 }}
40
+ animate={{
41
+ opacity: 1,
42
+ y: 0,
43
+ }}
44
+ transition={{
45
+ duration: 0.3,
46
+ delay: 0.2,
47
+ }}
48
+ >
49
+ {children}
50
+ </motion.div>
51
+ )
52
+ }
53
+
54
+ export default TitleAnims01
@@ -0,0 +1,29 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { Button } from '@/components/ui/button'
5
+ import { FaPlay } from 'react-icons/fa'
6
+ import { cn } from '@/utilities/ui'
7
+
8
+ export const AnimationContainer = ({
9
+ children,
10
+ className = ''
11
+ }: {
12
+ children: React.ReactNode
13
+ className?: string
14
+ }) => {
15
+ const [key, setKey] = React.useState(0)
16
+ const onClick = () => {
17
+ setKey((prv) => prv + 1)
18
+ }
19
+ return (
20
+ <div className={cn('pb-12 pt-4 border-b dark:border-stone-900', className)}>
21
+ <div className="flex-row-end w-full mb-2">
22
+ <Button onClick={onClick} size="icon" className="rounded-md size-9" variant="outline">
23
+ <FaPlay className="size-3" />
24
+ </Button>
25
+ </div>
26
+ <div key={key}>{children}</div>
27
+ </div>
28
+ )
29
+ }
@@ -0,0 +1,26 @@
1
+ 'use client'
2
+ import { motion, useInView } from 'framer-motion'
3
+ import { cn } from '@/utilities/ui'
4
+ import * as React from 'react'
5
+
6
+ export const BlurIn = ({
7
+ children,
8
+ className
9
+ }: {
10
+ children: React.ReactNode
11
+ className?: string
12
+ }) => {
13
+ const ref = React.useRef(null)
14
+ const isInView = useInView(ref, { once: false })
15
+ return (
16
+ <motion.div
17
+ ref={ref}
18
+ initial={{ filter: 'blur(40px)', opacity: 0 }}
19
+ animate={isInView ? { filter: 'none', opacity: 1 } : {}}
20
+ transition={{ duration: 0.9, delay: 0, ease: 'easeInOut' }}
21
+ className={cn(className, 'blurin-ani')}
22
+ >
23
+ {children}
24
+ </motion.div>
25
+ )
26
+ }
@@ -0,0 +1,53 @@
1
+ 'use client'
2
+
3
+ import { KeyframeOptions, animate, useInView, useIsomorphicLayoutEffect } from 'framer-motion'
4
+ import * as React from 'react'
5
+
6
+ type AnimatedCounterProps = {
7
+ from: number
8
+ to: number
9
+ animationOptions?: KeyframeOptions & { duration?: number }
10
+ className?: string
11
+ }
12
+
13
+ export const Counter = ({
14
+ from = 0,
15
+ to,
16
+ animationOptions,
17
+ className = 'text-xl font-extrabold sm:text-2xl md:text-3xl',
18
+ }: AnimatedCounterProps) => {
19
+ const ref = React.useRef<HTMLSpanElement>(null)
20
+ const inView = useInView(ref, { once: true })
21
+
22
+ useIsomorphicLayoutEffect(() => {
23
+ const element = ref.current
24
+
25
+ if (!element) return
26
+ if (!inView) return
27
+
28
+ // Set initial value
29
+ element.textContent = String(from)
30
+
31
+ // If reduced motion is enabled in system's preferences
32
+ if (window.matchMedia('(prefers-reduced-motion)').matches) {
33
+ element.textContent = String(to)
34
+ return
35
+ }
36
+
37
+ const controls = animate(from, to, {
38
+ duration: 10,
39
+ ease: 'easeOut',
40
+ ...animationOptions,
41
+ onUpdate(value) {
42
+ element.textContent = value.toFixed(0)
43
+ },
44
+ })
45
+
46
+ // Cancel on unmount
47
+ return () => {
48
+ controls.stop()
49
+ }
50
+ }, [ref, inView, from, to])
51
+
52
+ return <span ref={ref} className={className} />
53
+ }
@@ -0,0 +1,83 @@
1
+ 'use client'
2
+ import { motion, useInView } from 'framer-motion'
3
+ import * as React from 'react'
4
+
5
+ export function TextFade({
6
+ direction,
7
+ children,
8
+ className = '',
9
+ stagger = 0.1,
10
+ delay = 0.3
11
+ }: {
12
+ direction: 'up' | 'down' | 'left' | 'right'
13
+ children: React.ReactNode
14
+ className?: string
15
+ stagger?: number
16
+ delay?: number
17
+ }) {
18
+ const getVariant = () => {
19
+ const baseTransition = {
20
+ type: 'spring' as const,
21
+ duration: 0.9,
22
+ delay
23
+ }
24
+
25
+ switch (direction) {
26
+ case 'down':
27
+ return {
28
+ show: { opacity: 1, y: 0, transition: baseTransition },
29
+ hidden: { opacity: 0, y: -20 }
30
+ }
31
+ case 'up':
32
+ return {
33
+ show: { opacity: 1, y: 0, transition: baseTransition },
34
+ hidden: { opacity: 0, y: 20 }
35
+ }
36
+ case 'left':
37
+ return {
38
+ show: { opacity: 1, x: 0, transition: baseTransition },
39
+ hidden: { opacity: 0, x: 20 }
40
+ }
41
+ case 'right':
42
+ return {
43
+ show: { opacity: 1, x: 0, transition: baseTransition },
44
+ hidden: { opacity: 0, x: -20 }
45
+ }
46
+ default:
47
+ return {
48
+ show: { opacity: 1, y: 0, transition: baseTransition },
49
+ hidden: { opacity: 0, y: 20 }
50
+ }
51
+ }
52
+ }
53
+
54
+ const FADE_VARIANT = getVariant()
55
+ const ref = React.useRef(null)
56
+ const isInView = useInView(ref, { once: false })
57
+
58
+ return (
59
+ <motion.div
60
+ ref={ref}
61
+ initial="hidden"
62
+ animate={isInView ? 'show' : ''}
63
+ viewport={{ once: false, amount: 0.5 }}
64
+ variants={{
65
+ hidden: {},
66
+ show: {
67
+ transition: {
68
+ staggerChildren: stagger
69
+ }
70
+ }
71
+ }}
72
+ className={className}
73
+ >
74
+ {React.Children.map(children, (child) =>
75
+ React.isValidElement(child) ? (
76
+ <motion.div variants={FADE_VARIANT}>{child}</motion.div>
77
+ ) : (
78
+ child
79
+ )
80
+ )}
81
+ </motion.div>
82
+ )
83
+ }
@@ -0,0 +1,39 @@
1
+ 'use client'
2
+
3
+ import { AnimatePresence, motion, useInView } from 'framer-motion'
4
+ import * as React from 'react'
5
+ import { cn } from '@/utilities/ui'
6
+
7
+ export function GradualSpacing({
8
+ text = 'Gradual Spacing',
9
+ className = '',
10
+ aniTextClass = ''
11
+ }: {
12
+ text: string
13
+ className?: string
14
+ aniTextClass?: string
15
+ }) {
16
+ const ref = React.useRef(null)
17
+ const isInView = useInView(ref, { once: false })
18
+ return (
19
+ <div className={cn('flex space-x-1 gradual-spacing-text', {})}>
20
+ <AnimatePresence>
21
+ {text.split('').map((char, i) => (
22
+ <motion.span
23
+ ref={ref}
24
+ key={i}
25
+ initial={{ opacity: 0, x: -18 }}
26
+ animate={isInView ? { opacity: 1, x: 0 } : {}}
27
+ exit="hidden"
28
+ transition={{ duration: 0.5, delay: i * 0.1 }}
29
+ className={cn('tracking-tighter md:leading-[4rem]', className, aniTextClass)}
30
+
31
+ // className="text-xl text-center sm:text-4xl font-bold tracking-tighter md:text-6xl md:leading-[4rem]"
32
+ >
33
+ {char === ' ' ? <span>&nbsp;</span> : char}
34
+ </motion.span>
35
+ ))}
36
+ </AnimatePresence>
37
+ </div>
38
+ )
39
+ }
@@ -0,0 +1,93 @@
1
+ 'use client'
2
+ import { cn } from '@/utilities/ui'
3
+ import { motion, useInView } from 'framer-motion'
4
+ import * as React from 'react'
5
+
6
+ export function LettersPullUp({
7
+ text,
8
+ className = '',
9
+ aniTextClass = '',
10
+ }: {
11
+ text: string
12
+ className?: string
13
+ aniTextClass?: string
14
+ }) {
15
+ const splittedText = text.split('')
16
+
17
+ const pullupVariant = {
18
+ initial: { y: 100, opacity: 0 },
19
+ animate: (i: number) => ({
20
+ y: 0,
21
+ opacity: 1,
22
+ transition: {
23
+ delay: i * 0.15,
24
+ },
25
+ }),
26
+ }
27
+ const ref = React.useRef<HTMLDivElement>(null)
28
+ const isInView = useInView(ref, { once: false })
29
+ return (
30
+ <div className="flex indie-pull-up-justify">
31
+ {splittedText.map((current, i) => (
32
+ <motion.div
33
+ key={i}
34
+ ref={ref}
35
+ variants={pullupVariant}
36
+ initial="initial"
37
+ animate={isInView ? 'animate' : ''}
38
+ custom={i}
39
+ className={cn('indie-pull-up', className, aniTextClass)}
40
+ >
41
+ {current === ' ' ? <span className="indie-pull-up-space">&nbsp;</span> : current}
42
+ </motion.div>
43
+ ))}
44
+ </div>
45
+ )
46
+ }
47
+
48
+ export function WordsPullUp({
49
+ text,
50
+ className = '',
51
+ aniTextClass = '',
52
+ }: {
53
+ text: string
54
+ className?: string
55
+ aniTextClass?: string
56
+ }) {
57
+ const splittedText = text.split(' ')
58
+
59
+ const pullupVariant = {
60
+ initial: { y: 100, opacity: 0 },
61
+ animate: (i: number) => ({
62
+ y: 0,
63
+ opacity: 1,
64
+ transition: {
65
+ delay: i * 0.15,
66
+ },
67
+ }),
68
+ }
69
+ const ref = React.useRef(null)
70
+ const isInView = useInView(ref, { once: false })
71
+ return (
72
+ <div className="flex indie-pull-up-justify">
73
+ {splittedText.map((current, i) => (
74
+ <motion.div
75
+ key={i}
76
+ ref={ref}
77
+ variants={pullupVariant}
78
+ initial="initial"
79
+ animate={isInView ? 'animate' : ''}
80
+ custom={i}
81
+ className={cn(
82
+ 'indie-pull-up',
83
+ 'pr-2', // class to separate words
84
+ className,
85
+ aniTextClass,
86
+ )}
87
+ >
88
+ {current === '' ? <span className="indie-pull-up-space">&nbsp;</span> : current}
89
+ </motion.div>
90
+ ))}
91
+ </div>
92
+ )
93
+ }
@@ -0,0 +1,76 @@
1
+ 'use client'
2
+
3
+ import { useEffect, useRef, useId } from 'react'
4
+ import { AnimatePresence } from 'framer-motion'
5
+ import FadeUpOnInView from './FadeUpOnInView'
6
+
7
+ interface RevealTextProps {
8
+ text: string[]
9
+ className?: string
10
+ aniTextClass?: string
11
+ instanceIndex?: number
12
+ }
13
+
14
+ // Global counter to ensure unique instances
15
+ let globalInstanceCounter = 0
16
+
17
+ export const RevealText: React.FC<RevealTextProps> = ({
18
+ text,
19
+ className,
20
+ aniTextClass,
21
+ instanceIndex
22
+ }) => {
23
+ const uniqueId = useId()
24
+ // Create a unique instance ID that persists across renders
25
+ const uniqueInstanceId = useRef<number | undefined>(undefined)
26
+
27
+ // Initialize unique instance ID only once
28
+ if (uniqueInstanceId.current === undefined) {
29
+ uniqueInstanceId.current = instanceIndex ?? globalInstanceCounter++
30
+ }
31
+
32
+ const textRef = useRef<HTMLSpanElement>(null)
33
+
34
+ useEffect(() => {
35
+ const threshold = 0.3
36
+ const observer = new IntersectionObserver(
37
+ ([entry]) => {
38
+ if (entry && entry.isIntersecting && textRef.current && text[0]) {
39
+ const element = textRef.current
40
+ const string = text[0]
41
+ let spaned = ''
42
+ for (let i = 0; i < string.length; i++) {
43
+ spaned += string[i] === ' ' ? ' ' : `<span>${string[i]}</span>`
44
+ }
45
+ element.innerHTML = spaned
46
+ const letters = element.querySelectorAll('span')
47
+
48
+ // Use the unique instance ID for staggering
49
+ const baseDelay = (uniqueInstanceId.current ?? 0) * 0.05
50
+ letters.forEach((letter, i) => {
51
+ letter.setAttribute('style', `animation-delay: ${baseDelay + i * 0.05}s;`)
52
+ })
53
+ }
54
+ },
55
+ { threshold }
56
+ )
57
+
58
+ if (textRef.current) observer.observe(textRef.current)
59
+
60
+ return () => observer.disconnect()
61
+ }, [text, uniqueId])
62
+
63
+ return (
64
+ <AnimatePresence mode="wait">
65
+ <FadeUpOnInView delay={0 + (uniqueInstanceId.current ?? 0) * 0.1} className="fadeup">
66
+ <span
67
+ ref={textRef}
68
+ className={`reveal-text animation ${className || ''} ${aniTextClass || ''}`}
69
+ style={{ fontWeight: '700' }}
70
+ dangerouslySetInnerHTML={{ __html: text[0] || '' }}
71
+ />
72
+ </FadeUpOnInView>
73
+ </AnimatePresence>
74
+ )
75
+ }
76
+ export default RevealText
@@ -0,0 +1,43 @@
1
+ 'use client'
2
+ import { cn } from '@/utilities/ui'
3
+ import * as React from 'react'
4
+ import { AnimatePresence, motion } from 'framer-motion'
5
+
6
+ export function RotateWords({
7
+ text = 'Rotate',
8
+ words = ['Word 1', 'Word 2', 'Word 3'],
9
+ className = '',
10
+ aniTextClass = '',
11
+ }: {
12
+ text: string
13
+ words: string[]
14
+ className?: string
15
+ aniTextClass?: string
16
+ }) {
17
+ const [index, setIndex] = React.useState(0)
18
+
19
+ React.useEffect(() => {
20
+ const interval = setInterval(() => {
21
+ setIndex((prevIndex) => (prevIndex + 1) % words.length)
22
+ }, 5000)
23
+ // Clean up interval on unmount
24
+ return () => clearInterval(interval)
25
+ }, [words.length])
26
+ return (
27
+ <div className={cn('tracking-tighter md:leading-[4rem] flex gap-1.5', className, aniTextClass)}>
28
+ {/* <div className="text-xl text-center sm:text-4xl font-bold tracking-tighter md:text-6xl md:leading-[4rem] w-fit flex items-center jusitfy-center mx-auto gap-1.5"> */}
29
+ {text}{' '}
30
+ <AnimatePresence mode="wait">
31
+ <motion.span
32
+ key={words[index]}
33
+ initial={{ opacity: 0, y: -40 }}
34
+ animate={{ opacity: 1, y: 0 }}
35
+ exit={{ opacity: 0, y: 40 }}
36
+ transition={{ duration: 0.5, delay: 0.3 }}
37
+ >
38
+ {words[index]}
39
+ </motion.span>
40
+ </AnimatePresence>
41
+ </div>
42
+ )
43
+ }