blocks-dusted 0.1.9 → 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 (248) 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/components/HeaderDD02/MobileBottomNav/index.tsx +352 -257
  221. package/templates/components/HeaderDD02/index.tsx +313 -229
  222. package/templates/shared/src/components/BgLightning/index.tsx +242 -0
  223. package/templates/shared/src/components/ui/ShareButton/index.tsx +80 -0
  224. package/templates/shared/src/components/ui/anims/FadeOnScroll.tsx +48 -0
  225. package/templates/shared/src/components/ui/anims/FadeUpOnInView.tsx +63 -0
  226. package/templates/shared/src/components/ui/anims/GlareHover.tsx +111 -0
  227. package/templates/shared/src/components/ui/anims/LineAnims.tsx +81 -0
  228. package/templates/shared/src/components/ui/anims/TitleAnims01.tsx +54 -0
  229. package/templates/shared/src/components/ui/anims/animation-container.tsx +29 -0
  230. package/templates/shared/src/components/ui/anims/blur-in.tsx +26 -0
  231. package/templates/shared/src/components/ui/anims/counter.tsx +53 -0
  232. package/templates/shared/src/components/ui/anims/fade.tsx +83 -0
  233. package/templates/shared/src/components/ui/anims/gradual-spacing.tsx +39 -0
  234. package/templates/shared/src/components/ui/anims/pull-up.tsx +93 -0
  235. package/templates/shared/src/components/ui/anims/reveal-text.tsx +76 -0
  236. package/templates/shared/src/components/ui/anims/rotate-words.tsx +43 -0
  237. package/templates/shared/src/components/ui/anims/shiny-text.tsx +58 -0
  238. package/templates/shared/src/components/ui/anims/shuffle-text.tsx +85 -0
  239. package/templates/shared/src/components/ui/anims/split-text.tsx +211 -0
  240. package/templates/shared/src/components/ui/anims/staggered-fade.tsx +133 -0
  241. package/templates/shared/src/components/ui/anims/text-scroll.tsx +111 -0
  242. package/templates/shared/src/components/ui/anims/typing-effect.tsx +112 -0
  243. package/templates/shared/src/components/ui/button-dusted-fluid/index.tsx +1521 -0
  244. package/templates/shared/src/components/ui/separator.tsx +85 -0
  245. package/templates/shared/src/hooks/useBodyScrollLock.ts +97 -0
  246. package/templates/shared/src/hooks/useClickOutside.ts +28 -0
  247. package/templates/shared/src/utilities/renderCustomCSS.ts +5 -0
  248. package/templates/shared/src/utilities/smoothScroll.ts +65 -0
@@ -0,0 +1,211 @@
1
+ 'use client'
2
+
3
+ import React, { useRef, useEffect, useState } from 'react'
4
+ import { gsap } from 'gsap'
5
+ import { ScrollTrigger } from 'gsap/ScrollTrigger'
6
+ import { SplitText as GSAPSplitText } from 'gsap/SplitText'
7
+ import { useGSAP } from '@gsap/react'
8
+
9
+ gsap.registerPlugin(ScrollTrigger, GSAPSplitText, useGSAP)
10
+
11
+ export interface SplitTextProps {
12
+ text: string
13
+ className?: string
14
+ delay?: number
15
+ duration?: number
16
+ ease?: string | ((t: number) => number)
17
+ splitType?: 'chars' | 'words' | 'lines' | 'words, chars'
18
+ from?: gsap.TweenVars
19
+ to?: gsap.TweenVars
20
+ threshold?: number
21
+ rootMargin?: string
22
+ tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span'
23
+ textAlign?: React.CSSProperties['textAlign']
24
+ onLetterAnimationComplete?: () => void
25
+ }
26
+
27
+ export const SplitText: React.FC<SplitTextProps> = ({
28
+ text,
29
+ className = '',
30
+ delay = 100,
31
+ duration = 0.6,
32
+ ease = 'power3.out',
33
+ splitType = 'chars',
34
+ from = { opacity: 0, y: 40 },
35
+ to = { opacity: 1, y: 0 },
36
+ threshold = 0.1,
37
+ rootMargin = '-100px',
38
+ textAlign = 'center',
39
+ tag = 'p',
40
+ onLetterAnimationComplete
41
+ }) => {
42
+ const ref = useRef<HTMLParagraphElement>(null)
43
+ const animationCompletedRef = useRef(false)
44
+ const [fontsLoaded, setFontsLoaded] = useState<boolean>(false)
45
+
46
+ useEffect(() => {
47
+ if (document.fonts.status === 'loaded') {
48
+ setFontsLoaded(true)
49
+ } else {
50
+ document.fonts.ready.then(() => {
51
+ setFontsLoaded(true)
52
+ })
53
+ }
54
+ }, [])
55
+
56
+ useGSAP(
57
+ () => {
58
+ if (!ref.current || !text || !fontsLoaded) return
59
+
60
+ const el = ref.current as HTMLElement & {
61
+ _rbsplitInstance?: GSAPSplitText
62
+ }
63
+
64
+ if (el._rbsplitInstance) {
65
+ try {
66
+ el._rbsplitInstance.revert()
67
+ } catch (_) {}
68
+ el._rbsplitInstance = undefined
69
+ }
70
+
71
+ const startPct = (1 - threshold) * 100
72
+ const marginMatch = /^(-?\d+(?:\.\d+)?)(px|em|rem|%)?$/.exec(rootMargin)
73
+ const marginValue = marginMatch ? parseFloat(marginMatch[1] || '0') : 0
74
+ const marginUnit = marginMatch ? marginMatch[2] || 'px' : 'px'
75
+ const sign =
76
+ marginValue === 0
77
+ ? ''
78
+ : marginValue < 0
79
+ ? `-=${Math.abs(marginValue)}${marginUnit}`
80
+ : `+=${marginValue}${marginUnit}`
81
+ const start = `top ${startPct}%${sign}`
82
+ let targets: Element[] = []
83
+ const assignTargets = (self: GSAPSplitText) => {
84
+ if (splitType.includes('chars') && self.chars.length) targets = self.chars
85
+ if (!targets.length && splitType.includes('words') && self.words.length)
86
+ targets = self.words
87
+ if (!targets.length && splitType.includes('lines') && self.lines.length)
88
+ targets = self.lines
89
+ if (!targets.length) targets = self.chars || self.words || self.lines
90
+ }
91
+ const splitInstance = new GSAPSplitText(el, {
92
+ type: splitType,
93
+ smartWrap: true,
94
+ autoSplit: splitType === 'lines',
95
+ linesClass: 'split-line',
96
+ wordsClass: 'split-word',
97
+ charsClass: 'split-char',
98
+ reduceWhiteSpace: false,
99
+ onSplit: (self: GSAPSplitText) => {
100
+ assignTargets(self)
101
+ return gsap.fromTo(
102
+ targets,
103
+ { ...from },
104
+ {
105
+ ...to,
106
+ duration,
107
+ ease,
108
+ stagger: delay / 1000,
109
+ scrollTrigger: {
110
+ trigger: el,
111
+ start,
112
+ once: true,
113
+ fastScrollEnd: true,
114
+ anticipatePin: 0.4
115
+ },
116
+ onComplete: () => {
117
+ animationCompletedRef.current = true
118
+ onLetterAnimationComplete?.()
119
+ },
120
+ willChange: 'transform, opacity',
121
+ force3D: true
122
+ }
123
+ )
124
+ }
125
+ })
126
+ el._rbsplitInstance = splitInstance
127
+ return () => {
128
+ ScrollTrigger.getAll().forEach((st) => {
129
+ if (st.trigger === el) st.kill()
130
+ })
131
+ try {
132
+ splitInstance.revert()
133
+ } catch (_) {}
134
+ el._rbsplitInstance = undefined
135
+ }
136
+ },
137
+ {
138
+ dependencies: [
139
+ text,
140
+ delay,
141
+ duration,
142
+ ease,
143
+ splitType,
144
+ JSON.stringify(from),
145
+ JSON.stringify(to),
146
+ threshold,
147
+ rootMargin,
148
+ fontsLoaded,
149
+ onLetterAnimationComplete
150
+ ],
151
+ scope: ref
152
+ }
153
+ )
154
+
155
+ const renderTag = () => {
156
+ const style: React.CSSProperties = {
157
+ textAlign,
158
+ overflow: 'hidden',
159
+ display: 'inline-block',
160
+ whiteSpace: 'normal',
161
+ wordWrap: 'break-word',
162
+ willChange: 'transform, opacity'
163
+ }
164
+ const classes = `split-parent ${className}`
165
+ switch (tag) {
166
+ case 'h1':
167
+ return (
168
+ <h1 ref={ref} style={style} className={classes}>
169
+ {text}
170
+ </h1>
171
+ )
172
+ case 'h2':
173
+ return (
174
+ <h2 ref={ref} style={style} className={classes}>
175
+ {text}
176
+ </h2>
177
+ )
178
+ case 'h3':
179
+ return (
180
+ <h3 ref={ref} style={style} className={classes}>
181
+ {text}
182
+ </h3>
183
+ )
184
+ case 'h4':
185
+ return (
186
+ <h4 ref={ref} style={style} className={classes}>
187
+ {text}
188
+ </h4>
189
+ )
190
+ case 'h5':
191
+ return (
192
+ <h5 ref={ref} style={style} className={classes}>
193
+ {text}
194
+ </h5>
195
+ )
196
+ case 'h6':
197
+ return (
198
+ <h6 ref={ref} style={style} className={classes}>
199
+ {text}
200
+ </h6>
201
+ )
202
+ default:
203
+ return (
204
+ <p ref={ref} style={style} className={classes}>
205
+ {text}
206
+ </p>
207
+ )
208
+ }
209
+ }
210
+ return renderTag()
211
+ }
@@ -0,0 +1,133 @@
1
+ // 'use client'
2
+ // import { cn } from '@/utilities/ui'
3
+ // import { motion, useInView } from 'framer-motion'
4
+ // import * as React from 'react'
5
+
6
+ // type TextStaggeredFadeProps = {
7
+ // text: string
8
+ // className?: string
9
+ // aniTextClass?: string
10
+ // }
11
+
12
+ // export const StaggeredFade: React.FC<TextStaggeredFadeProps> = ({
13
+ // text,
14
+ // className = '',
15
+ // aniTextClass = ''
16
+ // }) => {
17
+ // const variants = {
18
+ // hidden: { opacity: 0 },
19
+ // show: (i: number) => ({
20
+ // y: 0,
21
+ // opacity: 1,
22
+ // transition: { delay: i * 0.07 }
23
+ // })
24
+ // }
25
+
26
+ // const letters = text.split('')
27
+ // const ref = React.useRef(null)
28
+ // const isInView = useInView(ref, { once: false })
29
+
30
+ // return (
31
+ // <span className="relative inline-block">
32
+ // {/* Underlay: full text visible at 50% opacity so it's readable before animation */}
33
+ // <span
34
+ // aria-hidden
35
+ // className={cn(
36
+ // 'absolute inset-0 opacity-40 select-none pointer-events-none',
37
+ // className,
38
+ // aniTextClass
39
+ // )}
40
+ // >
41
+ // {text}
42
+ // </span>
43
+ // {/* Animated letters on top */}
44
+ // <motion.span
45
+ // ref={ref}
46
+ // initial="hidden"
47
+ // animate={isInView ? 'show' : ''}
48
+ // variants={variants}
49
+ // viewport={{ once: false }}
50
+ // className={cn('indie-stagger-fade', className, aniTextClass)}
51
+ // >
52
+ // {letters.map((word, i) => (
53
+ // <motion.span key={`${word}-${i}`} variants={variants} custom={i}>
54
+ // {word}
55
+ // </motion.span>
56
+ // ))}
57
+ // </motion.span>
58
+ // </span>
59
+ // )
60
+ // }
61
+
62
+ // Optimised version
63
+ 'use client'
64
+
65
+ import { cn } from '@/utilities/ui'
66
+ import { motion, useInView } from 'framer-motion'
67
+ import * as React from 'react'
68
+
69
+ type TextStaggeredFadeProps = {
70
+ text: string
71
+ className?: string
72
+ aniTextClass?: string
73
+ }
74
+
75
+ export const StaggeredFade: React.FC<TextStaggeredFadeProps> = ({
76
+ text,
77
+ className = '',
78
+ aniTextClass = ''
79
+ }) => {
80
+ const ref = React.useRef<HTMLSpanElement | null>(null)
81
+ const isInView = useInView(ref, {
82
+ once: true,
83
+ margin: '0px 0px -15% 0px'
84
+ })
85
+
86
+ const letters = React.useMemo(() => text.split(''), [text])
87
+
88
+ return (
89
+ <span className="relative inline-block">
90
+ <span
91
+ aria-hidden="true"
92
+ className={cn(
93
+ 'absolute inset-0 opacity-40 select-none pointer-events-none',
94
+ className,
95
+ aniTextClass
96
+ )}
97
+ >
98
+ {text}
99
+ </span>
100
+
101
+ <motion.span
102
+ ref={ref}
103
+ initial={false}
104
+ animate={isInView ? 'show' : 'hidden'}
105
+ className={cn('indie-stagger-fade', className, aniTextClass)}
106
+ >
107
+ {letters.map((letter, i) => (
108
+ <motion.span
109
+ key={`${letter}-${i}`}
110
+ custom={i}
111
+ variants={{
112
+ hidden: {
113
+ opacity: 0,
114
+ y: 8
115
+ },
116
+ show: (index: number) => ({
117
+ opacity: 1,
118
+ y: 0,
119
+ transition: {
120
+ delay: index * 0.025,
121
+ duration: 0.35,
122
+ ease: [0.22, 1, 0.36, 1]
123
+ }
124
+ })
125
+ }}
126
+ >
127
+ {letter}
128
+ </motion.span>
129
+ ))}
130
+ </motion.span>
131
+ </span>
132
+ )
133
+ }
@@ -0,0 +1,111 @@
1
+ 'use client'
2
+
3
+ import React, { useEffect, useRef, useState } from 'react'
4
+ import {
5
+ motion,
6
+ useAnimationFrame,
7
+ useMotionValue,
8
+ useScroll,
9
+ useSpring,
10
+ useTransform,
11
+ useVelocity,
12
+ } from 'framer-motion'
13
+
14
+ import { cn } from '@/utilities/ui'
15
+
16
+ interface TextScrollProps {
17
+ text: string
18
+ default_velocity?: number
19
+ className?: string
20
+ }
21
+
22
+ interface ParallaxProps {
23
+ children: string
24
+ baseVelocity: number
25
+ className?: string
26
+ }
27
+
28
+ export const wrap = (min: number, max: number, v: number) => {
29
+ const rangeSize = max - min
30
+ return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min
31
+ }
32
+
33
+ export const TextScroll: React.FC<TextScrollProps> = ({
34
+ text,
35
+ default_velocity = 5,
36
+ className,
37
+ }) => {
38
+ const ParallaxText: React.FC<ParallaxProps> = ({ children, baseVelocity = 100, className }) => {
39
+ const baseX = useMotionValue(0)
40
+ const { scrollY } = useScroll()
41
+ const scrollVelocity = useVelocity(scrollY)
42
+ const smoothVelocity = useSpring(scrollVelocity, {
43
+ damping: 50,
44
+ stiffness: 400,
45
+ })
46
+
47
+ const velocityFactor = useTransform(smoothVelocity, [0, 1000], [0, 5], {
48
+ clamp: false,
49
+ })
50
+
51
+ const [repetitions, setRepetitions] = useState(1)
52
+ const containerRef = useRef<HTMLDivElement>(null)
53
+ const textRef = useRef<HTMLSpanElement>(null)
54
+
55
+ useEffect(() => {
56
+ const calculateRepetitions = () => {
57
+ if (containerRef.current && textRef.current) {
58
+ const containerWidth = containerRef.current.offsetWidth
59
+ const textWidth = textRef.current.offsetWidth
60
+ const newRepetitions = Math.ceil(containerWidth / textWidth) + 2
61
+ setRepetitions(newRepetitions)
62
+ }
63
+ }
64
+
65
+ calculateRepetitions()
66
+
67
+ window.addEventListener('resize', calculateRepetitions)
68
+ return () => window.removeEventListener('resize', calculateRepetitions)
69
+ }, [children])
70
+
71
+ const x = useTransform(baseX, (v) => `${wrap(-100 / repetitions, 0, v)}%`)
72
+
73
+ const directionFactor = useRef<number>(1)
74
+ useAnimationFrame((t, delta) => {
75
+ let moveBy = directionFactor.current * baseVelocity * (delta / 1000)
76
+
77
+ if (velocityFactor.get() < 0) {
78
+ directionFactor.current = -1
79
+ } else if (velocityFactor.get() > 0) {
80
+ directionFactor.current = 1
81
+ }
82
+
83
+ moveBy += directionFactor.current * moveBy * velocityFactor.get()
84
+
85
+ baseX.set(baseX.get() + moveBy)
86
+ })
87
+
88
+ return (
89
+ <div className="w-full overflow-hidden whitespace-nowrap" ref={containerRef}>
90
+ <motion.div className={cn('inline-block', className)} style={{ x }}>
91
+ {Array.from({ length: repetitions }).map((_, i) => (
92
+ <span key={i} ref={i === 0 ? textRef : null}>
93
+ {children}{' '}
94
+ </span>
95
+ ))}
96
+ </motion.div>
97
+ </div>
98
+ )
99
+ }
100
+
101
+ return (
102
+ <section className="relative w-full">
103
+ <ParallaxText baseVelocity={default_velocity} className={className}>
104
+ {text}
105
+ </ParallaxText>
106
+ <ParallaxText baseVelocity={-default_velocity} className={className}>
107
+ {text}
108
+ </ParallaxText>
109
+ </section>
110
+ )
111
+ }
@@ -0,0 +1,112 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { motion, useInView } from 'framer-motion'
5
+ import { cn } from '@/utilities/ui'
6
+
7
+ export function TypingEffect({
8
+ text = 'Typing Effect',
9
+ className = '',
10
+ aniTextClass = '',
11
+ charDelayMs = 200
12
+ }: {
13
+ text: string
14
+ className?: string
15
+ aniTextClass?: string
16
+ charDelayMs?: number
17
+ }) {
18
+ const ref = React.useRef(null)
19
+ const isInView = useInView(ref, { once: true })
20
+
21
+ const [visibleChars, setVisibleChars] = React.useState(0)
22
+
23
+ const chars = React.useMemo(() => Array.from(String(text)), [text])
24
+
25
+ const prefersReducedMotion = React.useMemo(() => {
26
+ if (typeof window === 'undefined') return false
27
+ return window.matchMedia('(prefers-reduced-motion: reduce)').matches
28
+ }, [])
29
+
30
+ React.useEffect(() => {
31
+ if (!isInView) return
32
+
33
+ if (prefersReducedMotion) {
34
+ setVisibleChars(chars.length)
35
+ return
36
+ }
37
+
38
+ setVisibleChars(0)
39
+
40
+ const delay = typeof charDelayMs === 'number' && charDelayMs > 0 ? charDelayMs : 200
41
+ const id = window.setInterval(() => {
42
+ setVisibleChars((prev) => {
43
+ if (prev >= chars.length) {
44
+ window.clearInterval(id)
45
+ return prev
46
+ }
47
+ return prev + 1
48
+ })
49
+ }, delay)
50
+
51
+ return () => window.clearInterval(id)
52
+ }, [isInView, prefersReducedMotion, chars.length, charDelayMs])
53
+
54
+ return (
55
+ <>
56
+ <span
57
+ ref={ref}
58
+ className={cn('tracking-tighter', className, aniTextClass)}
59
+ // className="text-xl text-center sm:text-4xl font-bold tracking-tighter md:text-6xl md:leading-[4rem]"
60
+ >
61
+ {chars.slice(0, visibleChars).map((ch, index) => {
62
+ // Keep word-wrap behavior by not forcing inline-block per character.
63
+ // Also render spaces as-is so wrapping occurs at spaces.
64
+ const shouldAnimate = !prefersReducedMotion
65
+
66
+ return (
67
+ <motion.span
68
+ key={`typed-${index}`}
69
+ className={ch === ' ' ? undefined : 'continuous-typing-effect'}
70
+ initial={shouldAnimate ? { opacity: 0 } : undefined}
71
+ animate={shouldAnimate ? { opacity: 1 } : undefined}
72
+ transition={shouldAnimate ? { duration: 0.12 } : undefined}
73
+ >
74
+ {ch}
75
+ </motion.span>
76
+ )
77
+ })}
78
+
79
+ <span aria-hidden className="typing-effect-cursor">
80
+ ▍
81
+ </span>
82
+ </span>
83
+
84
+ <style jsx global>{`
85
+ .typing-effect-cursor {
86
+ display: inline-block;
87
+ margin-left: 0.08em;
88
+ transform: translateY(0.08em);
89
+ animation: typing-effect-blink 0.9s steps(2, start) infinite;
90
+ }
91
+
92
+ @keyframes typing-effect-blink {
93
+ 0%,
94
+ 49% {
95
+ opacity: 1;
96
+ }
97
+ 50%,
98
+ 100% {
99
+ opacity: 0;
100
+ }
101
+ }
102
+
103
+ @media (prefers-reduced-motion: reduce) {
104
+ .typing-effect-cursor {
105
+ animation: none;
106
+ opacity: 1;
107
+ }
108
+ }
109
+ `}</style>
110
+ </>
111
+ )
112
+ }