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
@@ -1,93 +1,180 @@
1
- 'use client'
2
-
3
- import React, { useState } from 'react'
4
- import { motion } from 'framer-motion'
5
- import Image from 'next/image'
6
- import { cn } from '@/utilities/ui'
7
- // DDHG TODO: Re-enable after reviewing the project-specific separator/custom CSS bundle.
8
- // import { Separator } from '@/components/ui/separator'
9
- // import { extractCustomCSS } from '@/utilities/renderCustomCSS'
10
-
11
- const placeholderBlur =
12
- 'data:image/svg+xml;base64,' +
13
- btoa(`<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" style="opacity:0"><rect width="100%" height="100%" fill="transparent" /></svg>`)
14
-
15
- type LogoItem = {
16
- image?: { url?: string | null; alt?: string | null } | null
17
- imageClass?: string | null
18
- imageStyle?: React.CSSProperties
19
- imageAltClass?: string | null
20
- }
21
-
22
- export type DDHGLogoMarqueeProps = {
23
- sectionId?: string | null
24
- logos?: LogoItem[] | null
25
- speed?: number | null
26
- spacing?: number | null
27
- priority?: boolean | null
28
- showTopDivider?: boolean | null
29
- showBottomDivider?: boolean | null
30
- containerClass?: string | null
31
- itemWidth?: number | null
32
- enableCustomCSS?: boolean | null
33
- customCSS?: Array<{ blockType?: string; css?: string }> | string | null
34
- }
35
-
36
- const LogoImage: React.FC<{ src: string; alt?: string | null; customClass?: string | null; imageStyle?: React.CSSProperties; priority?: boolean }> = ({ src, alt, customClass, imageStyle, priority = false }) => {
37
- const [imageError, setImageError] = useState(false)
38
- const imageSrc = !src || imageError ? placeholderBlur : src
39
- return <Image src={imageSrc} alt={alt || 'Logo'} width={300} height={300} priority={priority} className={customClass || ''} style={{ objectFit: 'contain', ...(imageStyle && typeof imageStyle === 'object' ? imageStyle : {}) }} onError={() => setImageError(true)} placeholder="blur" blurDataURL={placeholderBlur} />
40
- }
41
-
42
- export const DDHGLogoMarquee: React.FC<DDHGLogoMarqueeProps> = ({
43
- sectionId,
44
- logos,
45
- speed = 10,
46
- spacing = 32,
47
- priority = false,
48
- showTopDivider = false,
49
- showBottomDivider = false,
50
- containerClass = 'overflow-hidden py-8 bg-transparent',
51
- enableCustomCSS = false,
52
- customCSS,
53
- itemWidth,
54
- }) => {
55
- const validLogos = Array.isArray(logos) ? logos : []
56
- if (validLogos.length === 0) return null
57
- const calculatedItemWidth = itemWidth || 100
58
- const totalWidth = validLogos.length * (calculatedItemWidth + (spacing || 0))
59
-
60
- // DDHG TODO: Re-enable with extractCustomCSS when that bundle is reviewed.
61
- // const extractedCSS = enableCustomCSS && Array.isArray(customCSS)
62
- // ? extractCustomCSS(customCSS)
63
- // : typeof customCSS === 'string'
64
- // ? customCSS
65
- // : ''
66
- const extractedCSS = ''
67
- void enableCustomCSS
68
- void customCSS
69
- void showTopDivider
70
- void showBottomDivider
71
-
72
- const renderSet = (suffix = '') => validLogos.map((logo, index) => (
73
- <div key={`logo-${index}${suffix}`} className="marque-image-container flex-shrink-0 flex flex-col items-center justify-center" style={{ marginRight: `${spacing || 0}px`, ...(itemWidth ? { width: `${calculatedItemWidth}px` } : { minWidth: `${calculatedItemWidth}px` }) }}>
74
- <LogoImage src={logo.image?.url || placeholderBlur} alt={logo.image?.alt} customClass={logo.imageClass} imageStyle={logo.imageStyle} priority={Boolean(priority)} />
75
- <p className={cn('text-base text-center', logo.imageAltClass)}>{logo.image?.alt || null}</p>
76
- </div>
77
- ))
78
-
79
- return <>
80
- {/* DDHG TODO: Re-enable optional Separator rendering after bundle review. */}
81
- {/* {showTopDivider && <Separator gradient={true} className="border-seperator" />} */}
82
- <div id={sectionId ?? undefined} className="logo-marquee-block relative mx-auto">
83
- {extractedCSS && <style dangerouslySetInnerHTML={{ __html: extractedCSS }} />}
84
- <motion.div className={`${containerClass} flex py-4`} animate={{ x: [0, -totalWidth] }} transition={{ repeat: Infinity, duration: speed || 10, ease: 'linear' }} style={{ width: `${totalWidth * 2}px` }}>
85
- {renderSet()}
86
- {renderSet('-duplicate')}
87
- </motion.div>
88
- </div>
89
- {/* {showBottomDivider && <Separator gradient={true} className="border-seperator opacity-20" />} */}
90
- </>
91
- }
92
-
93
- export default DDHGLogoMarquee
1
+ 'use client'
2
+
3
+ import React, { useState } from 'react'
4
+ import { motion } from 'framer-motion'
5
+ import Image from 'next/image'
6
+ import * as LucideIcons from 'lucide-react'
7
+ import { cn } from '@/utilities/ui'
8
+ // DDHG TODO: Re-enable after reviewing the project-specific separator/custom CSS bundle.
9
+ // import { Separator } from '@/components/ui/separator'
10
+ // import { extractCustomCSS } from '@/utilities/renderCustomCSS'
11
+
12
+ const placeholderBlur =
13
+ 'data:image/svg+xml;base64,' +
14
+ btoa(
15
+ `<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" style="opacity:0"><rect width="100%" height="100%" fill="transparent" /></svg>`,
16
+ )
17
+
18
+ type LogoItem = {
19
+ image?: { url?: string | null; alt?: string | null } | null
20
+ imageClass?: string | null
21
+ imageStyle?: React.CSSProperties
22
+ imageAltClass?: string | null
23
+ icon?: string | null
24
+ label?: string | null
25
+ showLabel?: boolean | null
26
+ }
27
+
28
+ function DynamicIcon({
29
+ name,
30
+ size = 36,
31
+ ...props
32
+ }: { name?: string | null } & Omit<LucideIcons.LucideProps, 'name'>) {
33
+ if (!name) return null
34
+ const Icon = (LucideIcons as unknown as Record<string, React.FC<LucideIcons.LucideProps>>)[name]
35
+ if (!Icon) return null
36
+ return <Icon size={size} {...props} />
37
+ }
38
+ export type DDHGLogoMarqueeProps = {
39
+ sectionId?: string | null
40
+ logos?: LogoItem[] | null
41
+ speed?: number | null
42
+ spacing?: number | null
43
+ priority?: boolean | null
44
+ showTopDivider?: boolean | null
45
+ showBottomDivider?: boolean | null
46
+ containerClass?: string | null
47
+ itemWidth?: number | null
48
+ enableCustomCSS?: boolean | null
49
+ customCSS?: Array<{ blockType?: string; css?: string }> | string | null
50
+ }
51
+
52
+ const LogoImage: React.FC<{
53
+ src: string
54
+ alt?: string | null
55
+ customClass?: string | null
56
+ imageStyle?: React.CSSProperties
57
+ priority?: boolean
58
+ }> = ({ src, alt, customClass, imageStyle, priority = false }) => {
59
+ const [imageError, setImageError] = useState(false)
60
+ const imageSrc = !src || imageError ? placeholderBlur : src
61
+ return (
62
+ <Image
63
+ src={imageSrc}
64
+ alt={alt || 'Logo'}
65
+ width={300}
66
+ height={300}
67
+ priority={priority}
68
+ className={customClass || ''}
69
+ style={{
70
+ objectFit: 'contain',
71
+ ...(imageStyle && typeof imageStyle === 'object' ? imageStyle : {}),
72
+ }}
73
+ onError={() => setImageError(true)}
74
+ placeholder="blur"
75
+ blurDataURL={placeholderBlur}
76
+ />
77
+ )
78
+ }
79
+
80
+ export const DDHGLogoMarquee: React.FC<DDHGLogoMarqueeProps> = ({
81
+ sectionId,
82
+ logos,
83
+ speed = 10,
84
+ spacing = 32,
85
+ priority = false,
86
+ showTopDivider = false,
87
+ showBottomDivider = false,
88
+ containerClass = 'overflow-hidden py-8 bg-transparent',
89
+ enableCustomCSS = false,
90
+ customCSS,
91
+ itemWidth,
92
+ }) => {
93
+ const validLogos = Array.isArray(logos) ? logos : []
94
+ if (validLogos.length === 0) return null
95
+ const calculatedItemWidth = itemWidth || 100
96
+ const defaultIcons = ['Code2', 'Database', 'PanelsTopLeft', 'Braces', 'Workflow', 'GitBranch']
97
+ const defaultLabels = ['Interface', 'Data', 'Layout', 'Types', 'Workflow', 'Collaboration']
98
+ const totalWidth = validLogos.length * (calculatedItemWidth + (spacing || 0))
99
+
100
+ // DDHG TODO: Re-enable with extractCustomCSS when that bundle is reviewed.
101
+ // const extractedCSS = enableCustomCSS && Array.isArray(customCSS)
102
+ // ? extractCustomCSS(customCSS)
103
+ // : typeof customCSS === 'string'
104
+ // ? customCSS
105
+ // : ''
106
+ const extractedCSS = ''
107
+ void enableCustomCSS
108
+ void customCSS
109
+ void showTopDivider
110
+ void showBottomDivider
111
+
112
+ const renderSet = (suffix = '') =>
113
+ validLogos.map((logo, index) => (
114
+ <div
115
+ key={`logo-${index}${suffix}`}
116
+ className="marque-image-container shrink-0 flex flex-col items-center justify-center"
117
+ style={{
118
+ marginRight: `${spacing || 0}px`,
119
+ ...(itemWidth
120
+ ? { width: `${calculatedItemWidth}px` }
121
+ : { minWidth: `${calculatedItemWidth}px` }),
122
+ }}
123
+ >
124
+ {true ? (
125
+ <>
126
+ <div className="flex h-20 w-20 items-center justify-center rounded-2xl border border-[#2A2A30] bg-linear-to-b from-[#1a1a1f] to-[#0f0f12] p-4 invert-[1] transition-all duration-300 hover:scale-105 hover:shadow-[0_0_30px_rgba(140,138,132,0.15)] dark:invert-[0]">
127
+ <DynamicIcon
128
+ className="text-[#9A9790]"
129
+ name={logo.icon || defaultIcons[index % defaultIcons.length]}
130
+ size={36}
131
+ />
132
+ </div>
133
+ {logo.showLabel !== false && (
134
+ <span className="mt-2 block whitespace-nowrap text-center text-sm text-[#9A9790]">
135
+ {logo.label || defaultLabels[index % defaultLabels.length]}
136
+ </span>
137
+ )}
138
+ </>
139
+ ) : (
140
+ <>
141
+ <LogoImage
142
+ src={logo.image?.url || placeholderBlur}
143
+ alt={logo.image?.alt}
144
+ customClass={logo.imageClass}
145
+ imageStyle={logo.imageStyle}
146
+ priority={Boolean(priority)}
147
+ />
148
+ <p className={cn('text-center text-base', logo.imageAltClass)}>
149
+ {logo.label || logo.image?.alt || null}
150
+ </p>
151
+ </>
152
+ )}
153
+ </div>
154
+ ))
155
+
156
+ return (
157
+ <>
158
+ {/* DDHG TODO: Re-enable optional Separator rendering after bundle review. */}
159
+ {/* {showTopDivider && <Separator gradient={true} className="border-seperator" />} */}
160
+ <div
161
+ id={sectionId ?? undefined}
162
+ className="logo-marquee-block relative mx-auto max-w-screen overflow-x-clip bg-stone-300/20 dark:bg-stone-900/10 top-[20vh]"
163
+ >
164
+ {extractedCSS && <style dangerouslySetInnerHTML={{ __html: extractedCSS }} />}
165
+ <motion.div
166
+ className={`${containerClass} flex py-4`}
167
+ animate={{ x: [0, -totalWidth] }}
168
+ transition={{ repeat: Infinity, duration: speed || 10, ease: 'linear' }}
169
+ style={{ width: `${totalWidth * 2}px` }}
170
+ >
171
+ {renderSet()}
172
+ {renderSet('-duplicate')}
173
+ </motion.div>
174
+ </div>
175
+ {/* {showBottomDivider && <Separator gradient={true} className="border-seperator opacity-20" />} */}
176
+ </>
177
+ )
178
+ }
179
+
180
+ export default DDHGLogoMarquee
@@ -1,66 +1,154 @@
1
- import type { Block } from 'payload'
2
- // DDHG TODO: Re-enable with the project-specific CustomCssBlock bundle.
3
- // import { CustomCSSBlock } from '@/blocks/CustomCssBlock/config'
4
-
5
- export const DDHGLogoMarquee: Block = {
6
- slug: 'DDHG-LogoMarquee',
7
- interfaceName: 'DDHGLogoMarquee',
8
- labels: { singular: 'Image Marquee', plural: 'Image Marquee' },
9
- fields: [
10
- { name: 'sectionId', type: 'text', label: 'Section ID', required: false, admin: { description: 'Optional anchor ID for linking and scroll targets.' } },
11
- {
12
- type: 'collapsible', label: 'Block Settings', admin: { initCollapsed: true, className: 'custom-css-class' },
13
- fields: [
14
- { type: 'collapsible', label: 'Container Class', admin: { initCollapsed: true, className: 'custom-css-class' }, fields: [
15
- { name: 'containerClass', label: false, type: 'text', required: false, admin: { description: 'Override the default container class.' } },
16
- ] },
17
- { type: 'collapsible', label: 'Marquee Settings', admin: { initCollapsed: true, className: 'custom-group-class' }, fields: [
18
- { type: 'row', fields: [
19
- { name: 'speed', type: 'number', label: 'Scroll Speed (seconds)', defaultValue: 10, required: true, admin: { width: '50%' } },
20
- { name: 'spacing', type: 'number', label: 'Spacing between images (px)', defaultValue: 32, required: true, admin: { width: '50%' } },
21
- ] },
22
- ] },
23
- { name: 'priority', type: 'checkbox', label: 'High Priority Loading', defaultValue: false },
24
- { type: 'collapsible', label: 'Dividers', admin: { initCollapsed: true, className: 'custom-group-class' }, fields: [
25
- { name: 'showTopDivider', type: 'checkbox', label: 'Show Top Divider' },
26
- { name: 'showBottomDivider', type: 'checkbox', label: 'Show Bottom Divider' },
27
- ] },
28
- ],
29
- },
30
- {
31
- name: 'logoImages', type: 'upload', relationTo: 'media', hasMany: true, required: false,
32
- filterOptions: { mimeType: { contains: 'image' } },
33
- hooks: { beforeChange: [({ value, siblingData }) => {
34
- if (!Array.isArray(value) || value.length === 0) return value
35
- const existingLogos = Array.isArray((siblingData as any)?.logos) ? (siblingData as any).logos : []
36
- const normalizeImageId = (imageValue: unknown): number | string | undefined => {
37
- if (typeof imageValue === 'number' || typeof imageValue === 'string') return imageValue
38
- if (imageValue && typeof imageValue === 'object' && 'id' in (imageValue as any)) {
39
- const maybeId = (imageValue as any).id
40
- if (typeof maybeId === 'number' || typeof maybeId === 'string') return maybeId
41
- }
42
- return undefined
43
- }
44
- const existingIds = new Set(existingLogos.map((row: any) => normalizeImageId(row?.image)).filter((id: any) => id !== undefined))
45
- const newRows = value.map((id) => normalizeImageId(id)).filter((id): id is number | string => id !== undefined).filter((id) => !existingIds.has(id)).map((id) => ({ image: id, imageAltClass: 'hidden', imageClass: '' }))
46
- ;(siblingData as any).logos = [...existingLogos, ...newRows]
47
- return []
48
- }] },
49
- },
50
- {
51
- name: 'logos', type: 'array', label: 'Images', labels: { singular: 'Image', plural: 'Images' },
52
- fields: [
53
- { name: 'image', type: 'upload', relationTo: 'media', required: false, filterOptions: { mimeType: { contains: 'image' } } },
54
- { type: 'collapsible', label: 'Alt Text Class', admin: { initCollapsed: true, className: 'custom-css-class' }, fields: [
55
- { name: 'imageAltClass', label: false, type: 'text', required: false, defaultValue: 'hidden' },
56
- ] },
57
- { type: 'collapsible', label: 'Image Class', admin: { initCollapsed: true, className: 'custom-css-class' }, fields: [
58
- { name: 'imageClass', label: false, type: 'text', required: false },
59
- ] },
60
- ],
61
- },
62
- // DDHG TODO: Re-enable custom CSS support after reviewing the CustomCssBlock bundle.
63
- // { name: 'enableCustomCSS', type: 'checkbox', label: 'Inject Custom CSS', defaultValue: false },
64
- // { name: 'customCSS', type: 'blocks', label: 'Custom CSS', blocks: [CustomCSSBlock], maxRows: 1, required: false, admin: { initCollapsed: true, className: 'for-devs-class custom-css-class', condition: (_, siblingData) => Boolean(siblingData.enableCustomCSS) } },
65
- ],
66
- }
1
+ import type { Block } from 'payload'
2
+ // DDHG TODO: Re-enable with the project-specific CustomCssBlock bundle.
3
+ // import { CustomCSSBlock } from '@/blocks/CustomCssBlock/config'
4
+
5
+ export const DDHGLogoMarquee: Block = {
6
+ slug: 'DDHG-LogoMarquee',
7
+ interfaceName: 'DDHGLogoMarquee',
8
+ labels: { singular: 'Image Marquee', plural: 'Image Marquee' },
9
+ fields: [
10
+ {
11
+ name: 'sectionId',
12
+ type: 'text',
13
+ label: 'Section ID',
14
+ required: false,
15
+ admin: { description: 'Optional anchor ID for linking and scroll targets.' },
16
+ },
17
+ {
18
+ type: 'collapsible',
19
+ label: 'Block Settings',
20
+ admin: { initCollapsed: true, className: 'custom-css-class' },
21
+ fields: [
22
+ {
23
+ type: 'collapsible',
24
+ label: 'Container Class',
25
+ admin: { initCollapsed: true, className: 'custom-css-class' },
26
+ fields: [
27
+ {
28
+ name: 'containerClass',
29
+ label: false,
30
+ type: 'text',
31
+ required: false,
32
+ admin: { description: 'Override the default container class.' },
33
+ },
34
+ ],
35
+ },
36
+ {
37
+ type: 'collapsible',
38
+ label: 'Marquee Settings',
39
+ admin: { initCollapsed: true, className: 'custom-group-class' },
40
+ fields: [
41
+ {
42
+ type: 'row',
43
+ fields: [
44
+ {
45
+ name: 'speed',
46
+ type: 'number',
47
+ label: 'Scroll Speed (seconds)',
48
+ defaultValue: 10,
49
+ required: true,
50
+ admin: { width: '50%' },
51
+ },
52
+ {
53
+ name: 'spacing',
54
+ type: 'number',
55
+ label: 'Spacing between images (px)',
56
+ defaultValue: 32,
57
+ required: true,
58
+ admin: { width: '50%' },
59
+ },
60
+ ],
61
+ },
62
+ ],
63
+ },
64
+ { name: 'priority', type: 'checkbox', label: 'High Priority Loading', defaultValue: false },
65
+ {
66
+ type: 'collapsible',
67
+ label: 'Dividers',
68
+ admin: { initCollapsed: true, className: 'custom-group-class' },
69
+ fields: [
70
+ { name: 'showTopDivider', type: 'checkbox', label: 'Show Top Divider' },
71
+ { name: 'showBottomDivider', type: 'checkbox', label: 'Show Bottom Divider' },
72
+ ],
73
+ },
74
+ ],
75
+ },
76
+ {
77
+ name: 'logoImages',
78
+ type: 'upload',
79
+ relationTo: 'media',
80
+ hasMany: true,
81
+ required: false,
82
+ filterOptions: { mimeType: { contains: 'image' } },
83
+ hooks: {
84
+ beforeChange: [
85
+ ({ value, siblingData }) => {
86
+ if (!Array.isArray(value) || value.length === 0) return value
87
+ const existingLogos = Array.isArray((siblingData as any)?.logos)
88
+ ? (siblingData as any).logos
89
+ : []
90
+ const normalizeImageId = (imageValue: unknown): number | string | undefined => {
91
+ if (typeof imageValue === 'number' || typeof imageValue === 'string')
92
+ return imageValue
93
+ if (imageValue && typeof imageValue === 'object' && 'id' in (imageValue as any)) {
94
+ const maybeId = (imageValue as any).id
95
+ if (typeof maybeId === 'number' || typeof maybeId === 'string') return maybeId
96
+ }
97
+ return undefined
98
+ }
99
+ const existingIds = new Set(
100
+ existingLogos
101
+ .map((row: any) => normalizeImageId(row?.image))
102
+ .filter((id: any) => id !== undefined),
103
+ )
104
+ const newRows = value
105
+ .map((id) => normalizeImageId(id))
106
+ .filter((id): id is number | string => id !== undefined)
107
+ .filter((id) => !existingIds.has(id))
108
+ .map((id) => ({ image: id, imageAltClass: 'hidden', imageClass: '' }))
109
+ ;(siblingData as any).logos = [...existingLogos, ...newRows]
110
+ return []
111
+ },
112
+ ],
113
+ },
114
+ },
115
+ {
116
+ name: 'logos',
117
+ type: 'array',
118
+ label: 'Images',
119
+ labels: { singular: 'Image', plural: 'Images' },
120
+ fields: [
121
+ {
122
+ name: 'image',
123
+ type: 'upload',
124
+ relationTo: 'media',
125
+ required: false,
126
+ filterOptions: { mimeType: { contains: 'image' } },
127
+ },
128
+ {
129
+ type: 'collapsible',
130
+ label: 'Alt Text Class',
131
+ admin: { initCollapsed: true, className: 'custom-css-class' },
132
+ fields: [
133
+ {
134
+ name: 'imageAltClass',
135
+ label: false,
136
+ type: 'text',
137
+ required: false,
138
+ defaultValue: 'hidden',
139
+ },
140
+ ],
141
+ },
142
+ {
143
+ type: 'collapsible',
144
+ label: 'Image Class',
145
+ admin: { initCollapsed: true, className: 'custom-css-class' },
146
+ fields: [{ name: 'imageClass', label: false, type: 'text', required: false }],
147
+ },
148
+ ],
149
+ },
150
+ // DDHG TODO: Re-enable custom CSS support after reviewing the CustomCssBlock bundle.
151
+ // { name: 'enableCustomCSS', type: 'checkbox', label: 'Inject Custom CSS', defaultValue: false },
152
+ // { name: 'customCSS', type: 'blocks', label: 'Custom CSS', blocks: [CustomCSSBlock], maxRows: 1, required: false, admin: { initCollapsed: true, className: 'for-devs-class custom-css-class', condition: (_, siblingData) => Boolean(siblingData.enableCustomCSS) } },
153
+ ],
154
+ }