blocks-dusted 0.1.10 → 0.1.12

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 (249) hide show
  1. package/README.md +35 -0
  2. package/package.json +5 -2
  3. package/src/cli.js +39 -3
  4. package/src/commands/shop.js +59 -0
  5. package/src/commands/warehouse.js +73 -0
  6. package/src/utils/paths.js +13 -13
  7. package/templates/blocks/DD-Accordion/Component.tsx +229 -0
  8. package/templates/blocks/DD-Accordion/README.md +3 -0
  9. package/templates/blocks/DD-Accordion/config.ts +73 -0
  10. package/templates/blocks/DD-Accordion/manifest.json +75 -0
  11. package/templates/blocks/DD-AnimText/Component.tsx +788 -0
  12. package/templates/blocks/DD-AnimText/README.md +3 -0
  13. package/templates/blocks/DD-AnimText/config.ts +295 -0
  14. package/templates/blocks/DD-AnimText/manifest.json +85 -0
  15. package/templates/blocks/DD-AsideNav/Component.tsx +321 -0
  16. package/templates/blocks/DD-AsideNav/config.ts +204 -0
  17. package/templates/blocks/DD-AsideNav/manifest.json +80 -0
  18. package/templates/blocks/DD-Banner/Component.tsx +51 -0
  19. package/templates/blocks/DD-Banner/config.ts +57 -0
  20. package/templates/blocks/DD-Banner/manifest.json +72 -0
  21. package/templates/blocks/DD-BgLightning/Component.tsx +44 -0
  22. package/templates/blocks/DD-BgLightning/README.md +3 -0
  23. package/templates/blocks/DD-BgLightning/config.ts +97 -0
  24. package/templates/blocks/DD-BgLightning/manifest.json +79 -0
  25. package/templates/blocks/DD-BookCall/Component.tsx +535 -535
  26. package/templates/blocks/DD-BookCall/config.ts +238 -238
  27. package/templates/blocks/DD-ButtonPop/Component.tsx +117 -0
  28. package/templates/blocks/DD-ButtonPop/config.ts +105 -0
  29. package/templates/blocks/DD-ButtonPop/manifest.json +88 -0
  30. package/templates/blocks/DD-ButtonPop/svg-icons/Dust2.tsx +167 -0
  31. package/templates/blocks/DD-Card/Component.tsx +251 -0
  32. package/templates/blocks/DD-Card/README.md +4 -0
  33. package/templates/blocks/DD-Card/config.ts +154 -0
  34. package/templates/blocks/DD-Card/manifest.json +82 -0
  35. package/templates/blocks/DD-CardTemplate01/Component.tsx +140 -140
  36. package/templates/blocks/DD-CardTemplate01/config.ts +106 -106
  37. package/templates/blocks/DD-Carousel-A/Component.tsx +249 -249
  38. package/templates/blocks/DD-Carousel-B/Component.tsx +403 -403
  39. package/templates/blocks/DD-Chip/Component.tsx +250 -0
  40. package/templates/blocks/DD-Chip/EXAMPLES.md +313 -0
  41. package/templates/blocks/DD-Chip/README.md +202 -0
  42. package/templates/blocks/DD-Chip/config.ts +369 -0
  43. package/templates/blocks/DD-Chip/manifest.json +74 -0
  44. package/templates/blocks/DD-ComparisonTable/Component.tsx +256 -256
  45. package/templates/blocks/DD-Contact/Component.tsx +435 -434
  46. package/templates/blocks/DD-Contact/config.ts +22 -22
  47. package/templates/blocks/DD-Counter/Component.tsx +190 -0
  48. package/templates/blocks/DD-Counter/README.md +4 -0
  49. package/templates/blocks/DD-Counter/config.ts +291 -0
  50. package/templates/blocks/DD-Counter/manifest.json +74 -0
  51. package/templates/blocks/DD-CustomCSS/Component.tsx +8 -0
  52. package/templates/blocks/DD-CustomCSS/README.md +4 -0
  53. package/templates/blocks/DD-CustomCSS/addToLayout.md +5 -0
  54. package/templates/blocks/DD-CustomCSS/config.ts +22 -0
  55. package/templates/blocks/DD-CustomCSS/manifest.json +72 -0
  56. package/templates/blocks/DD-CustomCSS/renderCustomCSS.md +7 -0
  57. package/templates/blocks/DD-FeatCat/Component.tsx +302 -302
  58. package/templates/blocks/DD-FeatCat/config.ts +201 -201
  59. package/templates/blocks/DD-FeatStrip/Component.tsx +585 -585
  60. package/templates/blocks/DD-FeatStrip/config.ts +134 -134
  61. package/templates/blocks/DD-FluidBtn/ButtonsEyeCatching.tsx +628 -0
  62. package/templates/blocks/DD-FluidBtn/Component.tsx +43 -0
  63. package/templates/blocks/DD-FluidBtn/README.md +6 -0
  64. package/templates/blocks/DD-FluidBtn/config.ts +102 -0
  65. package/templates/blocks/DD-FluidBtn/manifest.json +86 -0
  66. package/templates/blocks/DD-GooeyInfo/Component.tsx +149 -0
  67. package/templates/blocks/DD-GooeyInfo/config.ts +135 -0
  68. package/templates/blocks/DD-GooeyInfo/manifest.json +72 -0
  69. package/templates/blocks/DD-Hero/Component.tsx +297 -297
  70. package/templates/blocks/DD-Hero/config.ts +267 -267
  71. package/templates/blocks/DD-HorizontalScroll/Component.tsx +936 -936
  72. package/templates/blocks/DD-HorizontalScroll/config.ts +231 -231
  73. package/templates/blocks/DD-Icon/Component.tsx +287 -0
  74. package/templates/blocks/DD-Icon/README.md +4 -0
  75. package/templates/blocks/DD-Icon/config.ts +258 -0
  76. package/templates/blocks/DD-Icon/hooks/revalidateBlockIds.ts +66 -0
  77. package/templates/blocks/DD-Icon/manifest.json +82 -0
  78. package/templates/blocks/DD-IconButton/Component.tsx +455 -0
  79. package/templates/blocks/DD-IconButton/README.md +326 -0
  80. package/templates/blocks/DD-IconButton/config.ts +239 -0
  81. package/templates/blocks/DD-IconButton/manifest.json +85 -0
  82. package/templates/blocks/DD-IdTag/Component.tsx +21 -0
  83. package/templates/blocks/DD-IdTag/README.md +4 -0
  84. package/templates/blocks/DD-IdTag/config.ts +41 -0
  85. package/templates/blocks/DD-IdTag/manifest.json +72 -0
  86. package/templates/blocks/DD-Iframe/Component.tsx +45 -0
  87. package/templates/blocks/DD-Iframe/README.md +4 -0
  88. package/templates/blocks/DD-Iframe/config.ts +47 -0
  89. package/templates/blocks/DD-Iframe/manifest.json +72 -0
  90. package/templates/blocks/DD-IframeMedia/Component.tsx +133 -0
  91. package/templates/blocks/DD-IframeMedia/README.md +4 -0
  92. package/templates/blocks/DD-IframeMedia/config.ts +79 -0
  93. package/templates/blocks/DD-IframeMedia/manifest.json +72 -0
  94. package/templates/blocks/DD-LineAnim/Component.tsx +36 -0
  95. package/templates/blocks/DD-LineAnim/README.md +4 -0
  96. package/templates/blocks/DD-LineAnim/config.ts +90 -0
  97. package/templates/blocks/DD-LineAnim/manifest.json +80 -0
  98. package/templates/blocks/DD-LinkGrid/Component.tsx +119 -0
  99. package/templates/blocks/DD-LinkGrid/README.md +4 -0
  100. package/templates/blocks/DD-LinkGrid/config.ts +51 -0
  101. package/templates/blocks/DD-LinkGrid/manifest.json +74 -0
  102. package/templates/blocks/DD-LogoMarq/Component.tsx +132 -0
  103. package/templates/blocks/DD-LogoMarq/README.md +4 -0
  104. package/templates/blocks/DD-LogoMarq/config.ts +264 -0
  105. package/templates/blocks/DD-LogoMarq/manifest.json +82 -0
  106. package/templates/blocks/DD-Lottie/Component.tsx +459 -0
  107. package/templates/blocks/DD-Lottie/README.md +4 -0
  108. package/templates/blocks/DD-Lottie/config.ts +379 -0
  109. package/templates/blocks/DD-Lottie/index.tsx +28 -0
  110. package/templates/blocks/DD-Lottie/manifest.json +83 -0
  111. package/templates/blocks/DD-MagicBento/Component.tsx +777 -0
  112. package/templates/blocks/DD-MagicBento/README.md +4 -0
  113. package/templates/blocks/DD-MagicBento/config.ts +264 -0
  114. package/templates/blocks/DD-MagicBento/manifest.json +74 -0
  115. package/templates/blocks/DD-MasonaryMedia/Component.tsx +545 -545
  116. package/templates/blocks/DD-MasonaryMedia/config.ts +2 -2
  117. package/templates/blocks/DD-MasonaryMedia/vendor.d.ts +2 -2
  118. package/templates/blocks/DD-Masonry/Component.tsx +645 -0
  119. package/templates/blocks/DD-Masonry/README.md +4 -0
  120. package/templates/blocks/DD-Masonry/config.ts +475 -0
  121. package/templates/blocks/DD-Masonry/manifest.json +82 -0
  122. package/templates/blocks/DD-Pricing/Component.tsx +2 -5
  123. package/templates/blocks/DD-Process/Component.tsx +2 -4
  124. package/templates/blocks/DD-Process/config.ts +150 -150
  125. package/templates/blocks/DD-Progress/Component.tsx +156 -0
  126. package/templates/blocks/DD-Progress/README.md +4 -0
  127. package/templates/blocks/DD-Progress/config.ts +175 -0
  128. package/templates/blocks/DD-Progress/manifest.json +74 -0
  129. package/templates/blocks/DD-ProjHeader/Component.tsx +91 -0
  130. package/templates/blocks/DD-ProjHeader/README.md +4 -0
  131. package/templates/blocks/DD-ProjHeader/config.ts +96 -0
  132. package/templates/blocks/DD-ProjHeader/manifest.json +72 -0
  133. package/templates/blocks/DD-ProjSlider/Component.tsx +123 -0
  134. package/templates/blocks/DD-ProjSlider/README.md +4 -0
  135. package/templates/blocks/DD-ProjSlider/config.ts +64 -0
  136. package/templates/blocks/DD-ProjSlider/manifest.json +72 -0
  137. package/templates/blocks/DD-ScrollText/Component.tsx +114 -0
  138. package/templates/blocks/DD-ScrollText/README.md +4 -0
  139. package/templates/blocks/DD-ScrollText/config.ts +58 -0
  140. package/templates/blocks/DD-ScrollText/manifest.json +72 -0
  141. package/templates/blocks/DD-Section/Component.tsx +266 -266
  142. package/templates/blocks/DD-Separator/Component.tsx +66 -0
  143. package/templates/blocks/DD-Separator/README.md +4 -0
  144. package/templates/blocks/DD-Separator/config.ts +58 -0
  145. package/templates/blocks/DD-Separator/manifest.json +72 -0
  146. package/templates/blocks/DD-Services/Component.tsx +176 -176
  147. package/templates/blocks/DD-Services/config.ts +149 -149
  148. package/templates/blocks/DD-ShowcaseGrid/Component.tsx +307 -307
  149. package/templates/blocks/DD-Slider-A/Component.tsx +1 -1
  150. package/templates/blocks/DD-StackCards/Component.tsx +1 -1
  151. package/templates/blocks/DD-StackCards/config.ts +399 -399
  152. package/templates/blocks/DD-Team/Component.tsx +247 -247
  153. package/templates/blocks/DD-Team/config.ts +173 -173
  154. package/templates/blocks/DD-TeamCards/Component.tsx +251 -0
  155. package/templates/blocks/DD-TeamCards/README.md +4 -0
  156. package/templates/blocks/DD-TeamCards/config.ts +302 -0
  157. package/templates/blocks/DD-TeamCards/manifest.json +74 -0
  158. package/templates/blocks/DD-TechStack/Component.tsx +174 -174
  159. package/templates/blocks/DD-TechStack/config.ts +153 -153
  160. package/templates/blocks/DD-TestMarq/Component.tsx +132 -0
  161. package/templates/blocks/DD-TestMarq/README.md +4 -0
  162. package/templates/blocks/DD-TestMarq/RowLabel.tsx +9 -0
  163. package/templates/blocks/DD-TestMarq/config.ts +88 -0
  164. package/templates/blocks/DD-TestMarq/manifest.json +72 -0
  165. package/templates/blocks/DD-Testim/Component.tsx +247 -0
  166. package/templates/blocks/DD-Testim/README.md +4 -0
  167. package/templates/blocks/DD-Testim/config.ts +101 -0
  168. package/templates/blocks/DD-Testim/manifest.json +75 -0
  169. package/templates/blocks/DD-Testim2/Component.tsx +256 -0
  170. package/templates/blocks/DD-Testim2/README.md +4 -0
  171. package/templates/blocks/DD-Testim2/config.ts +100 -0
  172. package/templates/blocks/DD-Testim2/manifest.json +74 -0
  173. package/templates/blocks/DD-Testimonials/Component.tsx +139 -147
  174. package/templates/blocks/DD-Testimonials/config.ts +120 -120
  175. package/templates/blocks/DD-TextMarq/Component.tsx +157 -0
  176. package/templates/blocks/DD-TextMarq/README.md +4 -0
  177. package/templates/blocks/DD-TextMarq/config.ts +237 -0
  178. package/templates/blocks/DD-TextMarq/manifest.json +82 -0
  179. package/templates/blocks/DD-Thanks/Component.tsx +501 -0
  180. package/templates/blocks/DD-Thanks/README.md +4 -0
  181. package/templates/blocks/DD-Thanks/config.ts +224 -0
  182. package/templates/blocks/DD-Thanks/manifest.json +72 -0
  183. package/templates/blocks/DD-VertMarq/Component.tsx +154 -0
  184. package/templates/blocks/DD-VertMarq/README.md +4 -0
  185. package/templates/blocks/DD-VertMarq/config.ts +236 -0
  186. package/templates/blocks/DD-VertMarq/dist/index.css +6 -0
  187. package/templates/blocks/DD-VertMarq/dist/index.min.css +1 -0
  188. package/templates/blocks/DD-VertMarq/manifest.json +74 -0
  189. package/templates/blocks/DD-Work/Component.tsx +318 -315
  190. package/templates/blocks/DD-Work/config.ts +165 -165
  191. package/templates/blocks/DD-Work-B/Component.tsx +294 -294
  192. package/templates/blocks/DDHG-CTASection2/Component.tsx +185 -0
  193. package/templates/blocks/DDHG-CTASection2/config.ts +140 -0
  194. package/templates/blocks/DDHG-CTASection2/manifest.json +45 -0
  195. package/templates/blocks/DDHG-HighlightArc/Component.tsx +243 -0
  196. package/templates/blocks/DDHG-HighlightArc/config.ts +85 -0
  197. package/templates/blocks/DDHG-HighlightArc/manifest.json +46 -0
  198. package/templates/blocks/DDHG-LogoMarquee/Component.tsx +143 -0
  199. package/templates/blocks/DDHG-LogoMarquee/config.ts +154 -0
  200. package/templates/blocks/DDHG-LogoMarquee/manifest.json +39 -0
  201. package/templates/blocks/DDHG-NavCodeGrid/Component.tsx +227 -0
  202. package/templates/blocks/DDHG-NavCodeGrid/config.ts +64 -0
  203. package/templates/blocks/DDHG-NavCodeGrid/manifest.json +45 -0
  204. package/templates/blocks/DDHG-ProcessSec/Component.tsx +574 -0
  205. package/templates/blocks/DDHG-ProcessSec/config.ts +170 -0
  206. package/templates/blocks/DDHG-ProcessSec/manifest.json +56 -0
  207. package/templates/blocks/DDHG-ServiceDetails/Component.tsx +164 -0
  208. package/templates/blocks/DDHG-ServiceDetails/ServiceDetailCard.tsx +390 -0
  209. package/templates/blocks/DDHG-ServiceDetails/config.ts +77 -0
  210. package/templates/blocks/DDHG-ServiceDetails/manifest.json +50 -0
  211. package/templates/blocks/DDHG-ServiceHero/Component.tsx +234 -0
  212. package/templates/blocks/DDHG-ServiceHero/config.ts +49 -0
  213. package/templates/blocks/DDHG-ServiceHero/manifest.json +26 -0
  214. package/templates/blocks/DDHG-ServiceOverview/Component.tsx +277 -0
  215. package/templates/blocks/DDHG-ServiceOverview/config.ts +64 -0
  216. package/templates/blocks/DDHG-ServiceOverview/manifest.json +44 -0
  217. package/templates/blocks/DDHG-StatsFAQ/Component.tsx +389 -0
  218. package/templates/blocks/DDHG-StatsFAQ/config.ts +204 -0
  219. package/templates/blocks/DDHG-StatsFAQ/manifest.json +45 -0
  220. package/templates/blocks/DDHG-TeamCards/Component.tsx +169 -0
  221. package/templates/blocks/DDHG-TeamCards/config.ts +48 -0
  222. package/templates/blocks/DDHG-TeamCards/manifest.json +29 -0
  223. package/templates/shared/src/components/BgLightning/index.tsx +242 -0
  224. package/templates/shared/src/components/ui/ShareButton/index.tsx +80 -0
  225. package/templates/shared/src/components/ui/anims/FadeOnScroll.tsx +48 -0
  226. package/templates/shared/src/components/ui/anims/FadeUpOnInView.tsx +63 -0
  227. package/templates/shared/src/components/ui/anims/GlareHover.tsx +111 -0
  228. package/templates/shared/src/components/ui/anims/LineAnims.tsx +81 -0
  229. package/templates/shared/src/components/ui/anims/TitleAnims01.tsx +54 -0
  230. package/templates/shared/src/components/ui/anims/animation-container.tsx +29 -0
  231. package/templates/shared/src/components/ui/anims/blur-in.tsx +26 -0
  232. package/templates/shared/src/components/ui/anims/counter.tsx +53 -0
  233. package/templates/shared/src/components/ui/anims/fade.tsx +83 -0
  234. package/templates/shared/src/components/ui/anims/gradual-spacing.tsx +39 -0
  235. package/templates/shared/src/components/ui/anims/pull-up.tsx +93 -0
  236. package/templates/shared/src/components/ui/anims/reveal-text.tsx +76 -0
  237. package/templates/shared/src/components/ui/anims/rotate-words.tsx +43 -0
  238. package/templates/shared/src/components/ui/anims/shiny-text.tsx +58 -0
  239. package/templates/shared/src/components/ui/anims/shuffle-text.tsx +85 -0
  240. package/templates/shared/src/components/ui/anims/split-text.tsx +211 -0
  241. package/templates/shared/src/components/ui/anims/staggered-fade.tsx +133 -0
  242. package/templates/shared/src/components/ui/anims/text-scroll.tsx +111 -0
  243. package/templates/shared/src/components/ui/anims/typing-effect.tsx +112 -0
  244. package/templates/shared/src/components/ui/button-dusted-fluid/index.tsx +1521 -0
  245. package/templates/shared/src/components/ui/separator.tsx +85 -0
  246. package/templates/shared/src/hooks/useBodyScrollLock.ts +97 -0
  247. package/templates/shared/src/hooks/useClickOutside.ts +28 -0
  248. package/templates/shared/src/utilities/renderCustomCSS.ts +5 -0
  249. package/templates/shared/src/utilities/smoothScroll.ts +65 -0
@@ -1,256 +1,256 @@
1
- 'use client'
2
-
3
- import React, { Fragment, useState } from 'react'
4
- import { Check, Minus, Plus } from 'lucide-react'
5
-
6
- type TierKey = 'free' | 'pro' | 'team'
7
-
8
- type CellValue = boolean | string
9
-
10
- interface FeatureRow {
11
- id?: string | null
12
- label?: string | null
13
- free?: CellValue | null
14
- pro?: CellValue | null
15
- team?: CellValue | null
16
- }
17
-
18
- interface FeatureGroup {
19
- id?: string | null
20
- group?: string | null
21
- rows?: FeatureRow[] | null
22
- }
23
-
24
- interface TierHeader {
25
- key: TierKey
26
- label: string
27
- highlight: boolean
28
- }
29
-
30
- interface StudioComparisonTableProps {
31
- eyebrow?: string | null
32
- heading?: string | null
33
- defaultOpen?: boolean | null
34
- groups?: FeatureGroup[] | null
35
- sectionId?: string | null
36
- customCSS?: string | null
37
- [key: string]: unknown
38
- }
39
-
40
- const DEFAULT_GROUPS: FeatureGroup[] = [
41
- {
42
- group: 'Components & Templates',
43
- rows: [
44
- { label: 'Free components', free: true, pro: true, team: true },
45
- { label: 'Premium components', free: false, pro: '120+', team: '120+' },
46
- { label: 'Free templates', free: true, pro: true, team: true },
47
- { label: 'Premium templates', free: false, pro: '24+', team: '24+' },
48
- { label: 'Payload CMS v3 blocks', free: false, pro: true, team: true },
49
- { label: 'Figma source files', free: false, pro: true, team: true },
50
- ],
51
- },
52
- {
53
- group: 'Licensing',
54
- rows: [
55
- { label: 'Personal use', free: true, pro: true, team: true },
56
- {
57
- label: 'Commercial projects',
58
- free: false,
59
- pro: '1 project',
60
- team: 'Unlimited',
61
- },
62
- { label: 'White-label license', free: false, pro: false, team: true },
63
- { label: 'Client resale rights', free: false, pro: false, team: true },
64
- ],
65
- },
66
- {
67
- group: 'Updates & Access',
68
- rows: [
69
- { label: 'Lifetime updates', free: true, pro: true, team: true },
70
- {
71
- label: 'Early access to new releases',
72
- free: false,
73
- pro: true,
74
- team: true,
75
- },
76
- { label: 'Download source files', free: false, pro: true, team: true },
77
- ],
78
- },
79
- {
80
- group: 'Support',
81
- rows: [
82
- { label: 'Community Discord', free: true, pro: true, team: true },
83
- { label: 'Priority email support', free: false, pro: true, team: true },
84
- { label: 'Dedicated Slack channel', free: false, pro: false, team: true },
85
- { label: '1-on-1 onboarding call', free: false, pro: false, team: true },
86
- { label: 'SLA support guarantee', free: false, pro: false, team: true },
87
- ],
88
- },
89
- {
90
- group: 'Team',
91
- rows: [
92
- { label: 'Team seats', free: '1', pro: '1', team: 'Up to 10' },
93
- {
94
- label: 'Invoice & billing management',
95
- free: false,
96
- pro: false,
97
- team: true,
98
- },
99
- {
100
- label: 'Custom Payload CMS schemas',
101
- free: false,
102
- pro: false,
103
- team: true,
104
- },
105
- ],
106
- },
107
- ]
108
-
109
- function Cell({ value, highlight }: { value: CellValue | null | undefined; highlight: boolean }) {
110
- if (typeof value === 'string') {
111
- return (
112
- <span
113
- className={`text-sm font-medium ${highlight ? 'text-indigo-900 dark:text-lime-400' : 'text-stone-700 dark:text-stone-300'}`}
114
- >
115
- {value}
116
- </span>
117
- )
118
- }
119
-
120
- if (value === true) {
121
- return (
122
- <div
123
- className={`mx-auto flex h-5 w-5 items-center justify-center rounded-full ${
124
- highlight ? 'bg-stone-900' : 'bg-stone-800'
125
- }`}
126
- style={{ cornerShape: 'squircle' } as React.CSSProperties}
127
- >
128
- <Check className={`h-3 w-3 ${highlight ? 'text-stone-50' : 'text-stone-300'}`} />
129
- </div>
130
- )
131
- }
132
-
133
- return (
134
- <div className="mx-auto flex h-5 w-5 items-center justify-center opacity-30">
135
- <Minus className="h-4 w-4 text-stone-600" />
136
- </div>
137
- )
138
- }
139
-
140
- export function DDComparisonTable({
141
- eyebrow = 'Full breakdown',
142
- heading = 'Compare all features',
143
- defaultOpen = true,
144
- groups,
145
- sectionId,
146
- }: StudioComparisonTableProps) {
147
- const [open, setOpen] = useState(defaultOpen !== false)
148
- const featureGroups = groups && groups.length > 0 ? groups : DEFAULT_GROUPS
149
-
150
- const tiers: TierHeader[] = [
151
- { key: 'free', label: 'Free', highlight: false },
152
- { key: 'pro', label: 'Pro', highlight: true },
153
- { key: 'team', label: 'Team', highlight: false },
154
- ]
155
-
156
- return (
157
- <section
158
- id={sectionId ?? undefined}
159
- className="studio-comparison-table border-t border-stone-800 bg-transparent px-6 py-20"
160
- >
161
- <div className="mx-auto max-w-6xl">
162
- #BlockName-DDComparisonTable
163
- <button
164
- type="button"
165
- onClick={() => setOpen((current) => !current)}
166
- className="group mb-8 flex w-full cursor-pointer items-center justify-between gap-6 text-left"
167
- >
168
- <div>
169
- {eyebrow && (
170
- <p className="mb-1 text-xs font-semibold uppercase tracking-widest text-stone-500">
171
- {eyebrow}
172
- </p>
173
- )}
174
- {heading && (
175
- <h2 className="text-3xl font-semibold text-stone-900 dark:text-stone-50">
176
- {heading}
177
- </h2>
178
- )}
179
- </div>
180
-
181
- <div
182
- className="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl border border-stone-100 bg-stone-200 dark:border-stone-700 dark:bg-stone-800 transition-colors group-hover:border-stone-300 dark:group-hover:border-stone-500"
183
- style={{ cornerShape: 'squircle' } as React.CSSProperties}
184
- >
185
- {open ? (
186
- <Minus className="h-4 w-4 text-stone-700 dark:text-stone-400 transition-transform duration-300" />
187
- ) : (
188
- <Plus className="h-4 w-4 text-stone-700 dark:text-stone-300 transition-transform duration-300" />
189
- )}
190
- </div>
191
- </button>
192
-
193
- {open && (
194
- <div className="overflow-x-auto">
195
- <table className="w-full min-w-160">
196
- <thead>
197
- <tr>
198
- <th className="w-1/2 pb-0 text-left" />
199
- {tiers.map((tier) => (
200
- <th key={tier.key} className="pb-0 text-center">
201
- <span
202
- className={`inline-block rounded-lg px-4 py-1.5 text-sm font-semibold ${
203
- tier.highlight
204
- ? 'bg-stone-100 text-stone-900'
205
- : 'border-stone-100 bg-stone-200 dark:border-stone-700 dark:bg-stone-800/50 transition-colors group-hover:border-stone-300 dark:group-hover:border-stone-500'
206
- }`}
207
- style={{ cornerShape: 'squircle' } as React.CSSProperties}
208
- >
209
- {tier.label}
210
- </span>
211
- </th>
212
- ))}
213
- </tr>
214
- </thead>
215
-
216
- <tbody>
217
- {featureGroups.map((group, groupIndex) => (
218
- <Fragment key={group.id ?? group.group ?? groupIndex}>
219
- <tr>
220
- <td colSpan={4} className="pb-3 pt-0">
221
- <span className="text-xs font-bold uppercase tracking-widest text-stone-500">
222
- {group.group}
223
- </span>
224
- </td>
225
- </tr>
226
-
227
- {(group.rows ?? []).map((row, rowIndex) => (
228
- <tr
229
- key={row.id ?? row.label ?? rowIndex}
230
- className={`border-t transition-colors hover:bg-stone-200/40 dark:hover:bg-stone-900/40 ${
231
- rowIndex === 0 ? 'border-stone-800' : 'border-stone-800/50'
232
- }`}
233
- >
234
- <td className="py-3.5 pr-6">
235
- <span className="text-sm text-stone-400">{row.label}</span>
236
- </td>
237
-
238
- {tiers.map((tier) => (
239
- <td key={tier.key} className="py-3.5 text-center">
240
- <Cell value={row[tier.key]} highlight={tier.highlight} />
241
- </td>
242
- ))}
243
- </tr>
244
- ))}
245
- </Fragment>
246
- ))}
247
- </tbody>
248
- </table>
249
- </div>
250
- )}
251
- </div>
252
- </section>
253
- )
254
- }
255
-
256
- export default DDComparisonTable
1
+ 'use client'
2
+
3
+ import React, { Fragment, useState } from 'react'
4
+ import { Check, Minus, Plus } from 'lucide-react'
5
+
6
+ type TierKey = 'free' | 'pro' | 'team'
7
+
8
+ type CellValue = boolean | string
9
+
10
+ interface FeatureRow {
11
+ id?: string | null
12
+ label?: string | null
13
+ free?: CellValue | null
14
+ pro?: CellValue | null
15
+ team?: CellValue | null
16
+ }
17
+
18
+ interface FeatureGroup {
19
+ id?: string | null
20
+ group?: string | null
21
+ rows?: FeatureRow[] | null
22
+ }
23
+
24
+ interface TierHeader {
25
+ key: TierKey
26
+ label: string
27
+ highlight: boolean
28
+ }
29
+
30
+ interface StudioComparisonTableProps {
31
+ eyebrow?: string | null
32
+ heading?: string | null
33
+ defaultOpen?: boolean | null
34
+ groups?: FeatureGroup[] | null
35
+ sectionId?: string | null
36
+ customCSS?: string | null
37
+ [key: string]: unknown
38
+ }
39
+
40
+ const DEFAULT_GROUPS: FeatureGroup[] = [
41
+ {
42
+ group: 'Components & Templates',
43
+ rows: [
44
+ { label: 'Free components', free: true, pro: true, team: true },
45
+ { label: 'Premium components', free: false, pro: '120+', team: '120+' },
46
+ { label: 'Free templates', free: true, pro: true, team: true },
47
+ { label: 'Premium templates', free: false, pro: '24+', team: '24+' },
48
+ { label: 'Payload CMS v3 blocks', free: false, pro: true, team: true },
49
+ { label: 'Figma source files', free: false, pro: true, team: true },
50
+ ],
51
+ },
52
+ {
53
+ group: 'Licensing',
54
+ rows: [
55
+ { label: 'Personal use', free: true, pro: true, team: true },
56
+ {
57
+ label: 'Commercial projects',
58
+ free: false,
59
+ pro: '1 project',
60
+ team: 'Unlimited',
61
+ },
62
+ { label: 'White-label license', free: false, pro: false, team: true },
63
+ { label: 'Client resale rights', free: false, pro: false, team: true },
64
+ ],
65
+ },
66
+ {
67
+ group: 'Updates & Access',
68
+ rows: [
69
+ { label: 'Lifetime updates', free: true, pro: true, team: true },
70
+ {
71
+ label: 'Early access to new releases',
72
+ free: false,
73
+ pro: true,
74
+ team: true,
75
+ },
76
+ { label: 'Download source files', free: false, pro: true, team: true },
77
+ ],
78
+ },
79
+ {
80
+ group: 'Support',
81
+ rows: [
82
+ { label: 'Community Discord', free: true, pro: true, team: true },
83
+ { label: 'Priority email support', free: false, pro: true, team: true },
84
+ { label: 'Dedicated Slack channel', free: false, pro: false, team: true },
85
+ { label: '1-on-1 onboarding call', free: false, pro: false, team: true },
86
+ { label: 'SLA support guarantee', free: false, pro: false, team: true },
87
+ ],
88
+ },
89
+ {
90
+ group: 'Team',
91
+ rows: [
92
+ { label: 'Team seats', free: '1', pro: '1', team: 'Up to 10' },
93
+ {
94
+ label: 'Invoice & billing management',
95
+ free: false,
96
+ pro: false,
97
+ team: true,
98
+ },
99
+ {
100
+ label: 'Custom Payload CMS schemas',
101
+ free: false,
102
+ pro: false,
103
+ team: true,
104
+ },
105
+ ],
106
+ },
107
+ ]
108
+
109
+ function Cell({ value, highlight }: { value: CellValue | null | undefined; highlight: boolean }) {
110
+ if (typeof value === 'string') {
111
+ return (
112
+ <span
113
+ className={`text-sm font-medium ${highlight ? 'text-indigo-900 dark:text-lime-400' : 'text-stone-700 dark:text-stone-300'}`}
114
+ >
115
+ {value}
116
+ </span>
117
+ )
118
+ }
119
+
120
+ if (value === true) {
121
+ return (
122
+ <div
123
+ className={`mx-auto flex h-5 w-5 items-center justify-center rounded-full ${
124
+ highlight ? 'bg-stone-900' : 'bg-stone-800'
125
+ }`}
126
+ style={{ cornerShape: 'squircle' } as React.CSSProperties}
127
+ >
128
+ <Check className={`h-3 w-3 ${highlight ? 'text-stone-50' : 'text-stone-300'}`} />
129
+ </div>
130
+ )
131
+ }
132
+
133
+ return (
134
+ <div className="mx-auto flex h-5 w-5 items-center justify-center opacity-30">
135
+ <Minus className="h-4 w-4 text-stone-600" />
136
+ </div>
137
+ )
138
+ }
139
+
140
+ export function DDComparisonTable({
141
+ eyebrow = 'Full breakdown',
142
+ heading = 'Compare all features',
143
+ defaultOpen = true,
144
+ groups,
145
+ sectionId,
146
+ }: StudioComparisonTableProps) {
147
+ const [open, setOpen] = useState(defaultOpen !== false)
148
+ const featureGroups = groups && groups.length > 0 ? groups : DEFAULT_GROUPS
149
+
150
+ const tiers: TierHeader[] = [
151
+ { key: 'free', label: 'Free', highlight: false },
152
+ { key: 'pro', label: 'Pro', highlight: true },
153
+ { key: 'team', label: 'Team', highlight: false },
154
+ ]
155
+
156
+ return (
157
+ <section
158
+ id={sectionId ?? undefined}
159
+ className="studio-comparison-table border-t border-stone-800 bg-transparent px-6 py-20"
160
+ >
161
+ <div className="mx-auto max-w-6xl">
162
+ #BlockName-DDComparisonTable
163
+ <button
164
+ type="button"
165
+ onClick={() => setOpen((current) => !current)}
166
+ className="group mb-8 flex w-full cursor-pointer items-center justify-between gap-6 text-left"
167
+ >
168
+ <div>
169
+ {eyebrow && (
170
+ <p className="mb-1 text-xs font-semibold uppercase tracking-widest text-stone-500">
171
+ {eyebrow}
172
+ </p>
173
+ )}
174
+ {heading && (
175
+ <h2 className="text-3xl font-semibold text-stone-900 dark:text-stone-50">
176
+ {heading}
177
+ </h2>
178
+ )}
179
+ </div>
180
+
181
+ <div
182
+ className="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl border border-stone-100 bg-stone-200 dark:border-stone-700 dark:bg-stone-800 transition-colors group-hover:border-stone-300 dark:group-hover:border-stone-500"
183
+ style={{ cornerShape: 'squircle' } as React.CSSProperties}
184
+ >
185
+ {open ? (
186
+ <Minus className="h-4 w-4 text-stone-700 dark:text-stone-400 transition-transform duration-300" />
187
+ ) : (
188
+ <Plus className="h-4 w-4 text-stone-700 dark:text-stone-300 transition-transform duration-300" />
189
+ )}
190
+ </div>
191
+ </button>
192
+
193
+ {open && (
194
+ <div className="overflow-x-auto">
195
+ <table className="w-full min-w-160">
196
+ <thead>
197
+ <tr>
198
+ <th className="w-1/2 pb-0 text-left" />
199
+ {tiers.map((tier) => (
200
+ <th key={tier.key} className="pb-0 text-center">
201
+ <span
202
+ className={`inline-block rounded-lg px-4 py-1.5 text-sm font-semibold ${
203
+ tier.highlight
204
+ ? 'bg-stone-100 text-stone-900'
205
+ : 'border-stone-100 bg-stone-200 dark:border-stone-700 dark:bg-stone-800/50 transition-colors group-hover:border-stone-300 dark:group-hover:border-stone-500'
206
+ }`}
207
+ style={{ cornerShape: 'squircle' } as React.CSSProperties}
208
+ >
209
+ {tier.label}
210
+ </span>
211
+ </th>
212
+ ))}
213
+ </tr>
214
+ </thead>
215
+
216
+ <tbody>
217
+ {featureGroups.map((group, groupIndex) => (
218
+ <Fragment key={group.id ?? group.group ?? groupIndex}>
219
+ <tr>
220
+ <td colSpan={4} className="pb-3 pt-0">
221
+ <span className="text-xs font-bold uppercase tracking-widest text-stone-500">
222
+ {group.group}
223
+ </span>
224
+ </td>
225
+ </tr>
226
+
227
+ {(group.rows ?? []).map((row, rowIndex) => (
228
+ <tr
229
+ key={row.id ?? row.label ?? rowIndex}
230
+ className={`border-t transition-colors hover:bg-stone-200/40 dark:hover:bg-stone-900/40 ${
231
+ rowIndex === 0 ? 'border-stone-800' : 'border-stone-800/50'
232
+ }`}
233
+ >
234
+ <td className="py-3.5 pr-6">
235
+ <span className="text-sm text-stone-400">{row.label}</span>
236
+ </td>
237
+
238
+ {tiers.map((tier) => (
239
+ <td key={tier.key} className="py-3.5 text-center">
240
+ <Cell value={row[tier.key]} highlight={tier.highlight} />
241
+ </td>
242
+ ))}
243
+ </tr>
244
+ ))}
245
+ </Fragment>
246
+ ))}
247
+ </tbody>
248
+ </table>
249
+ </div>
250
+ )}
251
+ </div>
252
+ </section>
253
+ )
254
+ }
255
+
256
+ export default DDComparisonTable