blocks-dusted 0.1.1 → 0.1.2
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/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,11 @@
|
|
|
1
|
+
# Testimonials Collection Template
|
|
2
|
+
|
|
3
|
+
Installs `src/collections/Testimonials.ts` and registers `Testimonials` in `payload.config.ts` when the collections array can be patched safely.
|
|
4
|
+
|
|
5
|
+
The source was adapted from the Raw Dusted Blocks Testimonials collection for the default Payload starter helper paths:
|
|
6
|
+
|
|
7
|
+
- `../access/authenticated`
|
|
8
|
+
- `../access/anyone`
|
|
9
|
+
- `@/fields/defaultLexical`
|
|
10
|
+
|
|
11
|
+
Review the installed collection before running Payload type generation.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import type { CollectionConfig } from 'payload'
|
|
2
|
+
|
|
3
|
+
import { authenticated } from '../access/authenticated'
|
|
4
|
+
import { anyone } from '../access/anyone'
|
|
5
|
+
import { defaultLexical } from '@/fields/defaultLexical'
|
|
6
|
+
|
|
7
|
+
export const Testimonials: CollectionConfig = {
|
|
8
|
+
slug: 'testimonials',
|
|
9
|
+
orderable: true,
|
|
10
|
+
labels: {
|
|
11
|
+
singular: 'Testimonial',
|
|
12
|
+
plural: 'Testimonials',
|
|
13
|
+
},
|
|
14
|
+
access: {
|
|
15
|
+
create: authenticated,
|
|
16
|
+
delete: authenticated,
|
|
17
|
+
read: anyone,
|
|
18
|
+
update: authenticated,
|
|
19
|
+
},
|
|
20
|
+
admin: {
|
|
21
|
+
useAsTitle: 'title',
|
|
22
|
+
defaultColumns: ['clientName', 'designation', 'company'],
|
|
23
|
+
},
|
|
24
|
+
fields: [
|
|
25
|
+
{
|
|
26
|
+
name: 'title',
|
|
27
|
+
type: 'text',
|
|
28
|
+
required: true,
|
|
29
|
+
index: true,
|
|
30
|
+
admin: {
|
|
31
|
+
description: 'Use client name as title to identify this testimonial.',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
type: 'row',
|
|
36
|
+
fields: [
|
|
37
|
+
{
|
|
38
|
+
name: 'clientName',
|
|
39
|
+
type: 'richText',
|
|
40
|
+
label: "Client's Name",
|
|
41
|
+
required: true,
|
|
42
|
+
editor: defaultLexical,
|
|
43
|
+
admin: {
|
|
44
|
+
width: '50%',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'designation',
|
|
49
|
+
hidden: false,
|
|
50
|
+
type: 'richText',
|
|
51
|
+
label: 'Designation / Role',
|
|
52
|
+
required: false,
|
|
53
|
+
editor: defaultLexical,
|
|
54
|
+
admin: {
|
|
55
|
+
width: '50%',
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
type: 'row',
|
|
62
|
+
fields: [
|
|
63
|
+
{
|
|
64
|
+
name: 'company',
|
|
65
|
+
type: 'richText',
|
|
66
|
+
label: 'Company',
|
|
67
|
+
required: false,
|
|
68
|
+
editor: defaultLexical,
|
|
69
|
+
admin: {
|
|
70
|
+
width: '50%',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
type: 'group',
|
|
75
|
+
label: false,
|
|
76
|
+
admin: {
|
|
77
|
+
width: '50%',
|
|
78
|
+
},
|
|
79
|
+
fields: [
|
|
80
|
+
{
|
|
81
|
+
name: 'companyLogo',
|
|
82
|
+
type: 'upload',
|
|
83
|
+
relationTo: 'media',
|
|
84
|
+
label: 'Company Logo / Avatar',
|
|
85
|
+
required: false,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'fallbackAvatarUrl',
|
|
89
|
+
type: 'text',
|
|
90
|
+
label: 'Fallback Logo/Avatar URL',
|
|
91
|
+
admin: {
|
|
92
|
+
description: 'External URL for avatar when no media upload is provided.',
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: 'content',
|
|
101
|
+
type: 'richText',
|
|
102
|
+
label: 'Testimonial Content',
|
|
103
|
+
required: false,
|
|
104
|
+
editor: defaultLexical,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
type: 'row',
|
|
108
|
+
fields: [
|
|
109
|
+
{
|
|
110
|
+
name: 'rating',
|
|
111
|
+
type: 'number',
|
|
112
|
+
label: 'Star Rating (1-5)',
|
|
113
|
+
min: 1,
|
|
114
|
+
max: 5,
|
|
115
|
+
admin: {
|
|
116
|
+
description: 'Numeric star rating used by Studio Testimonials block.',
|
|
117
|
+
width: '50%',
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: 'date',
|
|
122
|
+
type: 'text',
|
|
123
|
+
label: 'Date',
|
|
124
|
+
admin: {
|
|
125
|
+
description: 'Date string shown on marquee cards e.g. "March 2025".',
|
|
126
|
+
width: '50%',
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'ratingText',
|
|
131
|
+
type: 'text',
|
|
132
|
+
label: 'Rating (Text)',
|
|
133
|
+
admin: {
|
|
134
|
+
description: 'Displayed rating string e.g. "5 stars" or "5.0" used by Marquee block.',
|
|
135
|
+
width: '100%',
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: 'sourceLogo',
|
|
142
|
+
type: 'upload',
|
|
143
|
+
relationTo: 'media',
|
|
144
|
+
label: 'Source Platform Logo',
|
|
145
|
+
admin: {
|
|
146
|
+
description: 'Platform logo for marquee cards, e.g. Upwork or Fiverr logo.',
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: 'sourceLogoAlt',
|
|
151
|
+
type: 'text',
|
|
152
|
+
label: 'Source Logo Alt Text',
|
|
153
|
+
defaultValue: 'logo alt',
|
|
154
|
+
admin: {
|
|
155
|
+
description: 'Alt text for the source platform logo.',
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export default Testimonials
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "collection",
|
|
3
|
+
"name": "Testimonials",
|
|
4
|
+
"label": "Testimonials Collection",
|
|
5
|
+
"slug": "testimonials",
|
|
6
|
+
"version": "0.0.1",
|
|
7
|
+
"source": {
|
|
8
|
+
"referencePath": "Raw Dusted Blocks/dusted-src (to add into CLI)/src/collections/Testimonials.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
{
|
|
12
|
+
"from": "Testimonials.ts",
|
|
13
|
+
"to": "src/collections/Testimonials.ts"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"dependencies": [],
|
|
17
|
+
"requiredProjectFiles": [
|
|
18
|
+
{
|
|
19
|
+
"path": "src/access/authenticated.ts",
|
|
20
|
+
"reason": "Testimonials uses the default authenticated access helper."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"path": "src/access/anyone.ts",
|
|
24
|
+
"reason": "Testimonials uses the default anyone read access helper."
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"path": "src/fields/defaultLexical.ts",
|
|
28
|
+
"reason": "Testimonials richText fields use the project's defaultLexical editor helper."
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"path": "src/collections/Media.ts",
|
|
32
|
+
"reason": "Testimonials upload fields relate to the media collection."
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"optionalProjectFiles": [
|
|
36
|
+
{
|
|
37
|
+
"path": "src/payload.config.ts",
|
|
38
|
+
"reason": "Installer can register Testimonials in the Payload collections array."
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"payloadConfigRegistration": {
|
|
42
|
+
"enabled": true,
|
|
43
|
+
"exportName": "Testimonials",
|
|
44
|
+
"importPath": "./collections/Testimonials"
|
|
45
|
+
},
|
|
46
|
+
"manual": [
|
|
47
|
+
"Review src/collections/Testimonials.ts against the target project's access helper paths, media slug, and defaultLexical helper before using it in production.",
|
|
48
|
+
"Run the target project's Payload type-generation command after installing the collection.",
|
|
49
|
+
"Run formatter, linter, TypeScript, and build checks after installation."
|
|
50
|
+
],
|
|
51
|
+
"notes": [
|
|
52
|
+
"This collection is based on the Raw Dusted Blocks Testimonials reference, adjusted to the default Payload starter access helper paths.",
|
|
53
|
+
"The installer patches payload.config collections registration only when it can find a clear collections array."
|
|
54
|
+
]
|
|
55
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# RichText Component Template
|
|
2
|
+
|
|
3
|
+
This template restructures the default Payload starter RichText component into the Payload Rich Text Dusted Standard folder shape.
|
|
4
|
+
|
|
5
|
+
It is intentionally limited to default Payload starter behaviour:
|
|
6
|
+
|
|
7
|
+
- internal page and post links
|
|
8
|
+
- Lexical text formatting
|
|
9
|
+
- embedded `banner`, `code`, and `mediaBlock` blocks
|
|
10
|
+
|
|
11
|
+
Do not add custom reference-project block mappings unless the target project's RichText editor configuration enables those blocks.
|
|
12
|
+
|
|
13
|
+
The current `blocks-dusted` installer is still block-template-first, so this component template is source material for the next component installer milestone rather than an installable block template.
|
|
@@ -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
|
+
}
|