blocks-dusted 0.1.1 → 0.1.3
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.
- package/README.md +967 -3
- package/package.json +2 -2
- package/src/commands/add.js +143 -45
- package/src/commands/list.js +2 -2
- package/src/installers/checkRequirements.js +1 -0
- package/src/installers/copyTemplateFiles.js +23 -2
- package/src/installers/patchPayloadConfigCollections.js +92 -0
- package/src/installers/writeInstalledBlockReadme.js +17 -4
- package/src/registry/listTemplates.js +16 -7
- package/src/registry/loadTemplateManifest.js +20 -11
- package/src/registry/validateTemplateManifest.js +6 -5
- package/src/utils/paths.js +7 -0
- package/templates/blocks/DD-BookCall/Component.tsx +535 -573
- package/templates/blocks/DD-CardTemplate01/Component.tsx +45 -49
- package/templates/blocks/DD-Carousel-A/Component.tsx +249 -266
- package/templates/blocks/DD-Carousel-B/Component.tsx +403 -432
- package/templates/blocks/DD-ComparisonTable/Component.tsx +256 -272
- package/templates/blocks/DD-Contact/Component.tsx +434 -439
- package/templates/blocks/DD-Contact/config.ts +8 -3
- package/templates/blocks/DD-FeatCat/Component.tsx +302 -361
- package/templates/blocks/DD-FeatCat/config.ts +201 -204
- package/templates/blocks/DD-FeatStrip/Component.tsx +171 -201
- package/templates/blocks/DD-Hero/Component.tsx +297 -317
- package/templates/blocks/DD-HorizontalScroll/Component.tsx +244 -303
- package/templates/blocks/DD-MasonaryMedia/Component.tsx +202 -228
- package/templates/blocks/DD-MasonaryMedia/config.ts +13 -14
- package/templates/blocks/DD-Pricing/Component.tsx +372 -380
- package/templates/blocks/DD-Process/Component.tsx +149 -155
- package/templates/blocks/DD-Section/Component.tsx +266 -327
- package/templates/blocks/DD-Services/Component.tsx +176 -188
- package/templates/blocks/DD-ShowcaseGrid/Component.tsx +307 -317
- package/templates/blocks/DD-Slider-A/Component.tsx +237 -252
- package/templates/blocks/DD-StackCards/Component.tsx +137 -160
- package/templates/blocks/DD-Team/Component.tsx +247 -265
- package/templates/blocks/DD-TechStack/Component.tsx +57 -72
- package/templates/blocks/DD-Testimonials/Component.tsx +147 -147
- package/templates/blocks/DD-Testimonials/config.ts +66 -66
- package/templates/blocks/DD-Work/Component.tsx +315 -328
- package/templates/blocks/DD-Work-B/Component.tsx +294 -320
- package/templates/collections/Testimonials/README.md +11 -0
- package/templates/collections/Testimonials/Testimonials.ts +161 -0
- package/templates/collections/Testimonials/manifest.json +55 -0
- package/templates/components/HeaderDD02/MobileBottomNav/index.tsx +545 -0
- package/templates/components/HeaderDD02/README.md +45 -0
- package/templates/components/HeaderDD02/RowLabel.tsx +33 -0
- package/templates/components/HeaderDD02/config.ts +302 -0
- package/templates/components/HeaderDD02/index.tsx +517 -0
- package/templates/components/HeaderDD02/manifest.json +123 -0
- package/templates/components/RichText/README.md +13 -0
- package/templates/components/RichText/converter/componentConverter/blocks.tsx +43 -0
- package/templates/components/RichText/converter/componentConverter/types.ts +11 -0
- package/templates/components/RichText/converter/index.tsx +18 -0
- package/templates/components/RichText/converter/internalLinks.tsx +45 -0
- package/templates/components/RichText/converter/textConverter.tsx +27 -0
- package/templates/components/RichText/index.tsx +35 -0
- package/templates/components/RichText/manifest.json +80 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type React from 'react'
|
|
2
|
+
import type { SerializedBlockNode } from '@payloadcms/richtext-lexical'
|
|
3
|
+
|
|
4
|
+
import { BannerBlock } from '@/blocks/Banner/Component'
|
|
5
|
+
import { CodeBlock } from '@/blocks/Code/Component'
|
|
6
|
+
import { MediaBlock } from '@/blocks/MediaBlock/Component'
|
|
7
|
+
import type { CodeBlockProps } from '@/blocks/Code/Component'
|
|
8
|
+
import type {
|
|
9
|
+
BannerBlock as BannerBlockProps,
|
|
10
|
+
MediaBlock as MediaBlockProps,
|
|
11
|
+
} from '@/payload-types'
|
|
12
|
+
|
|
13
|
+
type BlockConverter<T> = (props: { node?: SerializedBlockNode<T> }) => React.ReactNode
|
|
14
|
+
|
|
15
|
+
const banner: BlockConverter<BannerBlockProps> = ({ node }) => {
|
|
16
|
+
if (!node?.fields) return null
|
|
17
|
+
return <BannerBlock className="col-start-2 mb-4" {...node.fields} />
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const mediaBlock: BlockConverter<MediaBlockProps> = ({ node }) => {
|
|
21
|
+
if (!node?.fields) return null
|
|
22
|
+
return (
|
|
23
|
+
<MediaBlock
|
|
24
|
+
className="col-start-1 col-span-3"
|
|
25
|
+
imgClassName="m-0"
|
|
26
|
+
{...node.fields}
|
|
27
|
+
captionClassName="mx-auto max-w-[48rem]"
|
|
28
|
+
enableGutter={false}
|
|
29
|
+
disableInnerContainer={true}
|
|
30
|
+
/>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const code: BlockConverter<CodeBlockProps> = ({ node }) => {
|
|
35
|
+
if (!node?.fields) return null
|
|
36
|
+
return <CodeBlock className="col-start-2" {...node.fields} />
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const blockConverters = {
|
|
40
|
+
banner,
|
|
41
|
+
mediaBlock,
|
|
42
|
+
code,
|
|
43
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DefaultNodeTypes, SerializedBlockNode } from '@payloadcms/richtext-lexical'
|
|
2
|
+
|
|
3
|
+
import type { CodeBlockProps } from '@/blocks/Code/Component'
|
|
4
|
+
import type {
|
|
5
|
+
BannerBlock as BannerBlockProps,
|
|
6
|
+
MediaBlock as MediaBlockProps,
|
|
7
|
+
} from '@/payload-types'
|
|
8
|
+
|
|
9
|
+
export type RichTextEmbeddedBlock = BannerBlockProps | MediaBlockProps | CodeBlockProps
|
|
10
|
+
|
|
11
|
+
export type NodeTypes = DefaultNodeTypes | SerializedBlockNode<RichTextEmbeddedBlock>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
JSXConvertersFunction,
|
|
3
|
+
LinkJSXConverter,
|
|
4
|
+
} from '@payloadcms/richtext-lexical/react'
|
|
5
|
+
|
|
6
|
+
import { internalDocToHref } from '@/components/RichText/converter/internalLinks'
|
|
7
|
+
import { textConverter } from '@/components/RichText/converter/textConverter'
|
|
8
|
+
import { blockConverters } from '@/components/RichText/converter/componentConverter/blocks'
|
|
9
|
+
import type { NodeTypes } from '@/components/RichText/converter/componentConverter/types'
|
|
10
|
+
|
|
11
|
+
export type { NodeTypes } from '@/components/RichText/converter/componentConverter/types'
|
|
12
|
+
|
|
13
|
+
export const jsxConverters: JSXConvertersFunction<NodeTypes> = ({ defaultConverters }) => ({
|
|
14
|
+
...defaultConverters,
|
|
15
|
+
...LinkJSXConverter({ internalDocToHref }),
|
|
16
|
+
...textConverter,
|
|
17
|
+
blocks: blockConverters,
|
|
18
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { SerializedLinkNode } from '@payloadcms/richtext-lexical'
|
|
2
|
+
|
|
3
|
+
type LinkedDocument = {
|
|
4
|
+
slug?: string | null
|
|
5
|
+
breadcrumbs?: Array<{
|
|
6
|
+
slug?: string | null
|
|
7
|
+
url?: string | null
|
|
8
|
+
}> | null
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const pagePathFromDoc = (value: LinkedDocument): string => {
|
|
12
|
+
const crumbs = Array.isArray(value.breadcrumbs) ? value.breadcrumbs : []
|
|
13
|
+
const lastCrumb = crumbs[crumbs.length - 1]
|
|
14
|
+
|
|
15
|
+
if (typeof lastCrumb?.url === 'string' && lastCrumb.url) return lastCrumb.url
|
|
16
|
+
|
|
17
|
+
const segments = crumbs
|
|
18
|
+
.map((crumb) => (typeof crumb?.slug === 'string' ? crumb.slug : ''))
|
|
19
|
+
.filter(Boolean)
|
|
20
|
+
|
|
21
|
+
if (segments.length > 0) return `/${segments.join('/')}`
|
|
22
|
+
|
|
23
|
+
const slug = typeof value.slug === 'string' ? value.slug : ''
|
|
24
|
+
if (!slug || slug === 'home') return '/'
|
|
25
|
+
return `/${slug.replace(/^\/+/, '')}`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const internalDocToHref = ({ linkNode }: { linkNode: SerializedLinkNode }) => {
|
|
29
|
+
const doc = linkNode.fields.doc
|
|
30
|
+
const relationTo = doc?.relationTo
|
|
31
|
+
const value = doc?.value
|
|
32
|
+
|
|
33
|
+
if (!relationTo || typeof value !== 'object' || value === null) return '#'
|
|
34
|
+
|
|
35
|
+
switch (relationTo) {
|
|
36
|
+
case 'pages':
|
|
37
|
+
return pagePathFromDoc(value as LinkedDocument)
|
|
38
|
+
case 'posts': {
|
|
39
|
+
const slug = (value as LinkedDocument).slug
|
|
40
|
+
return typeof slug === 'string' && slug ? `/posts/${slug}` : '#'
|
|
41
|
+
}
|
|
42
|
+
default:
|
|
43
|
+
return '#'
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type React from 'react'
|
|
2
|
+
import type { SerializedTextNode } from '@payloadcms/richtext-lexical'
|
|
3
|
+
import type { JSXConverters } from '@payloadcms/richtext-lexical/react'
|
|
4
|
+
|
|
5
|
+
const IS_BOLD = 1
|
|
6
|
+
const IS_ITALIC = 2
|
|
7
|
+
const IS_STRIKETHROUGH = 4
|
|
8
|
+
const IS_UNDERLINE = 8
|
|
9
|
+
const IS_CODE = 16
|
|
10
|
+
const IS_SUBSCRIPT = 32
|
|
11
|
+
const IS_SUPERSCRIPT = 64
|
|
12
|
+
|
|
13
|
+
export const textConverter: JSXConverters<SerializedTextNode> = {
|
|
14
|
+
text: ({ node }) => {
|
|
15
|
+
let output: React.ReactNode = node.text
|
|
16
|
+
|
|
17
|
+
if (node.format & IS_BOLD) output = <strong>{output}</strong>
|
|
18
|
+
if (node.format & IS_ITALIC) output = <em>{output}</em>
|
|
19
|
+
if (node.format & IS_STRIKETHROUGH) output = <s>{output}</s>
|
|
20
|
+
if (node.format & IS_UNDERLINE) output = <u>{output}</u>
|
|
21
|
+
if (node.format & IS_CODE) output = <code>{output}</code>
|
|
22
|
+
if (node.format & IS_SUBSCRIPT) output = <sub>{output}</sub>
|
|
23
|
+
if (node.format & IS_SUPERSCRIPT) output = <sup>{output}</sup>
|
|
24
|
+
|
|
25
|
+
return output
|
|
26
|
+
},
|
|
27
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type React from 'react'
|
|
2
|
+
import { type DefaultTypedEditorState } from '@payloadcms/richtext-lexical'
|
|
3
|
+
import { RichText as ConvertRichText } from '@payloadcms/richtext-lexical/react'
|
|
4
|
+
|
|
5
|
+
import { jsxConverters } from '@/components/RichText/converter'
|
|
6
|
+
import { cn } from '@/utilities/ui'
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
data?: DefaultTypedEditorState | null
|
|
10
|
+
enableGutter?: boolean
|
|
11
|
+
enableProse?: boolean
|
|
12
|
+
} & React.HTMLAttributes<HTMLDivElement>
|
|
13
|
+
|
|
14
|
+
export default function RichText(props: Props) {
|
|
15
|
+
const { className, enableProse = true, enableGutter = true, data, ...rest } = props
|
|
16
|
+
|
|
17
|
+
if (!data) return null
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<ConvertRichText
|
|
21
|
+
converters={jsxConverters}
|
|
22
|
+
data={data}
|
|
23
|
+
className={cn(
|
|
24
|
+
'payload-richtext',
|
|
25
|
+
{
|
|
26
|
+
container: enableGutter,
|
|
27
|
+
'max-w-none': !enableGutter,
|
|
28
|
+
'mx-auto prose md:prose-md dark:prose-invert': enableProse,
|
|
29
|
+
},
|
|
30
|
+
className,
|
|
31
|
+
)}
|
|
32
|
+
{...rest}
|
|
33
|
+
/>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "component",
|
|
3
|
+
"name": "RichText",
|
|
4
|
+
"label": "Payload RichText Dusted Standard",
|
|
5
|
+
"slug": "RichText",
|
|
6
|
+
"version": "0.0.1",
|
|
7
|
+
"source": {
|
|
8
|
+
"defaultPath": "src/components/RichText/index.tsx",
|
|
9
|
+
"referencePath": "Raw Dusted Blocks/dusted-src (to add into CLI)/src/components/RichText"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
{
|
|
13
|
+
"from": "index.tsx",
|
|
14
|
+
"to": "src/components/RichText/index.tsx"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"from": "converter/index.tsx",
|
|
18
|
+
"to": "src/components/RichText/converter/index.tsx"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"from": "converter/internalLinks.tsx",
|
|
22
|
+
"to": "src/components/RichText/converter/internalLinks.tsx"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"from": "converter/textConverter.tsx",
|
|
26
|
+
"to": "src/components/RichText/converter/textConverter.tsx"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"from": "converter/componentConverter/blocks.tsx",
|
|
30
|
+
"to": "src/components/RichText/converter/componentConverter/blocks.tsx"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"from": "converter/componentConverter/types.ts",
|
|
34
|
+
"to": "src/components/RichText/converter/componentConverter/types.ts"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"dependencies": [
|
|
38
|
+
{
|
|
39
|
+
"name": "@payloadcms/richtext-lexical"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"requiredProjectFiles": [
|
|
43
|
+
{
|
|
44
|
+
"path": "src/utilities/ui.ts",
|
|
45
|
+
"reason": "RichText uses cn from @/utilities/ui."
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"path": "src/blocks/Banner/Component.tsx",
|
|
49
|
+
"reason": "Default Payload RichText embedded block mapping for banner."
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"path": "src/blocks/Code/Component.tsx",
|
|
53
|
+
"reason": "Default Payload RichText embedded block mapping for code."
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"path": "src/blocks/MediaBlock/Component.tsx",
|
|
57
|
+
"reason": "Default Payload RichText embedded block mapping for mediaBlock."
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"optionalProjectFiles": [
|
|
61
|
+
{
|
|
62
|
+
"path": "src/collections/Posts/index.ts",
|
|
63
|
+
"reason": "Inspect RichText editor features and embedded BlocksFeature configuration before installing."
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"manual": [
|
|
67
|
+
"The existing src/components/RichText folder is backed up before installation; review the backup and copy any project-specific behaviour missing from the newly installed RichText structure.",
|
|
68
|
+
"Install this component only after inspecting the target project\u0027s RichText editor configuration.",
|
|
69
|
+
"This default template maps only the Payload starter embedded RichText blocks: banner, code, and mediaBlock.",
|
|
70
|
+
"Add cta or other block mappings only if the target RichText field\u0027s BlocksFeature actually enables those blocks.",
|
|
71
|
+
"Keep internal link routes aligned with the target project\u0027s real pages/posts routes.",
|
|
72
|
+
"Run the target project\u0027s Payload type-generation command if generated types are stale.",
|
|
73
|
+
"Run formatter, linter, TypeScript, and build checks after installation."
|
|
74
|
+
],
|
|
75
|
+
"notes": [
|
|
76
|
+
"This is a Layer 2 reusable core component template, not a Payload block template.",
|
|
77
|
+
"Do not copy reference-project preview-link-card, custom media, custom color state, or non-starter block mappings into default Payload installs."
|
|
78
|
+
],
|
|
79
|
+
"backupExistingDestination": true
|
|
80
|
+
}
|