blocks-dusted 0.1.11 → 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 (46) 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/templates/blocks/DD-BookCall/Component.tsx +535 -534
  6. package/templates/blocks/DD-CardTemplate01/Component.tsx +140 -139
  7. package/templates/blocks/DD-Carousel-A/Component.tsx +1 -1
  8. package/templates/blocks/DD-Carousel-B/Component.tsx +1 -1
  9. package/templates/blocks/DD-Chip/Component.tsx +14 -14
  10. package/templates/blocks/DD-ComparisonTable/Component.tsx +1 -1
  11. package/templates/blocks/DD-Contact/Component.tsx +8 -7
  12. package/templates/blocks/DD-Counter/Component.tsx +10 -10
  13. package/templates/blocks/DD-FeatCat/Component.tsx +1 -1
  14. package/templates/blocks/DD-FeatStrip/Component.tsx +1 -1
  15. package/templates/blocks/DD-Hero/Component.tsx +297 -320
  16. package/templates/blocks/DD-HorizontalScroll/Component.tsx +936 -938
  17. package/templates/blocks/DD-IframeMedia/Component.tsx +14 -10
  18. package/templates/blocks/DD-MasonaryMedia/Component.tsx +8 -10
  19. package/templates/blocks/DD-Pricing/Component.tsx +369 -372
  20. package/templates/blocks/DD-Process/Component.tsx +147 -149
  21. package/templates/blocks/DD-Progress/Component.tsx +156 -141
  22. package/templates/blocks/DD-ProjSlider/config.ts +2 -2
  23. package/templates/blocks/DD-Section/Component.tsx +1 -1
  24. package/templates/blocks/DD-Services/Component.tsx +1 -1
  25. package/templates/blocks/DD-ShowcaseGrid/Component.tsx +13 -13
  26. package/templates/blocks/DD-Slider-A/Component.tsx +237 -237
  27. package/templates/blocks/DD-StackCards/Component.tsx +473 -473
  28. package/templates/blocks/DD-Team/Component.tsx +1 -1
  29. package/templates/blocks/DD-TechStack/Component.tsx +22 -28
  30. package/templates/blocks/DD-Testimonials/Component.tsx +35 -43
  31. package/templates/blocks/DD-TextMarq/Component.tsx +157 -157
  32. package/templates/blocks/DD-Thanks/Component.tsx +501 -500
  33. package/templates/blocks/DD-Work/Component.tsx +4 -4
  34. package/templates/blocks/DD-Work-B/Component.tsx +1 -1
  35. package/templates/blocks/DDHG-CTASection2/Component.tsx +6 -6
  36. package/templates/blocks/DDHG-HighlightArc/Component.tsx +243 -243
  37. package/templates/blocks/DDHG-LogoMarquee/Component.tsx +143 -93
  38. package/templates/blocks/DDHG-LogoMarquee/config.ts +154 -66
  39. package/templates/blocks/DDHG-NavCodeGrid/Component.tsx +227 -213
  40. package/templates/blocks/DDHG-ProcessSec/Component.tsx +38 -39
  41. package/templates/blocks/DDHG-ServiceDetails/Component.tsx +11 -11
  42. package/templates/blocks/DDHG-ServiceDetails/ServiceDetailCard.tsx +24 -28
  43. package/templates/blocks/DDHG-ServiceHero/Component.tsx +1 -1
  44. package/templates/blocks/DDHG-ServiceOverview/Component.tsx +23 -23
  45. package/templates/blocks/DDHG-StatsFAQ/Component.tsx +40 -40
  46. package/templates/blocks/DDHG-TeamCards/Component.tsx +169 -131
@@ -1,213 +1,227 @@
1
- 'use client'
2
-
3
- import Image from 'next/image'
4
- import Link from 'next/link'
5
- import * as LucideIcons from 'lucide-react'
6
- import React from 'react'
7
-
8
- import { getMediaUrl } from '@/utilities/getMediaUrl'
9
- import { cn } from '@/utilities/ui'
10
-
11
- type PortableDoc = {
12
- slug?: string | null
13
- breadcrumbs?: Array<{ url?: string | null }> | null
14
- [key: string]: unknown
15
- }
16
-
17
- type Media = {
18
- url?: string | null
19
- alt?: string | null
20
- [key: string]: unknown
21
- }
22
-
23
- type LinkReference =
24
- | { relationTo: 'pages'; value: number | PortableDoc }
25
- | { relationTo: 'posts'; value: number | PortableDoc }
26
- | { relationTo: 'projects'; value: number | PortableDoc }
27
- | { relationTo: 'thoughts'; value: number | PortableDoc }
28
-
29
- type NavCodeGridLink = {
30
- type?: 'reference' | 'custom' | null
31
- reference?: LinkReference | null
32
- url?: string | null
33
- label?: string | null
34
- newTab?: boolean | null
35
- icon?: string | null
36
- iconPosition?: 'before' | 'after' | null
37
- customIcon?: number | Media | null
38
- } | null
39
-
40
- export type DDHGNavCodeGridItem = {
41
- id?: string | null
42
- code?: string | null
43
- link?: NavCodeGridLink
44
- }
45
-
46
- export type DDHGNavCodeGridProps = {
47
- items?: DDHGNavCodeGridItem[] | null
48
- defaultHref?: string | null
49
- containerClassName?: string | null
50
- gridClassName?: string | null
51
- cellClassName?: string | null
52
- showIcons?: boolean | null
53
- }
54
-
55
- const getPageURLFromDoc = (doc: PortableDoc | number): string | null => {
56
- if (typeof doc === 'number') return null
57
- const crumbs = Array.isArray(doc?.breadcrumbs) ? doc.breadcrumbs : []
58
- if (crumbs.length) {
59
- const last = crumbs[crumbs.length - 1]
60
- if (typeof last?.url === 'string' && last.url) return last.url
61
- }
62
- const slug = doc?.slug
63
- if (!slug || slug === 'home') return '/'
64
- return slug.startsWith('/') ? slug : `/${slug}`
65
- }
66
-
67
- const getDocumentSlug = (doc: PortableDoc | number): string | null => {
68
- if (typeof doc === 'number') return null
69
- return doc?.slug || null
70
- }
71
-
72
- const getCollectionPath = (relationTo: LinkReference['relationTo']): string => {
73
- if (relationTo === 'posts') return 'internal-docs'
74
- if (relationTo === 'thoughts') return 'thoughts'
75
- if (relationTo === 'projects') return 'archives'
76
- return ''
77
- }
78
-
79
- const isExternalUrl = (href: string): boolean =>
80
- href.startsWith('http://') ||
81
- href.startsWith('https://') ||
82
- href.startsWith('mailto:') ||
83
- href.startsWith('tel:')
84
-
85
- const resolveHref = (link: NavCodeGridLink, defaultHref = '/archive'): string => {
86
- if (!link) return defaultHref
87
- if (link.type === 'custom' && link.url) return link.url
88
- if (link.type === 'reference' && link.reference?.value) {
89
- const { relationTo, value } = link.reference
90
- if (relationTo === 'pages') return getPageURLFromDoc(value) || defaultHref
91
- const slug = getDocumentSlug(value)
92
- if (!slug) return defaultHref
93
- const basePath = getCollectionPath(relationTo)
94
- return basePath ? `/${basePath}/${slug}` : `/${slug}`
95
- }
96
- return defaultHref
97
- }
98
-
99
- const renderIcon = (link: NavCodeGridLink, showIcons = true) => {
100
- if (!showIcons || !link) return null
101
-
102
- if (link.customIcon && typeof link.customIcon === 'object') {
103
- const iconUrl = getMediaUrl(link.customIcon.url)
104
- if (iconUrl) {
105
- return (
106
- <span className="inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center overflow-hidden">
107
- <Image
108
- src={iconUrl}
109
- alt={link.customIcon.alt || ''}
110
- width={14}
111
- height={14}
112
- className="m-0 block h-full w-full object-contain"
113
- />
114
- </span>
115
- )
116
- }
117
- }
118
-
119
- if (link.icon) {
120
- const LucideIcon = LucideIcons[link.icon as keyof typeof LucideIcons] as
121
- | React.ComponentType<{ className?: string }>
122
- | undefined
123
- if (LucideIcon) {
124
- return (
125
- <span className="inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center">
126
- <LucideIcon className="h-3.5 w-3.5" />
127
- </span>
128
- )
129
- }
130
- }
131
-
132
- return null
133
- }
134
-
135
- const getDelayClass = (index: number) => {
136
- const delay = Math.min(index * 40, 320)
137
- return `[transition-delay:${delay}ms]`
138
- }
139
-
140
- export const DDHGNavCodeGrid: React.FC<DDHGNavCodeGridProps> = ({
141
- items,
142
- defaultHref = '/archive',
143
- containerClassName,
144
- gridClassName,
145
- cellClassName,
146
- showIcons = true,
147
- }) => {
148
- if (!Array.isArray(items) || items.length === 0) return null
149
-
150
- return (
151
- <div className={cn('w-full', containerClassName)}>
152
- <div className={cn('grid grid-cols-2 border border-border sm:grid-cols-4 !gap-0', gridClassName)}>
153
- {items.map((item, index) => {
154
- const link = item.link || null
155
- const href = resolveHref(link, defaultHref || '/archive')
156
- const label = link?.label || item.code || 'Archive'
157
- const icon = renderIcon(link, Boolean(showIcons))
158
- const iconPosition = link?.iconPosition || 'before'
159
- const target = link?.newTab ? '_blank' : undefined
160
- const rel = link?.newTab ? 'noopener noreferrer' : undefined
161
- const className = cn(
162
- 'menu-cell-hover group bg-transparent backdrop-blur-2xl border border-[var(--hg-50)] [border-style:outset] [text-shadow:0px_2px_4px_#ffffff45] relative flex items-center justify-center gap-2 py-2.5 text-[10px] font-normal uppercase tracking-[0.1em] text-[#6b6860] transition-all duration-200 hover:text-stone-700 dark:text-stone-200 sm:py-3 sm:text-[10px] md:py-4',
163
- '--border-r --border-b --border-border',
164
- (index + 1) % 4 === 0 ? '--sm:border-r-0' : '--border-border ',
165
- index >= 4 ? '--sm:border-b-0' : '',
166
- (index + 1) % 2 === 0 ? '--border-r-0' : '--border-r',
167
- index >= 6 ? '--border-b-0' : '--border-b',
168
- getDelayClass(index),
169
- cellClassName,
170
- )
171
-
172
- const content = (
173
- <>
174
- {icon && iconPosition === 'before' && icon}
175
- <span className="relative z-10">{label}</span>
176
- {icon && iconPosition === 'after' && icon}
177
- </>
178
- )
179
-
180
- if (isExternalUrl(href)) {
181
- return (
182
- <a
183
- key={item.id || `${label}-${index}`}
184
- href={href}
185
- target={target}
186
- rel={rel}
187
- className={className}
188
- style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 400, position: 'relative', textDecoration: 'none' }}
189
- >
190
- {content}
191
- </a>
192
- )
193
- }
194
-
195
- return (
196
- <Link
197
- key={item.id || `${label}-${index}`}
198
- href={href}
199
- target={target}
200
- rel={rel}
201
- className={className}
202
- style={{ fontFamily: "'Space Grotesk', sans-serif", fontWeight: 400, position: 'relative', textDecoration: 'none' }}
203
- >
204
- {content}
205
- </Link>
206
- )
207
- })}
208
- </div>
209
- </div>
210
- )
211
- }
212
-
213
- export default DDHGNavCodeGrid
1
+ 'use client'
2
+
3
+ import Image from 'next/image'
4
+ import Link from 'next/link'
5
+ import * as LucideIcons from 'lucide-react'
6
+ import React from 'react'
7
+
8
+ import { getMediaUrl } from '@/utilities/getMediaUrl'
9
+ import { cn } from '@/utilities/ui'
10
+
11
+ type PortableDoc = {
12
+ slug?: string | null
13
+ breadcrumbs?: Array<{ url?: string | null }> | null
14
+ [key: string]: unknown
15
+ }
16
+
17
+ type Media = {
18
+ url?: string | null
19
+ alt?: string | null
20
+ [key: string]: unknown
21
+ }
22
+
23
+ type LinkReference =
24
+ | { relationTo: 'pages'; value: number | PortableDoc }
25
+ | { relationTo: 'posts'; value: number | PortableDoc }
26
+ | { relationTo: 'projects'; value: number | PortableDoc }
27
+ | { relationTo: 'thoughts'; value: number | PortableDoc }
28
+
29
+ type NavCodeGridLink = {
30
+ type?: 'reference' | 'custom' | null
31
+ reference?: LinkReference | null
32
+ url?: string | null
33
+ label?: string | null
34
+ newTab?: boolean | null
35
+ icon?: string | null
36
+ iconPosition?: 'before' | 'after' | null
37
+ customIcon?: number | Media | null
38
+ } | null
39
+
40
+ export type DDHGNavCodeGridItem = {
41
+ id?: string | null
42
+ code?: string | null
43
+ link?: NavCodeGridLink
44
+ }
45
+
46
+ export type DDHGNavCodeGridProps = {
47
+ items?: DDHGNavCodeGridItem[] | null
48
+ defaultHref?: string | null
49
+ containerClassName?: string | null
50
+ gridClassName?: string | null
51
+ cellClassName?: string | null
52
+ showIcons?: boolean | null
53
+ }
54
+
55
+ const getPageURLFromDoc = (doc: PortableDoc | number): string | null => {
56
+ if (typeof doc === 'number') return null
57
+ const crumbs = Array.isArray(doc?.breadcrumbs) ? doc.breadcrumbs : []
58
+ if (crumbs.length) {
59
+ const last = crumbs[crumbs.length - 1]
60
+ if (typeof last?.url === 'string' && last.url) return last.url
61
+ }
62
+ const slug = doc?.slug
63
+ if (!slug || slug === 'home') return '/'
64
+ return slug.startsWith('/') ? slug : `/${slug}`
65
+ }
66
+
67
+ const getDocumentSlug = (doc: PortableDoc | number): string | null => {
68
+ if (typeof doc === 'number') return null
69
+ return doc?.slug || null
70
+ }
71
+
72
+ const getCollectionPath = (relationTo: LinkReference['relationTo']): string => {
73
+ if (relationTo === 'posts') return 'internal-docs'
74
+ if (relationTo === 'thoughts') return 'thoughts'
75
+ if (relationTo === 'projects') return 'archives'
76
+ return ''
77
+ }
78
+
79
+ const isExternalUrl = (href: string): boolean =>
80
+ href.startsWith('http://') ||
81
+ href.startsWith('https://') ||
82
+ href.startsWith('mailto:') ||
83
+ href.startsWith('tel:')
84
+
85
+ const resolveHref = (link: NavCodeGridLink, defaultHref = '/archive'): string => {
86
+ if (!link) return defaultHref
87
+ if (link.type === 'custom' && link.url) return link.url
88
+ if (link.type === 'reference' && link.reference?.value) {
89
+ const { relationTo, value } = link.reference
90
+ if (relationTo === 'pages') return getPageURLFromDoc(value) || defaultHref
91
+ const slug = getDocumentSlug(value)
92
+ if (!slug) return defaultHref
93
+ const basePath = getCollectionPath(relationTo)
94
+ return basePath ? `/${basePath}/${slug}` : `/${slug}`
95
+ }
96
+ return defaultHref
97
+ }
98
+
99
+ const renderIcon = (link: NavCodeGridLink, showIcons = true) => {
100
+ if (!showIcons || !link) return null
101
+
102
+ if (link.customIcon && typeof link.customIcon === 'object') {
103
+ const iconUrl = getMediaUrl(link.customIcon.url)
104
+ if (iconUrl) {
105
+ return (
106
+ <span className="inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center overflow-hidden">
107
+ <Image
108
+ src={iconUrl}
109
+ alt={link.customIcon.alt || ''}
110
+ width={14}
111
+ height={14}
112
+ className="m-0 block h-full w-full object-contain"
113
+ />
114
+ </span>
115
+ )
116
+ }
117
+ }
118
+
119
+ if (link.icon) {
120
+ const LucideIcon = LucideIcons[link.icon as keyof typeof LucideIcons] as
121
+ React.ComponentType<{ className?: string }> | undefined
122
+ if (LucideIcon) {
123
+ return (
124
+ <span className="inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center">
125
+ <LucideIcon className="h-3.5 w-3.5" />
126
+ </span>
127
+ )
128
+ }
129
+ }
130
+
131
+ return null
132
+ }
133
+
134
+ const getDelayClass = (index: number) => {
135
+ const delay = Math.min(index * 40, 320)
136
+ return `[transition-delay:${delay}ms]`
137
+ }
138
+
139
+ export const DDHGNavCodeGrid: React.FC<DDHGNavCodeGridProps> = ({
140
+ items,
141
+ defaultHref = '/archive',
142
+ containerClassName,
143
+ gridClassName,
144
+ cellClassName,
145
+ showIcons = true,
146
+ }) => {
147
+ if (!Array.isArray(items) || items.length === 0) return null
148
+
149
+ return (
150
+ <div className={cn('w-full max-w-7xl mx-auto', containerClassName, 'pt-24')}>
151
+ <div
152
+ className={cn(
153
+ 'grid grid-cols-2 overflow-hidden bg-stone-100/50 dark:bg-stone-900/50 sm:grid-cols-4 !gap-0 shadow-lg',
154
+ gridClassName,
155
+ )}
156
+ >
157
+ {items.map((item, index) => {
158
+ const link = item.link || null
159
+ const href = resolveHref(link, defaultHref || '/archive')
160
+ const label = link?.label || item.code || 'Archive'
161
+ const icon = renderIcon(link, Boolean(showIcons))
162
+ const iconPosition = link?.iconPosition || 'before'
163
+ const target = link?.newTab ? '_blank' : undefined
164
+ const rel = link?.newTab ? 'noopener noreferrer' : undefined
165
+ const className = cn(
166
+ 'menu-cell-hover group relative flex items-center justify-center gap-2 bg-stone-200/50 py-2.5 text-xs font-normal uppercase tracking-[0.1em] text-sm [text-shadow:0px_2px_4px_#ffffff45] backdrop-blur-2xl transition-all duration-300 hover:-translate-y-0.5 hover:bg-stone-200/80 hover:text-stone-700 dark:bg-stone-900/50 dark:text-stone-200 dark:hover:bg-stone-800/70 sm:py-3 sm:text-xs md:py-4 hover:shadow-2xl',
167
+ 'border-r border-b border-border',
168
+ (index + 1) % 4 === 0 ? 'sm:border-r-0' : ' ',
169
+ index >= 4 ? 'sm:border-b-0' : '',
170
+ (index + 1) % 2 === 0 ? 'border-r-0' : 'border-r',
171
+ index >= 6 ? 'border-b-0' : 'border-b',
172
+ getDelayClass(index),
173
+ cellClassName,
174
+ )
175
+
176
+ const content = (
177
+ <>
178
+ {icon && iconPosition === 'before' && icon}
179
+ <span className="relative z-10">{label}</span>
180
+ {icon && iconPosition === 'after' && icon}
181
+ </>
182
+ )
183
+
184
+ if (isExternalUrl(href)) {
185
+ return (
186
+ <a
187
+ key={item.id || `${label}-${index}`}
188
+ href={href}
189
+ target={target}
190
+ rel={rel}
191
+ className={className}
192
+ style={{
193
+ fontFamily: "'Space Grotesk', sans-serif",
194
+ fontWeight: 400,
195
+ position: 'relative',
196
+ textDecoration: 'none',
197
+ }}
198
+ >
199
+ {content}
200
+ </a>
201
+ )
202
+ }
203
+
204
+ return (
205
+ <Link
206
+ key={item.id || `${label}-${index}`}
207
+ href={href}
208
+ target={target}
209
+ rel={rel}
210
+ className={className}
211
+ style={{
212
+ fontFamily: "'Space Grotesk', sans-serif",
213
+ fontWeight: 400,
214
+ position: 'relative',
215
+ textDecoration: 'none',
216
+ }}
217
+ >
218
+ {content}
219
+ </Link>
220
+ )
221
+ })}
222
+ </div>
223
+ </div>
224
+ )
225
+ }
226
+
227
+ export default DDHGNavCodeGrid