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,472 @@
1
+ 'use client'
2
+
3
+ import React from 'react'
4
+ import { motion } from 'framer-motion'
5
+ import { TextFade } from '@/components/ui/anims/fade'
6
+ import { cn } from '@/utilities/ui'
7
+ import RichText from '@/components/RichText'
8
+ import { Media } from '@/components/Media'
9
+ import ElectricBorder from './ElectricBorder'
10
+
11
+ export type CardVariant =
12
+ | 'SimpleCard_V1'
13
+ | 'SimpleCard_V2'
14
+ | 'SimpleCard_V3'
15
+ | 'SimpleCard_V4'
16
+ | 'SimpleCard_V5'
17
+ | 'SimpleCard_V6'
18
+ | 'SimpleCard_V7'
19
+
20
+ export type CardWithVariantsProps = {
21
+ cards: {
22
+ content?: any
23
+ variant: CardVariant
24
+ avatar?: any
25
+ avatarPriority?: boolean
26
+ avatarImgClass?: string
27
+ servCardContClass?: string
28
+ simpleCard1Class?: string
29
+ simpleCard2Class?: string
30
+ simpleCard3Class?: string
31
+ simpleCard4Class?: string
32
+ simpleCard5Class?: string
33
+ simpleCard6Class?: string
34
+ simpleCard7Class?: string
35
+ electrifyBorder?: boolean
36
+ electricColor?: string
37
+ electricSpeed?: number
38
+ electricChaos?: number
39
+ electricThickness?: number
40
+ enableCustomCSS?: boolean
41
+ customCSS?: string
42
+ }[]
43
+ className?: string
44
+ gridClass?: string
45
+ containerClass?: string
46
+ }
47
+
48
+ const motionSettings = (index: number) => ({
49
+ initial: { opacity: 0, y: 20 },
50
+ whileInView: { opacity: 1, y: 0 },
51
+ transition: { duration: 0.4, delay: index * 0.1, ease: [0.4, 0, 0.2, 1] as const },
52
+ viewport: { once: true, amount: 0.2 },
53
+ })
54
+
55
+ const CardBody = ({
56
+ content,
57
+ className = 'p-1',
58
+ richTextClassName,
59
+ servCardContClass,
60
+ }: {
61
+ content?: any
62
+ className?: string
63
+ richTextClassName?: string
64
+ servCardContClass?: string
65
+ }) => (
66
+ <TextFade direction="up" className="card-block-anims">
67
+ <div className={cn(className, servCardContClass, 'flex justify-center')}>
68
+ {content && (
69
+ <RichText
70
+ data={content}
71
+ enableGutter={false}
72
+ enableProse={false}
73
+ className={cn('card-rt flex', richTextClassName, servCardContClass)}
74
+ />
75
+ )}
76
+ </div>
77
+ </TextFade>
78
+ )
79
+
80
+ const SimpleContainer = ({
81
+ children,
82
+ customClass,
83
+ }: {
84
+ children: React.ReactNode
85
+ customClass?: string
86
+ }) => (
87
+ <div className={cn('simple-card-1 relative mx-auto w-full bg-transparent', customClass)}>
88
+ <div className="simple-card-1-div1 relative z-20 mx-auto">{children}</div>
89
+ </div>
90
+ )
91
+
92
+ const ShadowContainer = ({
93
+ children,
94
+ customClass,
95
+ }: {
96
+ children: React.ReactNode
97
+ customClass?: string
98
+ }) => (
99
+ <div
100
+ className={cn('simple-card-2 relative mx-auto h-auto w-full bg-card shadow-xl', customClass)}
101
+ >
102
+ <div className="simple-card-2-div1 relative z-20 overflow-hidden p-2">{children}</div>
103
+ </div>
104
+ )
105
+
106
+ const PlusIcon = ({ className, ...rest }: React.SVGProps<SVGSVGElement>) => (
107
+ <svg
108
+ xmlns="http://www.w3.org/2000/svg"
109
+ fill="none"
110
+ viewBox="0 0 24 24"
111
+ width={24}
112
+ height={24}
113
+ strokeWidth="1"
114
+ stroke="currentColor"
115
+ role="presentation"
116
+ aria-hidden="true"
117
+ {...rest}
118
+ className={cn('absolute size-6 text-purple-600 dark:text-[#9acd32]', className)}
119
+ >
120
+ <path strokeLinecap="round" strokeLinejoin="round" d="M12 6v12m6-6H6" />
121
+ </svg>
122
+ )
123
+
124
+ const DecorativeDiv = ({ className, style, ...rest }: React.HTMLAttributes<HTMLDivElement>) => (
125
+ <div
126
+ {...rest}
127
+ className={cn('absolute size-6 text-purple-600 dark:text-[#9acd32]', className)}
128
+ style={style}
129
+ />
130
+ )
131
+
132
+ const cardStyles = {
133
+ v4: { borderRadius: '0px' },
134
+ v5: { borderRadius: '4px' },
135
+ v7Outer: { border: '0px solid rgb(0 0 0 / 0.3)', borderRadius: '14px' },
136
+ v7Inner: {
137
+ borderRadius: '4px',
138
+ filter: 'brightness(1.2) invert(0) contrast(1)',
139
+ border: '0px solid transparent',
140
+ // @ts-ignore - styles
141
+ mixBlendMode: 'revert-layer' as const,
142
+ boxShadow: '0 0 80px 0px inset rgba(255, 255, 255, 0.2)',
143
+ },
144
+ }
145
+
146
+ const cornerStyles = {
147
+ topLeft: {
148
+ borderLeft: '3px outset currentColor',
149
+ borderTop: '3px outset currentColor',
150
+ borderRadius: '6px 0 0 0',
151
+ },
152
+ topRight: {
153
+ borderRight: '3px outset currentColor',
154
+ borderTop: '3px outset currentColor',
155
+ borderRadius: '0 6px 0 0',
156
+ },
157
+ bottomLeft: {
158
+ borderLeft: '3px outset currentColor',
159
+ borderBottom: '3px outset currentColor',
160
+ borderRadius: '0 0 0 6px',
161
+ },
162
+ bottomRight: {
163
+ borderRight: '3px outset currentColor',
164
+ borderBottom: '3px outset currentColor',
165
+ borderRadius: '0 0 6px 0',
166
+ },
167
+ }
168
+
169
+ const CardVariants: Record<
170
+ CardVariant,
171
+ React.FC<{
172
+ content: any
173
+ index: number
174
+ avatar?: any
175
+ avatarPriority?: boolean
176
+ avatarImgClass?: string
177
+ servCardContClass?: string
178
+ simpleCard1Class?: string
179
+ simpleCard2Class?: string
180
+ simpleCard3Class?: string
181
+ simpleCard4Class?: string
182
+ simpleCard5Class?: string
183
+ simpleCard6Class?: string
184
+ simpleCard7Class?: string
185
+ }>
186
+ > = {
187
+ SimpleCard_V1: ({ content, index, servCardContClass, simpleCard1Class }) => (
188
+ <SimpleContainer customClass={simpleCard1Class}>
189
+ <motion.div {...motionSettings(index)} className="w-full">
190
+ <CardBody content={content} servCardContClass={servCardContClass} />
191
+ </motion.div>
192
+ </SimpleContainer>
193
+ ),
194
+
195
+ SimpleCard_V2: ({
196
+ content,
197
+ index,
198
+ avatar,
199
+ avatarPriority,
200
+ avatarImgClass,
201
+ servCardContClass,
202
+ simpleCard2Class,
203
+ }) => (
204
+ <TextFade direction="up" className="space-y-0">
205
+ <ShadowContainer customClass={simpleCard2Class}>
206
+ <motion.div {...motionSettings(index)} className="simple-card-2-div2 flex w-full flex-wrap">
207
+ {avatar ? (
208
+ <>
209
+ <div className="simple-card-2-div3 w-1/4">
210
+ <div className="simple-card-2-div4 avatar-container relative flex w-full max-w-24 items-start justify-center p-1 object-contain">
211
+ <TextFade direction="down" className="w-full space-y-0">
212
+ <div className="relative aspect-square w-full overflow-hidden">
213
+ <Media
214
+ priority={avatarPriority}
215
+ resource={avatar}
216
+ fill
217
+ className="avatar-media h-full w-full [&_picture]:!my-0 [&_picture]:block [&_picture]:h-full [&_picture]:w-full [&_picture_img]:!my-0"
218
+ imgClassName={cn(
219
+ 'z-[1] !my-0 h-full w-full rounded-[2px]',
220
+ avatarImgClass || 'object-contain',
221
+ )}
222
+ />
223
+ </div>
224
+ </TextFade>
225
+ </div>
226
+ </div>
227
+ <div className="simple-card-2-div5 w-3/4">
228
+ <CardBody
229
+ content={content}
230
+ servCardContClass={servCardContClass}
231
+ className="card-body-content flex w-full flex-col p-2 [&_p]:!text-[13px] [&_p]:!tracking-[0.5px] [&_p]:!opacity-75"
232
+ />
233
+ </div>
234
+ </>
235
+ ) : (
236
+ <div className="simple-card-2-div6 w-full">
237
+ <CardBody
238
+ content={content}
239
+ servCardContClass={servCardContClass}
240
+ className="card-body-content flex w-full p-1 [&_p]:!text-[13px] [&_p]:!tracking-[0.5px] [&_p]:!opacity-75"
241
+ />
242
+ </div>
243
+ )}
244
+ </motion.div>
245
+ </ShadowContainer>
246
+ </TextFade>
247
+ ),
248
+
249
+ SimpleCard_V3: ({ content, index, servCardContClass, simpleCard3Class }) => (
250
+ <motion.div
251
+ {...motionSettings(index)}
252
+ className={cn(
253
+ 'simple-card-3 relative my-4 flex border border-dashed border-neutral-700 transition-all duration-300 dark:border-white/50',
254
+ '[&_.custom-span]:!top-1 [&_.custom-span]:left-2 [&_.custom-span]:opacity-100',
255
+ simpleCard3Class,
256
+ )}
257
+ >
258
+ <PlusIcon className="left-[-12.5px] top-[-12.5px]" />
259
+ <PlusIcon className="right-[-12.5px] top-[-12.5px]" />
260
+ <PlusIcon className="bottom-[-12.5px] left-[-12.5px]" />
261
+ <PlusIcon className="bottom-[-12.5px] right-[-12.5px]" />
262
+ <CardBody content={content} className="p-0" servCardContClass={servCardContClass} />
263
+ </motion.div>
264
+ ),
265
+
266
+ SimpleCard_V4: ({ content, index, servCardContClass, simpleCard4Class }) => (
267
+ <motion.div
268
+ {...motionSettings(index)}
269
+ className={cn('simple-card-4 relative border-0 shadow-lg', simpleCard4Class)}
270
+ style={cardStyles.v4}
271
+ >
272
+ <CardBody content={content} className="p-0" servCardContClass={servCardContClass} />
273
+ </motion.div>
274
+ ),
275
+
276
+ SimpleCard_V5: ({ content, index, servCardContClass, simpleCard5Class }) => (
277
+ <div
278
+ className={cn(
279
+ 'simple-card-5 min-w-[250px] border-[0.5px] bg-white/70 p-1 backdrop-blur-[10px] transition-all duration-300',
280
+ simpleCard5Class,
281
+ )}
282
+ >
283
+ <motion.div
284
+ {...motionSettings(index)}
285
+ className={cn(
286
+ 'simple-card-5-div1 border bg-gradient-to-br',
287
+ 'from-white to-zinc-200/60 border-stone-300 shadow-[2px_0_8px_rgba(0,_0,_0,_0.15)]',
288
+ 'dark:from-zinc-950 dark:to-zinc-900/60 dark:border-stone-900/50 dark:shadow-inner',
289
+ )}
290
+ style={cardStyles.v5}
291
+ >
292
+ <CardBody
293
+ content={content}
294
+ servCardContClass={servCardContClass}
295
+ className="card-body-content flex p-4 [&_p]:!text-[13px] [&_p]:!tracking-[0.5px] [&_p]:!opacity-75"
296
+ />
297
+ </motion.div>
298
+ </div>
299
+ ),
300
+
301
+ SimpleCard_V6: ({ content, index, servCardContClass, simpleCard6Class }) => (
302
+ <div
303
+ className={cn(
304
+ 'simple-card-6 border-[0.5px] border-stone-300 p-2 shadow-[2px_0_8px_rgba(0,_0,_0,_0.15)]',
305
+ '[&_.prose_:where(picture):not(:where([class~="not-prose"],[class~="not-prose"]_*))]:!my-0 [&_.prose_:where(picture):not(:where([class~="not-prose"],[class~="not-prose"]_*))]:block',
306
+ '[&_.py-4]:!py-0',
307
+ simpleCard6Class,
308
+ )}
309
+ >
310
+ <motion.div
311
+ {...motionSettings(index)}
312
+ className="simple-card-6-div1 relative border border-stone-400 bg-white/70 px-4 py-8 shadow-[2px_0_8px_rgba(0,_0,_0,_0.15)] backdrop-blur-[10px]"
313
+ >
314
+ <CardBody
315
+ content={content}
316
+ className="simple-card-6-content"
317
+ servCardContClass={servCardContClass}
318
+ />
319
+ </motion.div>
320
+ </div>
321
+ ),
322
+
323
+ SimpleCard_V7: ({ content, index, servCardContClass, simpleCard7Class }) => (
324
+ <motion.div
325
+ {...motionSettings(index)}
326
+ className={cn('simple-card-7 relative z-0 size-full shadow-lg', simpleCard7Class)}
327
+ style={cardStyles.v7Outer}
328
+ >
329
+ <div
330
+ className="simple-card-7-div1 relative z-[1] size-full bg-grid p-1"
331
+ style={cardStyles.v7Inner}
332
+ >
333
+ <DecorativeDiv className="-left-0.5 -top-0.5 z-[2] invert-0" style={cornerStyles.topLeft} />
334
+ <DecorativeDiv
335
+ className="-right-0.5 -top-0.5 z-[2] invert-0"
336
+ style={cornerStyles.topRight}
337
+ />
338
+ <DecorativeDiv
339
+ className="-bottom-0.5 -left-0.5 z-[2] invert-0"
340
+ style={cornerStyles.bottomLeft}
341
+ />
342
+ <DecorativeDiv
343
+ className="-bottom-0.5 -right-0.5 z-[2] invert-0"
344
+ style={cornerStyles.bottomRight}
345
+ />
346
+ <CardBody
347
+ content={content}
348
+ className="z-[2] overflow-hidden rounded-sm p-0 shadow-xl invert-0"
349
+ richTextClassName="px-4 py-4"
350
+ servCardContClass={servCardContClass}
351
+ />
352
+ </div>
353
+ </motion.div>
354
+ ),
355
+ }
356
+
357
+ export const CardWithVariants: React.FC<CardWithVariantsProps> = ({
358
+ cards,
359
+ className,
360
+ containerClass,
361
+ gridClass,
362
+ }) => {
363
+ const scopeId = React.useId().replace(/:/g, '')
364
+
365
+ const mergedCustomCSS = React.useMemo(() => {
366
+ return (cards || [])
367
+ .filter((card) => Boolean(card?.enableCustomCSS && card?.customCSS))
368
+ .map((card) => String(card.customCSS))
369
+ .join('\n')
370
+ }, [cards])
371
+
372
+ const injectedCSS = React.useMemo(() => {
373
+ if (!mergedCustomCSS.trim()) return ''
374
+ return mergedCustomCSS.split(':host').join(`[data-cwv-scope="${scopeId}"]`)
375
+ }, [mergedCustomCSS, scopeId])
376
+
377
+ const getVariantCustomClass = (card: CardWithVariantsProps['cards'][number]) => {
378
+ switch (card.variant) {
379
+ case 'SimpleCard_V1':
380
+ return card.simpleCard1Class
381
+ case 'SimpleCard_V2':
382
+ return card.simpleCard2Class
383
+ case 'SimpleCard_V3':
384
+ return card.simpleCard3Class
385
+ case 'SimpleCard_V4':
386
+ return card.simpleCard4Class
387
+ case 'SimpleCard_V5':
388
+ return card.simpleCard5Class
389
+ case 'SimpleCard_V6':
390
+ return card.simpleCard6Class
391
+ case 'SimpleCard_V7':
392
+ return card.simpleCard7Class
393
+ default:
394
+ return undefined
395
+ }
396
+ }
397
+
398
+ if (!cards || cards.length === 0) return null
399
+
400
+ return (
401
+ <div
402
+ className={cn(
403
+ 'simple-cards-container mt-6 block w-full transition-all duration-300',
404
+ '[&_h1]:!m-0 [&_h1]:!p-0 [&_h2]:!m-0 [&_h2]:!p-0 [&_h3]:!m-0 [&_h3]:!p-0 [&_h4]:!m-0 [&_h4]:!p-0 [&_h5]:!m-0 [&_h5]:!p-0 [&_h6]:!m-0 [&_h6]:!p-0',
405
+ containerClass,
406
+ className,
407
+ )}
408
+ data-cwv-scope={scopeId}
409
+ >
410
+ {injectedCSS.trim() && (
411
+ <style data-cwv-style={scopeId} dangerouslySetInnerHTML={{ __html: injectedCSS }} />
412
+ )}
413
+
414
+ <div className={cn(gridClass || 'grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3')}>
415
+ {cards.map((card, index) => {
416
+ const CardComponent = CardVariants[card.variant] || CardVariants.SimpleCard_V1
417
+ const baseKey = `${card.variant}-${index}`
418
+ const variantCustomClass = getVariantCustomClass(card)
419
+ const derivedCardClasses = variantCustomClass
420
+ ? variantCustomClass
421
+ .split(/\s+/)
422
+ .filter(Boolean)
423
+ .map((token) => `${token}_card`)
424
+ : []
425
+
426
+ const cardElement = (
427
+ <div
428
+ className={cn('cwv-card w-full', derivedCardClasses)}
429
+ data-cwv-card
430
+ data-card-index={index}
431
+ data-card-variant={card.variant}
432
+ data-card-classlist={variantCustomClass || undefined}
433
+ >
434
+ <CardComponent
435
+ content={card.content}
436
+ index={index}
437
+ avatar={card?.avatar}
438
+ avatarPriority={card?.avatarPriority}
439
+ avatarImgClass={card?.avatarImgClass}
440
+ servCardContClass={card?.servCardContClass}
441
+ simpleCard1Class={card?.simpleCard1Class}
442
+ simpleCard2Class={card?.simpleCard2Class}
443
+ simpleCard3Class={card?.simpleCard3Class}
444
+ simpleCard4Class={card?.simpleCard4Class}
445
+ simpleCard5Class={card?.simpleCard5Class}
446
+ simpleCard6Class={card?.simpleCard6Class}
447
+ simpleCard7Class={card?.simpleCard7Class}
448
+ />
449
+ </div>
450
+ )
451
+
452
+ if (card.electrifyBorder) {
453
+ return (
454
+ <ElectricBorder
455
+ key={`electric-${baseKey}`}
456
+ color={card.electricColor || '#7df9ff'}
457
+ speed={card.electricSpeed || 1}
458
+ chaos={card.electricChaos || 0.5}
459
+ thickness={card.electricThickness || 2}
460
+ style={{ borderRadius: 16 }}
461
+ >
462
+ {cardElement}
463
+ </ElectricBorder>
464
+ )
465
+ }
466
+
467
+ return <React.Fragment key={baseKey}>{cardElement}</React.Fragment>
468
+ })}
469
+ </div>
470
+ </div>
471
+ )
472
+ }
@@ -0,0 +1,203 @@
1
+ 'use client'
2
+
3
+ import { electricBorderStyles } from './styles'
4
+ import { useInjectStyle } from './useInjectStyle'
5
+ /* eslint-disable react-hooks/exhaustive-deps */
6
+ import React, {
7
+ CSSProperties,
8
+ PropsWithChildren,
9
+ useEffect,
10
+ useId,
11
+ useLayoutEffect,
12
+ useRef
13
+ } from 'react'
14
+
15
+ type ElectricBorderProps = PropsWithChildren<{
16
+ color?: string
17
+ speed?: number
18
+ chaos?: number
19
+ thickness?: number
20
+ className?: string
21
+ style?: CSSProperties
22
+ }>
23
+
24
+ const ElectricBorder: React.FC<ElectricBorderProps> = ({
25
+ children,
26
+ color = '#5227FF',
27
+ speed = 1,
28
+ chaos = 1,
29
+ thickness = 2,
30
+ className,
31
+ style
32
+ }: ElectricBorderProps) => {
33
+ useInjectStyle(electricBorderStyles, 'dd-electric-border-styles')
34
+ const rawId = useId().replace(/[:]/g, '')
35
+ const filterId = `turbulent-displace-${rawId}`
36
+ const svgRef = useRef<SVGSVGElement | null>(null)
37
+ const rootRef = useRef<HTMLDivElement | null>(null)
38
+ const strokeRef = useRef<HTMLDivElement | null>(null)
39
+ const animationFrameRef = useRef<number | null>(null)
40
+
41
+ const updateAnim = () => {
42
+ const svg = svgRef.current
43
+ const host = rootRef.current
44
+ if (!svg || !host) return
45
+
46
+ if (strokeRef.current) {
47
+ strokeRef.current.style.filter = `url(#${filterId})`
48
+ }
49
+
50
+ const width = Math.max(
51
+ 1,
52
+ Math.round(host.clientWidth || host.getBoundingClientRect().width || 0)
53
+ )
54
+ const height = Math.max(
55
+ 1,
56
+ Math.round(host.clientHeight || host.getBoundingClientRect().height || 0)
57
+ )
58
+
59
+ const offsetNoise1 = svg.querySelector<SVGElement>('feOffset[result="offsetNoise1"]')
60
+ const offsetNoise2 = svg.querySelector<SVGElement>('feOffset[result="offsetNoise2"]')
61
+ const offsetNoise3 = svg.querySelector<SVGElement>('feOffset[result="offsetNoise3"]')
62
+ const offsetNoise4 = svg.querySelector<SVGElement>('feOffset[result="offsetNoise4"]')
63
+
64
+ const baseDur = 6
65
+ const durationMs = Math.max(1, (baseDur / (speed || 1)) * 1000)
66
+
67
+ if (animationFrameRef.current !== null) {
68
+ cancelAnimationFrame(animationFrameRef.current)
69
+ }
70
+
71
+ const tick = (now: number) => {
72
+ const progress = (now % durationMs) / durationMs
73
+
74
+ offsetNoise1?.setAttribute('dy', String(height * (1 - progress)))
75
+ offsetNoise2?.setAttribute('dy', String(-height * progress))
76
+ offsetNoise3?.setAttribute('dx', String(width * (1 - progress)))
77
+ offsetNoise4?.setAttribute('dx', String(-width * progress))
78
+
79
+ animationFrameRef.current = requestAnimationFrame(tick)
80
+ }
81
+
82
+ animationFrameRef.current = requestAnimationFrame(tick)
83
+
84
+ const disp = svg.querySelector('feDisplacementMap')
85
+ if (disp) disp.setAttribute('scale', String(30 * (chaos || 1)))
86
+
87
+ const filterEl = svg.querySelector<SVGFilterElement>(`#${CSS.escape(filterId)}`)
88
+ if (filterEl) {
89
+ filterEl.setAttribute('x', '-200%')
90
+ filterEl.setAttribute('y', '-200%')
91
+ filterEl.setAttribute('width', '500%')
92
+ filterEl.setAttribute('height', '500%')
93
+ }
94
+ }
95
+
96
+ useEffect(() => {
97
+ updateAnim()
98
+ }, [speed, chaos])
99
+
100
+ useLayoutEffect(() => {
101
+ if (!rootRef.current) return
102
+ const ro = new ResizeObserver(() => updateAnim())
103
+ ro.observe(rootRef.current)
104
+ updateAnim()
105
+ return () => {
106
+ ro.disconnect()
107
+ if (animationFrameRef.current !== null) {
108
+ cancelAnimationFrame(animationFrameRef.current)
109
+ }
110
+ }
111
+ }, [])
112
+
113
+ const vars: CSSProperties = {
114
+ ['--electric-border-color' as any]: color,
115
+ ['--eb-border-width' as any]: `${thickness}px`
116
+ }
117
+
118
+ return (
119
+ <div
120
+ ref={rootRef}
121
+ className={`electric-border ${className ?? ''}`}
122
+ style={{ ...vars, ...style }}
123
+ >
124
+ <svg
125
+ ref={svgRef}
126
+ className="eb-svg"
127
+ aria-hidden
128
+ focusable="false"
129
+ style={{ willChange: 'filter' }}
130
+ >
131
+ <defs>
132
+ <filter
133
+ id={filterId}
134
+ colorInterpolationFilters="sRGB"
135
+ x="-20%"
136
+ y="-20%"
137
+ width="140%"
138
+ height="140%"
139
+ style={{ willChange: 'filter' }}
140
+ >
141
+ <feTurbulence
142
+ type="turbulence"
143
+ baseFrequency="0.02"
144
+ numOctaves="10"
145
+ result="noise1"
146
+ seed="1"
147
+ />
148
+ <feOffset in="noise1" dx="700" dy="0" result="offsetNoise1" />
149
+
150
+ <feTurbulence
151
+ type="turbulence"
152
+ baseFrequency="0.02"
153
+ numOctaves="10"
154
+ result="noise2"
155
+ seed="1"
156
+ />
157
+ <feOffset in="noise2" dx="0" dy="0" result="offsetNoise2" />
158
+
159
+ <feTurbulence
160
+ type="turbulence"
161
+ baseFrequency="0.02"
162
+ numOctaves="10"
163
+ result="noise1"
164
+ seed="2"
165
+ />
166
+ <feOffset in="noise1" dx="490" dy="0" result="offsetNoise3" />
167
+
168
+ <feTurbulence
169
+ type="turbulence"
170
+ baseFrequency="0.02"
171
+ numOctaves="10"
172
+ result="noise2"
173
+ seed="2"
174
+ />
175
+ <feOffset in="noise2" dx="0" dy="0" result="offsetNoise4" />
176
+
177
+ <feComposite in="offsetNoise1" in2="offsetNoise2" result="part1" />
178
+ <feComposite in="offsetNoise3" in2="offsetNoise4" result="part2" />
179
+ <feBlend in="part1" in2="part2" mode="color-dodge" result="combinedNoise" />
180
+ <feDisplacementMap
181
+ in="SourceGraphic"
182
+ in2="combinedNoise"
183
+ scale="30"
184
+ xChannelSelector="R"
185
+ yChannelSelector="B"
186
+ />
187
+ </filter>
188
+ </defs>
189
+ </svg>
190
+
191
+ <div className="eb-layers">
192
+ <div ref={strokeRef} className="eb-stroke" style={{ willChange: 'filter' }} />
193
+ <div className="eb-glow-1" />
194
+ <div className="eb-glow-2" />
195
+ <div className="eb-background-glow" />
196
+ </div>
197
+
198
+ <div className="eb-content">{children}</div>
199
+ </div>
200
+ )
201
+ }
202
+
203
+ export default ElectricBorder