blocks-dusted 0.1.11 → 0.1.13

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 (161) hide show
  1. package/package.json +5 -2
  2. package/src/cli.js +39 -3
  3. package/src/commands/shop.js +59 -0
  4. package/src/commands/warehouse.js +73 -0
  5. package/src/installers/patchRenderBlocks.js +1 -1
  6. package/src/registry/validateTemplateManifest.js +2 -1
  7. package/templates/blocks/BannerDD790432/Component.tsx +63 -0
  8. package/templates/blocks/BannerDD790432/config.ts +54 -0
  9. package/templates/blocks/BannerDD790432/manifest.json +80 -0
  10. package/templates/blocks/Button47/Component.tsx +124 -0
  11. package/templates/blocks/Button47/config.ts +75 -0
  12. package/templates/blocks/Button47/link.ts +22 -0
  13. package/templates/blocks/Button47/manifest.json +105 -0
  14. package/templates/blocks/Button47/styles.module.scss +75 -0
  15. package/templates/blocks/DD-Accordion/Component.tsx +55 -36
  16. package/templates/blocks/DD-Accordion/config.ts +71 -59
  17. package/templates/blocks/DD-AnimText/Component.tsx +50 -32
  18. package/templates/blocks/DD-AnimText/config.ts +296 -295
  19. package/templates/blocks/DD-AsideNav/Component.tsx +323 -319
  20. package/templates/blocks/DD-Banner/Component.tsx +54 -51
  21. package/templates/blocks/DD-BookCall/Component.tsx +10 -9
  22. package/templates/blocks/DD-ButtonPop/Component.tsx +118 -117
  23. package/templates/blocks/DD-Card/Component.tsx +4 -4
  24. package/templates/blocks/DD-CardTemplate01/Component.tsx +5 -5
  25. package/templates/blocks/DD-CardsWithVariantV3/Component.tsx +472 -0
  26. package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/index.tsx +203 -0
  27. package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/styles.ts +87 -0
  28. package/templates/blocks/DD-CardsWithVariantV3/ElectricBorder/useInjectStyle.ts +39 -0
  29. package/templates/blocks/DD-CardsWithVariantV3/config.ts +326 -0
  30. package/templates/blocks/DD-CardsWithVariantV3/manifest.json +110 -0
  31. package/templates/blocks/DD-Carousel-A/Component.tsx +251 -249
  32. package/templates/blocks/DD-Carousel-B/Component.tsx +405 -403
  33. package/templates/blocks/DD-Chip/Component.tsx +14 -14
  34. package/templates/blocks/DD-ComparisonTable/Component.tsx +255 -256
  35. package/templates/blocks/DD-Contact/Component.tsx +433 -434
  36. package/templates/blocks/DD-Counter/Component.tsx +18 -13
  37. package/templates/blocks/DD-DeliCard/Component.tsx +303 -0
  38. package/templates/blocks/DD-DeliCard/config.ts +186 -0
  39. package/templates/blocks/DD-DeliCard/manifest.json +94 -0
  40. package/templates/blocks/DD-FeatCat/Component.tsx +302 -302
  41. package/templates/blocks/DD-FeatProd/CircularGallery.tsx +1179 -0
  42. package/templates/blocks/DD-FeatProd/Component.tsx +484 -0
  43. package/templates/blocks/DD-FeatProd/config.ts +173 -0
  44. package/templates/blocks/DD-FeatProd/manifest.json +93 -0
  45. package/templates/blocks/DD-FeatServ/Component.tsx +607 -0
  46. package/templates/blocks/DD-FeatServ/config.ts +213 -0
  47. package/templates/blocks/DD-FeatServ/manifest.json +113 -0
  48. package/templates/blocks/DD-FeatStrip/Component.tsx +584 -585
  49. package/templates/blocks/DD-FluidBtn/ButtonsEyeCatching.tsx +627 -628
  50. package/templates/blocks/DD-FluidBtn/Component.tsx +46 -43
  51. package/templates/blocks/DD-GooeyInfo/Component.tsx +150 -149
  52. package/templates/blocks/DD-GooeyInfo/config.ts +136 -135
  53. package/templates/blocks/DD-Hero/Component.tsx +16 -40
  54. package/templates/blocks/DD-HeroPlas/Component.tsx +50 -0
  55. package/templates/blocks/DD-HeroPlas/ThreeScene.tsx +109 -0
  56. package/templates/blocks/DD-HeroPlas/config.ts +33 -0
  57. package/templates/blocks/DD-HeroPlas/manifest.json +88 -0
  58. package/templates/blocks/DD-HorizontalScroll/Component.tsx +4 -5
  59. package/templates/blocks/DD-Icon/Component.tsx +46 -81
  60. package/templates/blocks/DD-IconButton/Component.tsx +13 -20
  61. package/templates/blocks/DD-IdTag/Component.tsx +22 -21
  62. package/templates/blocks/DD-IframeMedia/Component.tsx +14 -10
  63. package/templates/blocks/DD-LineAnim/Component.tsx +42 -36
  64. package/templates/blocks/DD-LogoMarq/Component.tsx +38 -48
  65. package/templates/blocks/DD-Lottie/Component.tsx +11 -3
  66. package/templates/blocks/DD-MasonaryMedia/Component.tsx +544 -547
  67. package/templates/blocks/DD-MasonaryMedia/config.ts +389 -389
  68. package/templates/blocks/DD-Masonry/Component.tsx +654 -644
  69. package/templates/blocks/DD-Masonry/config.ts +475 -475
  70. package/templates/blocks/DD-MaterialSwatches/Component.tsx +85 -0
  71. package/templates/blocks/DD-MaterialSwatches/config.ts +232 -0
  72. package/templates/blocks/DD-MaterialSwatches/manifest.json +84 -0
  73. package/templates/blocks/DD-MaterialSwatches/material.ts +107 -0
  74. package/templates/blocks/DD-NineCanvas/Component.tsx +129 -0
  75. package/templates/blocks/DD-NineCanvas/RenderBlocks.tsx +244 -0
  76. package/templates/blocks/DD-NineCanvas/allowedCanvasBlocks.ts +6 -0
  77. package/templates/blocks/DD-NineCanvas/blockComponents.tsx +8 -0
  78. package/templates/blocks/DD-NineCanvas/canvas/CanvasGrid.tsx +316 -0
  79. package/templates/blocks/DD-NineCanvas/canvas/RadialNav.tsx +432 -0
  80. package/templates/blocks/DD-NineCanvas/canvas/canvas-panels.css +889 -0
  81. package/templates/blocks/DD-NineCanvas/canvas/icons/custom-icons.tsx +364 -0
  82. package/templates/blocks/DD-NineCanvas/config.ts +61 -0
  83. package/templates/blocks/DD-NineCanvas/manifest.json +165 -0
  84. package/templates/blocks/DD-NineCanvas/styles.scss +152 -0
  85. package/templates/blocks/DD-NineCanvas/tooltip/get-strict-context.tsx +26 -0
  86. package/templates/blocks/DD-NineCanvas/tooltip/primitives.tsx +178 -0
  87. package/templates/blocks/DD-NineCanvas/tooltip/tooltip.tsx +71 -0
  88. package/templates/blocks/DD-NineCanvas/tooltip/use-controlled-state.tsx +33 -0
  89. package/templates/blocks/DD-NineCanvas/utilities/FadeOnScroll.tsx +68 -0
  90. package/templates/blocks/DD-NineCanvas/utilities/ParallaxWrapper.tsx +157 -0
  91. package/templates/blocks/DD-NineCanvas/utilities/renderCustomCSS.ts +5 -0
  92. package/templates/blocks/DD-NineCanvas/utilities/webglCleanup.ts +27 -0
  93. package/templates/blocks/DD-PayloadAIAssistant/Component.tsx +78 -0
  94. package/templates/blocks/DD-PayloadAIAssistant/DustedBot.tsx +590 -0
  95. package/templates/blocks/DD-PayloadAIAssistant/config.ts +37 -0
  96. package/templates/blocks/DD-PayloadAIAssistant/demo.css +125 -0
  97. package/templates/blocks/DD-PayloadAIAssistant/manifest.json +93 -0
  98. package/templates/blocks/DD-PayloadAIAssistant/source-defaults.ts +17 -0
  99. package/templates/blocks/DD-PayloadAIAssistant/styles.ts +306 -0
  100. package/templates/blocks/DD-Pricing/Component.tsx +368 -372
  101. package/templates/blocks/DD-Pricing/config.ts +215 -215
  102. package/templates/blocks/DD-Process/Component.tsx +147 -149
  103. package/templates/blocks/DD-Progress/Component.tsx +156 -141
  104. package/templates/blocks/DD-ProjHeader/Component.tsx +93 -91
  105. package/templates/blocks/DD-ProjSlider/Component.tsx +1 -1
  106. package/templates/blocks/DD-ProjSlider/config.ts +2 -2
  107. package/templates/blocks/DD-Section/Component.tsx +265 -266
  108. package/templates/blocks/DD-Separator/Component.tsx +66 -66
  109. package/templates/blocks/DD-Services/Component.tsx +176 -176
  110. package/templates/blocks/DD-ShowcaseGrid/Component.tsx +306 -307
  111. package/templates/blocks/DD-Slider-A/Component.tsx +237 -237
  112. package/templates/blocks/DD-StackCards/Component.tsx +474 -473
  113. package/templates/blocks/DD-Team/Component.tsx +247 -247
  114. package/templates/blocks/DD-TeamCards/Component.tsx +251 -251
  115. package/templates/blocks/DD-TechStack/Component.tsx +161 -168
  116. package/templates/blocks/DD-TestMarq/Component.tsx +158 -132
  117. package/templates/blocks/DD-Testim/Component.tsx +247 -247
  118. package/templates/blocks/DD-Testim2/Component.tsx +265 -256
  119. package/templates/blocks/DD-Testimonials/Component.tsx +139 -147
  120. package/templates/blocks/DD-TextMarq/Component.tsx +157 -157
  121. package/templates/blocks/DD-Thanks/Component.tsx +501 -500
  122. package/templates/blocks/DD-Work/Component.tsx +315 -315
  123. package/templates/blocks/DD-Work-B/Component.tsx +294 -294
  124. package/templates/blocks/DDHG-CTASection2/Component.tsx +183 -184
  125. package/templates/blocks/DDHG-HighlightArc/Component.tsx +246 -243
  126. package/templates/blocks/DDHG-LogoMarquee/Component.tsx +180 -93
  127. package/templates/blocks/DDHG-LogoMarquee/config.ts +154 -66
  128. package/templates/blocks/DDHG-NavCodeGrid/Component.tsx +225 -213
  129. package/templates/blocks/DDHG-ProcessSec/Component.tsx +38 -39
  130. package/templates/blocks/DDHG-ServiceDetails/Component.tsx +11 -11
  131. package/templates/blocks/DDHG-ServiceDetails/ServiceDetailCard.tsx +30 -47
  132. package/templates/blocks/DDHG-ServiceHero/Component.tsx +10 -10
  133. package/templates/blocks/DDHG-ServiceOverview/Component.tsx +23 -23
  134. package/templates/blocks/DDHG-StatsFAQ/Component.tsx +40 -40
  135. package/templates/blocks/DDHG-TeamCards/Component.tsx +140 -131
  136. package/templates/blocks/Form/Checkbox/index.tsx +45 -0
  137. package/templates/blocks/Form/Component.tsx +163 -0
  138. package/templates/blocks/Form/Country/index.tsx +65 -0
  139. package/templates/blocks/Form/Country/options.ts +982 -0
  140. package/templates/blocks/Form/Email/index.tsx +38 -0
  141. package/templates/blocks/Form/Error/index.tsx +15 -0
  142. package/templates/blocks/Form/Message/index.tsx +13 -0
  143. package/templates/blocks/Form/Number/index.tsx +36 -0
  144. package/templates/blocks/Form/Select/index.tsx +63 -0
  145. package/templates/blocks/Form/State/index.tsx +64 -0
  146. package/templates/blocks/Form/State/options.ts +52 -0
  147. package/templates/blocks/Form/Text/index.tsx +32 -0
  148. package/templates/blocks/Form/Textarea/index.tsx +40 -0
  149. package/templates/blocks/Form/Width/index.tsx +13 -0
  150. package/templates/blocks/Form/config.ts +51 -0
  151. package/templates/blocks/Form/fields.tsx +21 -0
  152. package/templates/blocks/Form/manifest.json +168 -0
  153. package/templates/blocks/MediaBlock/Component.tsx +67 -0
  154. package/templates/blocks/MediaBlock/config.ts +14 -0
  155. package/templates/blocks/MediaBlock/manifest.json +92 -0
  156. package/templates/blocks/TransitionsDustedShowcase/Component.tsx +9 -0
  157. package/templates/blocks/TransitionsDustedShowcase/config.ts +13 -0
  158. package/templates/blocks/TransitionsDustedShowcase/manifest.json +80 -0
  159. package/templates/blocks/rawHtml/Component.tsx +25 -0
  160. package/templates/blocks/rawHtml/config.ts +56 -0
  161. package/templates/blocks/rawHtml/manifest.json +80 -0
@@ -0,0 +1,152 @@
1
+ .topLogoBgWrapper {
2
+ position: fixed;
3
+ left: 0;
4
+ right: 0;
5
+ top: 0;
6
+ margin: auto;
7
+ width: fit-content;
8
+ max-width: fit-content;
9
+ height: fit-content;
10
+ max-height: 2.5rem;
11
+ z-index: 99999;
12
+ pointer-events: auto;
13
+
14
+ filter: drop-shadow(0px 1px 2px var(--border)) drop-shadow(rgba(0, 0, 0, 0.8) 2px 4px 6px);
15
+
16
+ animation: topLogoEnter 0.45s cubic-bezier(0.22, 1, 0.36, 1) both;
17
+ }
18
+
19
+ @keyframes topLogoEnter {
20
+ from {
21
+ opacity: 0;
22
+ transform: translateY(-1.25rem) scale(0.94);
23
+ }
24
+
25
+ to {
26
+ opacity: 1;
27
+ transform: translateY(0) scale(1);
28
+ }
29
+ }
30
+ @media (max-width: 768px) {
31
+ .topLogoBgWrapper {
32
+ scale: 0.7;
33
+ transform-origin: top;
34
+ }
35
+ }
36
+
37
+ .svglogolink {
38
+ position: relative;
39
+ top: -2.6rem;
40
+ max-width: fit-content;
41
+ margin: auto;
42
+ padding-top: 0.6rem;
43
+ display: flex;
44
+ align-items: flex-start;
45
+ justify-content: center;
46
+ cursor: pointer;
47
+ z-index: 99999;
48
+ filter: brightness(0.8) drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.5));
49
+ transition: all 0.3s;
50
+ }
51
+ .svglogolink::before {
52
+ content: '';
53
+ position: absolute;
54
+ top: 0;
55
+ width: 3.5rem;
56
+ height: 5px;
57
+ border-radius: 999px;
58
+ background: #e5e5e5;
59
+ box-shadow: 0 0 12px rgba(255, 255, 255, 0.65);
60
+ opacity: 0;
61
+ filter: blur(0.25px);
62
+ transform: translateY(-2px);
63
+ transition: all 0.3s;
64
+ }
65
+ .svglogolink::after {
66
+ content: '';
67
+ position: absolute;
68
+ top: 5px;
69
+ width: 5.25rem;
70
+ height: 3rem;
71
+ background: linear-gradient(
72
+ to bottom,
73
+ rgba(255, 255, 255, 0.28),
74
+ rgba(255, 255, 255, 0.08) 45%,
75
+ rgba(255, 255, 255, 0)
76
+ );
77
+ clip-path: polygon(28% 0, 72% 0, 100% 100%, 0 100%);
78
+ filter: blur(1.5px);
79
+ opacity: 0;
80
+ pointer-events: none;
81
+ transition: all 0.3s;
82
+ mix-blend-mode: lighten;
83
+ }
84
+ .svglogolink:hover {
85
+ filter: brightness(1.5) drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.8));
86
+ }
87
+ .svglogolink:hover::before,
88
+ .svglogolink:hover::after {
89
+ opacity: 1;
90
+ }
91
+
92
+ .bottomLogoBgWrapper {
93
+ position: fixed;
94
+ left: 0;
95
+ right: 0;
96
+ bottom: 0;
97
+ margin: auto;
98
+ width: fit-content;
99
+ height: fit-content;
100
+ z-index: 100;
101
+ pointer-events: auto;
102
+
103
+ filter: drop-shadow(0px 1px 2px var(--border)) drop-shadow(rgba(0, 0, 0, 0.8) 2px 4px 6px);
104
+
105
+ animation: bottomLogoEnter 0.45s cubic-bezier(0.22, 1, 0.36, 1) both;
106
+ }
107
+
108
+ @keyframes bottomLogoEnter {
109
+ from {
110
+ opacity: 0;
111
+ transform: translateY(1.25rem) scale(0.94);
112
+ }
113
+
114
+ to {
115
+ opacity: 1;
116
+ transform: translateY(0) scale(1);
117
+ }
118
+ }
119
+ @media (max-width: 768px) {
120
+ .bottomLogoBgWrapper {
121
+ scale: 0.7;
122
+ transform-origin: bottom;
123
+ }
124
+ }
125
+
126
+ .ninecanvas {
127
+ position: relative;
128
+ min-height: 100vh;
129
+ max-height: 100vh;
130
+ overflow: auto hidden;
131
+ z-index: 20;
132
+ }
133
+
134
+ body.has-ninecanvas-footer-reveal article.page-article {
135
+ overflow: auto hidden;
136
+ }
137
+
138
+ .hzNineCanvasBlock {
139
+ isolation: isolate;
140
+ margin: 0;
141
+ position: sticky;
142
+ top: 0;
143
+ height: 100dvh;
144
+ // background: var(--card-foreground);
145
+ background: radial-gradient(circle at center, #353535, transparent);
146
+ overflow: hidden;
147
+ z-index: 20;
148
+ }
149
+
150
+ .hzNineCanvasBlock .renderblock-container {
151
+ min-height: initial;
152
+ }
@@ -0,0 +1,26 @@
1
+ import * as React from 'react'
2
+
3
+ function getStrictContext<T>(
4
+ name?: string,
5
+ ): readonly [
6
+ ({ value, children }: { value: T; children?: React.ReactNode }) => React.JSX.Element,
7
+ () => T,
8
+ ] {
9
+ const Context = React.createContext<T | undefined>(undefined)
10
+
11
+ const Provider = ({ value, children }: { value: T; children?: React.ReactNode }) => (
12
+ <Context.Provider value={value}>{children}</Context.Provider>
13
+ )
14
+
15
+ const useSafeContext = () => {
16
+ const ctx = React.useContext(Context)
17
+ if (ctx === undefined) {
18
+ throw new Error(`useContext must be used within ${name ?? 'a Provider'}`)
19
+ }
20
+ return ctx
21
+ }
22
+
23
+ return [Provider, useSafeContext] as const
24
+ }
25
+
26
+ export { getStrictContext }
@@ -0,0 +1,178 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { Tooltip as TooltipPrimitive } from '@base-ui/react/tooltip'
5
+ import {
6
+ AnimatePresence,
7
+ motion,
8
+ useMotionValue,
9
+ useSpring,
10
+ type HTMLMotionProps,
11
+ type MotionValue,
12
+ type SpringOptions,
13
+ } from 'motion/react'
14
+
15
+ import { getStrictContext } from './get-strict-context'
16
+ import { useControlledState } from './use-controlled-state'
17
+
18
+ type TooltipContextType = {
19
+ isOpen: boolean
20
+ setIsOpen: TooltipProps['onOpenChange']
21
+ x: MotionValue<number>
22
+ y: MotionValue<number>
23
+ followCursor?: boolean | 'x' | 'y'
24
+ followCursorSpringOptions?: SpringOptions
25
+ }
26
+
27
+ const [LocalTooltipProvider, useTooltip] = getStrictContext<TooltipContextType>('TooltipContext')
28
+
29
+ type TooltipProviderProps = React.ComponentProps<typeof TooltipPrimitive.Provider>
30
+
31
+ function TooltipProvider(props: TooltipProviderProps) {
32
+ return <TooltipPrimitive.Provider data-slot="tooltip-provider" {...props} />
33
+ }
34
+
35
+ type TooltipProps = React.ComponentProps<typeof TooltipPrimitive.Root> & {
36
+ followCursor?: boolean | 'x' | 'y'
37
+ followCursorSpringOptions?: SpringOptions
38
+ }
39
+
40
+ function Tooltip({
41
+ followCursor = false,
42
+ followCursorSpringOptions = { stiffness: 200, damping: 17 },
43
+ ...props
44
+ }: TooltipProps) {
45
+ const [isOpen, setIsOpen] = useControlledState({
46
+ value: props?.open,
47
+ defaultValue: props?.defaultOpen,
48
+ onChange: props?.onOpenChange,
49
+ })
50
+ const x = useMotionValue(0)
51
+ const y = useMotionValue(0)
52
+
53
+ return (
54
+ <LocalTooltipProvider
55
+ value={{
56
+ isOpen,
57
+ setIsOpen,
58
+ x,
59
+ y,
60
+ followCursor,
61
+ followCursorSpringOptions,
62
+ }}
63
+ >
64
+ <TooltipPrimitive.Root data-slot="tooltip" {...props} onOpenChange={setIsOpen} />
65
+ </LocalTooltipProvider>
66
+ )
67
+ }
68
+
69
+ type TooltipTriggerProps = React.ComponentProps<typeof TooltipPrimitive.Trigger>
70
+
71
+ function TooltipTrigger({ onMouseMove, ...props }: TooltipTriggerProps) {
72
+ const { x, y, followCursor } = useTooltip()
73
+
74
+ const handleMouseMove = (
75
+ event: Parameters<NonNullable<TooltipTriggerProps['onMouseMove']>>[0],
76
+ ) => {
77
+ onMouseMove?.(event)
78
+
79
+ const target = event.currentTarget.getBoundingClientRect()
80
+
81
+ if (followCursor === 'x' || followCursor === true) {
82
+ const eventOffsetX = event.clientX - target.left
83
+ const offsetXFromCenter = (eventOffsetX - target.width / 2) / 2
84
+ x.set(offsetXFromCenter)
85
+ }
86
+
87
+ if (followCursor === 'y' || followCursor === true) {
88
+ const eventOffsetY = event.clientY - target.top
89
+ const offsetYFromCenter = (eventOffsetY - target.height / 2) / 2
90
+ y.set(offsetYFromCenter)
91
+ }
92
+ }
93
+
94
+ return (
95
+ <TooltipPrimitive.Trigger
96
+ data-slot="tooltip-trigger"
97
+ onMouseMove={handleMouseMove}
98
+ {...props}
99
+ />
100
+ )
101
+ }
102
+
103
+ type TooltipPortalProps = Omit<React.ComponentProps<typeof TooltipPrimitive.Portal>, 'keepMounted'>
104
+
105
+ function TooltipPortal(props: TooltipPortalProps) {
106
+ const { isOpen } = useTooltip()
107
+
108
+ return (
109
+ <AnimatePresence>
110
+ {isOpen && <TooltipPrimitive.Portal keepMounted data-slot="tooltip-portal" {...props} />}
111
+ </AnimatePresence>
112
+ )
113
+ }
114
+
115
+ type TooltipPositionerProps = React.ComponentProps<typeof TooltipPrimitive.Positioner>
116
+
117
+ function TooltipPositioner(props: TooltipPositionerProps) {
118
+ return <TooltipPrimitive.Positioner data-slot="tooltip-positioner" {...props} />
119
+ }
120
+
121
+ type TooltipPopupProps = Omit<React.ComponentProps<typeof TooltipPrimitive.Popup>, 'render'> &
122
+ HTMLMotionProps<'div'>
123
+
124
+ function TooltipPopup({
125
+ transition = { type: 'spring', stiffness: 300, damping: 25 },
126
+ style,
127
+ ...props
128
+ }: TooltipPopupProps) {
129
+ const { x, y, followCursor, followCursorSpringOptions } = useTooltip()
130
+ const translateX = useSpring(x, followCursorSpringOptions)
131
+ const translateY = useSpring(y, followCursorSpringOptions)
132
+
133
+ return (
134
+ <TooltipPrimitive.Popup
135
+ render={
136
+ <motion.div
137
+ key="tooltip-popup"
138
+ data-slot="tooltip-popup"
139
+ initial={{ opacity: 0, scale: 0.5 }}
140
+ animate={{ opacity: 1, scale: 1 }}
141
+ exit={{ opacity: 0, scale: 0.5 }}
142
+ transition={transition}
143
+ style={{
144
+ x: followCursor === 'x' || followCursor === true ? translateX : undefined,
145
+ y: followCursor === 'y' || followCursor === true ? translateY : undefined,
146
+ ...style,
147
+ }}
148
+ {...props}
149
+ />
150
+ }
151
+ />
152
+ )
153
+ }
154
+
155
+ type TooltipArrowProps = React.ComponentProps<typeof TooltipPrimitive.Arrow>
156
+
157
+ function TooltipArrow(props: TooltipArrowProps) {
158
+ return <TooltipPrimitive.Arrow data-slot="tooltip-arrow" {...props} />
159
+ }
160
+
161
+ export {
162
+ TooltipProvider,
163
+ Tooltip,
164
+ TooltipTrigger,
165
+ TooltipPortal,
166
+ TooltipPositioner,
167
+ TooltipPopup,
168
+ TooltipArrow,
169
+ useTooltip,
170
+ type TooltipProviderProps,
171
+ type TooltipProps,
172
+ type TooltipTriggerProps,
173
+ type TooltipPortalProps,
174
+ type TooltipPositionerProps,
175
+ type TooltipPopupProps,
176
+ type TooltipArrowProps,
177
+ type TooltipContextType,
178
+ }
@@ -0,0 +1,71 @@
1
+ import * as React from 'react'
2
+
3
+ import {
4
+ TooltipProvider as TooltipProviderPrimitive,
5
+ Tooltip as TooltipPrimitive,
6
+ TooltipTrigger as TooltipTriggerPrimitive,
7
+ TooltipPositioner as TooltipPositionerPrimitive,
8
+ TooltipPopup as TooltipPopupPrimitive,
9
+ TooltipArrow as TooltipArrowPrimitive,
10
+ TooltipPortal as TooltipPortalPrimitive,
11
+ type TooltipProviderProps as TooltipProviderPrimitiveProps,
12
+ type TooltipProps as TooltipPrimitiveProps,
13
+ type TooltipTriggerProps as TooltipTriggerPrimitiveProps,
14
+ type TooltipPositionerProps as TooltipPositionerPrimitiveProps,
15
+ type TooltipPopupProps as TooltipPopupPrimitiveProps,
16
+ } from './primitives'
17
+ import { cn } from '@/utilities/ui'
18
+
19
+ type TooltipProviderProps = TooltipProviderPrimitiveProps
20
+
21
+ function TooltipProvider({ delay = 0, ...props }: TooltipProviderProps) {
22
+ return <TooltipProviderPrimitive delay={delay} {...props} />
23
+ }
24
+
25
+ type TooltipProps = TooltipPrimitiveProps & {
26
+ delay?: TooltipProviderProps['delay']
27
+ }
28
+
29
+ function Tooltip({ delay = 0, ...props }: TooltipProps) {
30
+ return (
31
+ <TooltipProvider delay={delay}>
32
+ <TooltipPrimitive {...props} />
33
+ </TooltipProvider>
34
+ )
35
+ }
36
+
37
+ type TooltipTriggerProps = TooltipTriggerPrimitiveProps
38
+
39
+ function TooltipTrigger({ ...props }: TooltipTriggerProps) {
40
+ return <TooltipTriggerPrimitive {...props} />
41
+ }
42
+
43
+ type TooltipPanelProps = TooltipPositionerPrimitiveProps & TooltipPopupPrimitiveProps
44
+
45
+ function TooltipPanel({ className, sideOffset = 4, children, style, ...props }: TooltipPanelProps) {
46
+ return (
47
+ <TooltipPortalPrimitive>
48
+ <TooltipPositionerPrimitive sideOffset={sideOffset} className="z-100 hzToolTip" {...props}>
49
+ <TooltipPopupPrimitive
50
+ className={cn(
51
+ 'bg-primary/75 text-primary-foreground w-fit origin-(--transform-origin) rounded-md px-3 py-1.5 text-xs text-balance',
52
+ className,
53
+ )}
54
+ style={style}
55
+ >
56
+ {children}
57
+ <TooltipArrowPrimitive className="bg-primary fill-primary z-50 size-2.5 data-[side='bottom']:-top-1 data-[side='right']:-left-1 data-[side='left']:-right-1 data-[side='inline-start']:-right-1 data-[side='inline-end']:-left-1 rotate-45 rounded-[2px]" />
58
+ </TooltipPopupPrimitive>
59
+ </TooltipPositionerPrimitive>
60
+ </TooltipPortalPrimitive>
61
+ )
62
+ }
63
+
64
+ export {
65
+ Tooltip,
66
+ TooltipTrigger,
67
+ TooltipPanel,
68
+ type TooltipProps,
69
+ type TooltipTriggerProps,
70
+ type TooltipPanelProps,
71
+ }
@@ -0,0 +1,33 @@
1
+ import * as React from 'react'
2
+
3
+ interface CommonControlledStateProps<T> {
4
+ value?: T
5
+ defaultValue?: T
6
+ }
7
+
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ export function useControlledState<T, Rest extends any[] = []>(
10
+ props: CommonControlledStateProps<T> & {
11
+ onChange?: (value: T, ...args: Rest) => void
12
+ },
13
+ ): readonly [T, (next: T, ...args: Rest) => void] {
14
+ const { value, defaultValue, onChange } = props
15
+
16
+ const [state, setInternalState] = React.useState<T>(
17
+ value !== undefined ? value : (defaultValue as T),
18
+ )
19
+
20
+ React.useEffect(() => {
21
+ if (value !== undefined) setInternalState(value)
22
+ }, [value])
23
+
24
+ const setState = React.useCallback(
25
+ (next: T, ...args: Rest) => {
26
+ setInternalState(next)
27
+ onChange?.(next, ...args)
28
+ },
29
+ [onChange],
30
+ )
31
+
32
+ return [state, setState] as const
33
+ }
@@ -0,0 +1,68 @@
1
+ 'use client'
2
+
3
+ import React, { useEffect, useRef, useState } from 'react'
4
+ import { motion, useScroll, useTransform } from 'framer-motion'
5
+
6
+ type FadeOffset = 'start start' | 'start center' | 'start end' | `start ${number}%`
7
+
8
+ interface FadeOnScrollProps {
9
+ children: React.ReactNode
10
+ startFade?: number
11
+ endFade?: number
12
+ finalOpacity?: number
13
+ offsetStart?: FadeOffset
14
+ offsetEnd?: FadeOffset
15
+ useAbsoluteScroll?: boolean
16
+ }
17
+
18
+ export const FadeOnScroll: React.FC<FadeOnScrollProps> = ({
19
+ children,
20
+ startFade = 0,
21
+ endFade = 1,
22
+ finalOpacity = 0,
23
+ offsetStart = 'start 50%',
24
+ offsetEnd = 'start 0%',
25
+ useAbsoluteScroll = false,
26
+ }) => {
27
+ const containerRef = useRef<HTMLDivElement>(null)
28
+ const [targetRef, setTargetRef] = useState<HTMLElement | null>(null)
29
+
30
+ // Bind scroll tracking only when ready
31
+ const scrollSetupRef = useRef(false)
32
+ const { scrollY, scrollYProgress } = useScroll({
33
+ target: targetRef ? { current: targetRef } : undefined,
34
+ offset: [offsetStart, offsetEnd],
35
+ })
36
+
37
+ const opacity = useTransform(
38
+ useAbsoluteScroll ? scrollY : scrollYProgress,
39
+ [startFade, endFade],
40
+ [1, finalOpacity],
41
+ )
42
+
43
+ useEffect(() => {
44
+ if (typeof window === 'undefined') return
45
+
46
+ const container = containerRef.current
47
+ if (!container) return
48
+
49
+ const parent = container.closest('.renderblock-container')
50
+ if (!parent) return
51
+
52
+ let sibling = parent.nextElementSibling as HTMLElement | null
53
+ while (sibling && !sibling.classList.contains('renderblock-container')) {
54
+ sibling = sibling.nextElementSibling as HTMLElement | null
55
+ }
56
+
57
+ if (sibling && !scrollSetupRef.current) {
58
+ setTargetRef(sibling)
59
+ scrollSetupRef.current = true
60
+ }
61
+ }, [])
62
+
63
+ return (
64
+ <motion.div ref={containerRef} style={{ opacity }}>
65
+ {children}
66
+ </motion.div>
67
+ )
68
+ }
@@ -0,0 +1,157 @@
1
+ 'use client'
2
+
3
+ import React, { useEffect, useId, useRef } from 'react'
4
+ import { motion, useScroll, useTransform } from 'framer-motion'
5
+ import { gsap } from 'gsap'
6
+ import { ScrollTrigger } from 'gsap/ScrollTrigger'
7
+ import { ScrollToPlugin } from 'gsap/ScrollToPlugin'
8
+
9
+ type ParallaxWrapperProps = {
10
+ children: React.ReactNode
11
+ enabled?: boolean
12
+ sectionId?: string
13
+ animationConfig?: {
14
+ smooth?: number
15
+ effects?: boolean
16
+ scrollToSelector?: string
17
+ scrollDuration?: number
18
+ ease?: string
19
+ triggerSelector?: string
20
+ pinSpacing?: number | string
21
+ pinTargetSelector?: string
22
+ markers?: boolean
23
+ makers?: boolean
24
+ parallaxDistance?: number
25
+ parallaxDirection?: 'up' | 'down'
26
+ }
27
+ }
28
+
29
+ const toNumber = (value: number | string | undefined, fallback: number): number => {
30
+ if (typeof value === 'number' && Number.isFinite(value)) return value
31
+
32
+ if (typeof value === 'string') {
33
+ const parsed = Number(value)
34
+ if (Number.isFinite(parsed)) return parsed
35
+ }
36
+
37
+ return fallback
38
+ }
39
+
40
+ const ParallaxWrapper: React.FC<ParallaxWrapperProps> = ({
41
+ children,
42
+ enabled = true,
43
+ sectionId,
44
+ animationConfig = {},
45
+ }) => {
46
+ const reactId = useId()
47
+ const safeId = sectionId || `parallax-${reactId.replace(/:/g, '')}`
48
+
49
+ const sectionRef = useRef<HTMLElement>(null)
50
+ const innerRef = useRef<HTMLDivElement>(null)
51
+
52
+ const {
53
+ scrollToSelector,
54
+ scrollDuration = 1.3,
55
+ triggerSelector,
56
+ pinTargetSelector,
57
+ pinSpacing,
58
+ markers,
59
+ makers,
60
+ parallaxDistance = 120,
61
+ parallaxDirection = 'up',
62
+ } = animationConfig
63
+
64
+ const showMarkers = markers === true || makers === true
65
+ const distance = Math.abs(toNumber(parallaxDistance, 120))
66
+ const yStart = parallaxDirection === 'down' ? -distance : distance
67
+ const yEnd = parallaxDirection === 'down' ? distance : -distance
68
+
69
+ const { scrollYProgress } = useScroll({
70
+ target: sectionRef,
71
+ offset: ['start end', 'end start'],
72
+ })
73
+
74
+ const y = useTransform(scrollYProgress, [0, 1], [yStart, yEnd])
75
+
76
+ useEffect(() => {
77
+ if (!enabled || typeof window === 'undefined') return
78
+
79
+ gsap.registerPlugin(ScrollTrigger, ScrollToPlugin)
80
+
81
+ const sectionEl = sectionRef.current
82
+ const innerEl = innerRef.current
83
+
84
+ if (!sectionEl || !innerEl) return
85
+
86
+ const scrollTo = (selector: string = scrollToSelector || `#${safeId}`) => {
87
+ if (!selector) return
88
+
89
+ if ((window as any).lenis) {
90
+ ;(window as any).lenis.scrollTo(selector, {
91
+ offset: 0,
92
+ duration: scrollDuration,
93
+ easing: (t: number) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
94
+ })
95
+ return
96
+ }
97
+
98
+ const target = document.querySelector(selector)
99
+ if (target) {
100
+ target.scrollIntoView({ behavior: 'smooth', block: 'start' })
101
+ }
102
+ }
103
+
104
+ ;(window as any).gsapScrollTo = scrollTo
105
+
106
+ const triggerEl = triggerSelector ? document.querySelector(triggerSelector) : sectionEl
107
+ const pinEl = pinTargetSelector ? document.querySelector(pinTargetSelector) : null
108
+
109
+ if (!triggerEl) return
110
+
111
+ let pinTrigger: ScrollTrigger | undefined
112
+
113
+ if (pinEl) {
114
+ const pinDistance = toNumber(pinSpacing, window.innerHeight)
115
+
116
+ pinTrigger = ScrollTrigger.create({
117
+ trigger: triggerEl,
118
+ pin: pinEl,
119
+ start: 'top top',
120
+ end: `+=${pinDistance}`,
121
+ scrub: true,
122
+ markers: showMarkers,
123
+ invalidateOnRefresh: true,
124
+ })
125
+ }
126
+
127
+ return () => {
128
+ pinTrigger?.kill()
129
+ }
130
+ }, [
131
+ enabled,
132
+ safeId,
133
+ scrollToSelector,
134
+ scrollDuration,
135
+ triggerSelector,
136
+ pinTargetSelector,
137
+ pinSpacing,
138
+ showMarkers,
139
+ ])
140
+
141
+ if (!enabled) return <>{children}</>
142
+
143
+ return (
144
+ <section
145
+ id={safeId}
146
+ ref={sectionRef}
147
+ className="relative overflow-hidden"
148
+ data-parallax-wrapper="true"
149
+ >
150
+ <motion.div ref={innerRef} style={{ y }} className="relative will-change-transform">
151
+ {children}
152
+ </motion.div>
153
+ </section>
154
+ )
155
+ }
156
+
157
+ export default ParallaxWrapper
@@ -0,0 +1,5 @@
1
+ export const extractCustomCSS = (blocks: any[]) =>
2
+ (Array.isArray(blocks) ? blocks : [])
3
+ ?.filter((block) => block.blockType === 'customCSS')
4
+ .map((block) => block.css)
5
+ .join('\n')