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
package/README.md
CHANGED
|
@@ -4,6 +4,348 @@
|
|
|
4
4
|
|
|
5
5
|
The GitHub source repository is private. That does not prevent installation from npm after the package is published, including when the published npm package is public.
|
|
6
6
|
|
|
7
|
+
## Project Objective
|
|
8
|
+
|
|
9
|
+
`blocks-dusted` is a reusable Payload CMS CLI.
|
|
10
|
+
|
|
11
|
+
The end goal is **not** simply a block installer.
|
|
12
|
+
|
|
13
|
+
It is a complete installation framework capable of progressively installing reusable Payload features into existing Payload projects.
|
|
14
|
+
|
|
15
|
+
Everything should be manifest-driven, repeatable, safe, versionable, and easy to extend.
|
|
16
|
+
|
|
17
|
+
Eventually a developer should be able to build an entire Payload project from reusable packages.
|
|
18
|
+
|
|
19
|
+
Example:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm dlx blocks-dusted add DD-Hero
|
|
23
|
+
pnpm dlx blocks-dusted add DD-Contact
|
|
24
|
+
pnpm dlx blocks-dusted add DD-Header
|
|
25
|
+
pnpm dlx blocks-dusted add DD-Footer
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
without manually copying files.
|
|
29
|
+
|
|
30
|
+
## Current Status
|
|
31
|
+
|
|
32
|
+
Repository
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
https://github.com/Hadizainal/blocks-dusted
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Current visibility:
|
|
39
|
+
|
|
40
|
+
- Private
|
|
41
|
+
|
|
42
|
+
Current npm package:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
blocks-dusted
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Current executable:
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
blocks-dusted
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Published version:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
0.1.1
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Verified working through:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
pnpm dlx blocks-dusted
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The CLI has been successfully tested from a completely separate Payload project.
|
|
67
|
+
|
|
68
|
+
## Current CLI Features
|
|
69
|
+
|
|
70
|
+
Implemented
|
|
71
|
+
|
|
72
|
+
- manifest-driven registry
|
|
73
|
+
- block listing
|
|
74
|
+
- doctor command
|
|
75
|
+
- dry-run support
|
|
76
|
+
- block installation
|
|
77
|
+
- shared file installation
|
|
78
|
+
- dependency detection
|
|
79
|
+
- manual dependency reporting
|
|
80
|
+
- RenderBlocks patching
|
|
81
|
+
- Collection block registration
|
|
82
|
+
- collision protection
|
|
83
|
+
- shared file protection
|
|
84
|
+
- automatic backups
|
|
85
|
+
- installed block README generation
|
|
86
|
+
- package validation
|
|
87
|
+
- packed tarball validation
|
|
88
|
+
- clean-room installation tests
|
|
89
|
+
- npm distribution
|
|
90
|
+
|
|
91
|
+
Not implemented intentionally
|
|
92
|
+
|
|
93
|
+
- automatic dependency installation
|
|
94
|
+
- automatic Payload generators
|
|
95
|
+
- automatic migrations
|
|
96
|
+
- automatic builds
|
|
97
|
+
|
|
98
|
+
These should remain manual unless explicitly changed later.
|
|
99
|
+
|
|
100
|
+
## Immediate Next Work
|
|
101
|
+
|
|
102
|
+
The existing blocks are **not yet considered complete**.
|
|
103
|
+
|
|
104
|
+
Many were converted from Designs Dusted and now require updating.
|
|
105
|
+
|
|
106
|
+
Examples include:
|
|
107
|
+
|
|
108
|
+
### Component cleanup
|
|
109
|
+
|
|
110
|
+
Replace unnecessary wrappers.
|
|
111
|
+
|
|
112
|
+
Example:
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
<section>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
should become
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
<div>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
where appropriate.
|
|
125
|
+
|
|
126
|
+
### Section IDs
|
|
127
|
+
|
|
128
|
+
Blocks should consistently expose configurable section IDs.
|
|
129
|
+
|
|
130
|
+
Many currently require updating.
|
|
131
|
+
|
|
132
|
+
### URL fields
|
|
133
|
+
|
|
134
|
+
Numerous blocks still contain older URL field implementations.
|
|
135
|
+
|
|
136
|
+
They should be migrated to the latest shared URL configuration.
|
|
137
|
+
|
|
138
|
+
### Button configuration
|
|
139
|
+
|
|
140
|
+
Older button implementations still exist.
|
|
141
|
+
|
|
142
|
+
These should be replaced with the current shared implementation.
|
|
143
|
+
|
|
144
|
+
### Shared utilities
|
|
145
|
+
|
|
146
|
+
Many older helper implementations still exist.
|
|
147
|
+
|
|
148
|
+
Future block updates should migrate toward shared reusable utilities instead of duplicated logic.
|
|
149
|
+
|
|
150
|
+
## Future Development
|
|
151
|
+
|
|
152
|
+
The project is moving beyond simple blocks.
|
|
153
|
+
|
|
154
|
+
The next stage introduces reusable project infrastructure.
|
|
155
|
+
|
|
156
|
+
Think in layers.
|
|
157
|
+
|
|
158
|
+
### Layer 1
|
|
159
|
+
|
|
160
|
+
Reusable Blocks
|
|
161
|
+
|
|
162
|
+
Examples
|
|
163
|
+
|
|
164
|
+
- Hero
|
|
165
|
+
- Contact
|
|
166
|
+
- Pricing
|
|
167
|
+
- Carousel
|
|
168
|
+
- Testimonials
|
|
169
|
+
|
|
170
|
+
These install independently.
|
|
171
|
+
|
|
172
|
+
### Layer 2
|
|
173
|
+
|
|
174
|
+
Reusable Core Components
|
|
175
|
+
|
|
176
|
+
Examples
|
|
177
|
+
|
|
178
|
+
- Button
|
|
179
|
+
- Rich Text
|
|
180
|
+
- Section wrapper
|
|
181
|
+
- URL utilities
|
|
182
|
+
- Shared fields
|
|
183
|
+
- Icon picker
|
|
184
|
+
- Media helpers
|
|
185
|
+
|
|
186
|
+
These are dependencies used by many blocks.
|
|
187
|
+
|
|
188
|
+
### Layer 3
|
|
189
|
+
|
|
190
|
+
Reusable Globals
|
|
191
|
+
|
|
192
|
+
Examples
|
|
193
|
+
|
|
194
|
+
- Header
|
|
195
|
+
- Footer
|
|
196
|
+
- Logos
|
|
197
|
+
- Cookie Consent
|
|
198
|
+
- Newsletter Modal
|
|
199
|
+
|
|
200
|
+
Installation should:
|
|
201
|
+
|
|
202
|
+
- copy component
|
|
203
|
+
- register Payload global
|
|
204
|
+
- patch payload.config.ts
|
|
205
|
+
- preserve user changes
|
|
206
|
+
- create backups
|
|
207
|
+
|
|
208
|
+
### Layer 4
|
|
209
|
+
|
|
210
|
+
Frontend Infrastructure
|
|
211
|
+
|
|
212
|
+
Examples
|
|
213
|
+
|
|
214
|
+
- RenderBlocks
|
|
215
|
+
- Layout
|
|
216
|
+
- Providers
|
|
217
|
+
- Navigation
|
|
218
|
+
- Animations
|
|
219
|
+
- Utilities
|
|
220
|
+
- Hooks
|
|
221
|
+
- Context Providers
|
|
222
|
+
|
|
223
|
+
These require safe project patching.
|
|
224
|
+
|
|
225
|
+
### Layer 5
|
|
226
|
+
|
|
227
|
+
Project Features
|
|
228
|
+
|
|
229
|
+
Entire reusable systems.
|
|
230
|
+
|
|
231
|
+
Examples
|
|
232
|
+
|
|
233
|
+
- Quote System
|
|
234
|
+
- Newsletter
|
|
235
|
+
- Analytics
|
|
236
|
+
- Search
|
|
237
|
+
- Commerce
|
|
238
|
+
- Authentication
|
|
239
|
+
- OpenPanel
|
|
240
|
+
- Stripe
|
|
241
|
+
|
|
242
|
+
Each should install as a complete feature rather than individual files.
|
|
243
|
+
|
|
244
|
+
## Installation Philosophy
|
|
245
|
+
|
|
246
|
+
Everything should remain manifest-driven.
|
|
247
|
+
|
|
248
|
+
Avoid project-specific logic.
|
|
249
|
+
|
|
250
|
+
Every installer should know:
|
|
251
|
+
|
|
252
|
+
- files
|
|
253
|
+
- shared files
|
|
254
|
+
- dependencies
|
|
255
|
+
- registrations
|
|
256
|
+
- patch operations
|
|
257
|
+
- manual follow-up
|
|
258
|
+
|
|
259
|
+
from the manifest.
|
|
260
|
+
|
|
261
|
+
Avoid hardcoding block-specific behaviour.
|
|
262
|
+
|
|
263
|
+
## Safety Philosophy
|
|
264
|
+
|
|
265
|
+
The CLI must remain conservative.
|
|
266
|
+
|
|
267
|
+
Never overwrite existing work.
|
|
268
|
+
|
|
269
|
+
Always prefer reporting over guessing.
|
|
270
|
+
|
|
271
|
+
Continue protecting:
|
|
272
|
+
|
|
273
|
+
- destination collisions
|
|
274
|
+
- shared files
|
|
275
|
+
- backups
|
|
276
|
+
- dry-run
|
|
277
|
+
- manual dependency installation
|
|
278
|
+
- manual generators
|
|
279
|
+
|
|
280
|
+
Safety is more important than convenience.
|
|
281
|
+
|
|
282
|
+
## Future Installer Capabilities
|
|
283
|
+
|
|
284
|
+
The installer will become progressively smarter.
|
|
285
|
+
|
|
286
|
+
Potential future installers include:
|
|
287
|
+
|
|
288
|
+
- blocks
|
|
289
|
+
- globals
|
|
290
|
+
- components
|
|
291
|
+
- providers
|
|
292
|
+
- utilities
|
|
293
|
+
- hooks
|
|
294
|
+
- layouts
|
|
295
|
+
- Payload plugins
|
|
296
|
+
- admin customisations
|
|
297
|
+
- frontend features
|
|
298
|
+
|
|
299
|
+
Each installer should follow the same architecture.
|
|
300
|
+
|
|
301
|
+
## Codex Guidance
|
|
302
|
+
|
|
303
|
+
Codex should optimise for:
|
|
304
|
+
|
|
305
|
+
- reusable architecture
|
|
306
|
+
- manifest-driven behaviour
|
|
307
|
+
- minimal hardcoding
|
|
308
|
+
- safe source patching
|
|
309
|
+
- deterministic installs
|
|
310
|
+
- idempotent operations
|
|
311
|
+
- backward compatibility where appropriate
|
|
312
|
+
|
|
313
|
+
Avoid writing project-specific installers.
|
|
314
|
+
|
|
315
|
+
Everything should remain generic.
|
|
316
|
+
|
|
317
|
+
## Definition of Success
|
|
318
|
+
|
|
319
|
+
Eventually this should become a package where installing an entire Designs Dusted ecosystem into a fresh Payload project is largely declarative.
|
|
320
|
+
|
|
321
|
+
For example:
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
pnpm dlx blocks-dusted add DD-Hero
|
|
325
|
+
pnpm dlx blocks-dusted add DD-Header
|
|
326
|
+
pnpm dlx blocks-dusted add DD-Footer
|
|
327
|
+
pnpm dlx blocks-dusted add DD-QuoteSystem
|
|
328
|
+
pnpm dlx blocks-dusted add DD-Newsletter
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Each command should:
|
|
332
|
+
|
|
333
|
+
- install files
|
|
334
|
+
- install shared resources
|
|
335
|
+
- safely patch the project
|
|
336
|
+
- report manual follow-up steps
|
|
337
|
+
- never destroy existing work
|
|
338
|
+
|
|
339
|
+
without requiring the installer to understand each feature individually.
|
|
340
|
+
|
|
341
|
+
## Current Milestone
|
|
342
|
+
|
|
343
|
+
- Package published to npm.
|
|
344
|
+
- CLI verified from a clean Payload project.
|
|
345
|
+
- Manifest architecture established.
|
|
346
|
+
|
|
347
|
+
The next milestone is **improving the quality and breadth of installable assets**, not redesigning the CLI architecture. The architecture is now in place; future work should focus on expanding it while preserving its generic, manifest-driven design.
|
|
348
|
+
|
|
7
349
|
## Main Workflow
|
|
8
350
|
|
|
9
351
|
Run commands from the root of your Payload project:
|
|
@@ -13,6 +355,7 @@ pnpm dlx blocks-dusted list
|
|
|
13
355
|
pnpm dlx blocks-dusted doctor
|
|
14
356
|
pnpm dlx blocks-dusted add DD-Hero --dry-run
|
|
15
357
|
pnpm dlx blocks-dusted add DD-Hero
|
|
358
|
+
pnpm dlx blocks-dusted add RichText
|
|
16
359
|
```
|
|
17
360
|
|
|
18
361
|
Use `blocks-dusted list` first to see the exact available block names in the package. `DD-Hero` is an existing block in the current manifest registry.
|
|
@@ -20,7 +363,7 @@ Use `blocks-dusted list` first to see the exact available block names in the pac
|
|
|
20
363
|
The preferred install command after publication is:
|
|
21
364
|
|
|
22
365
|
```bash
|
|
23
|
-
pnpm dlx blocks-dusted add <
|
|
366
|
+
pnpm dlx blocks-dusted add <TemplateName>
|
|
24
367
|
```
|
|
25
368
|
|
|
26
369
|
## Commands
|
|
@@ -33,7 +376,8 @@ blocks-dusted doctor
|
|
|
33
376
|
blocks-dusted doctor --cwd C:\Projects\my-payload-site
|
|
34
377
|
blocks-dusted add DD-Hero --dry-run
|
|
35
378
|
blocks-dusted add DD-Hero --no-register
|
|
36
|
-
blocks-dusted add DD-Hero --cwd C:\Projects\my-payload-site
|
|
379
|
+
blocks-dusted add DD-Hero --cwd C:\Projects\my-payload-site
|
|
380
|
+
blocks-dusted add RichText --cwd C:\Projects\my-payload-site
|
|
37
381
|
```
|
|
38
382
|
|
|
39
383
|
`--cwd` targets a Payload project directory without changing your shell directory. Relative `--cwd` values resolve from the directory where you launched the command.
|
|
@@ -59,10 +403,630 @@ pnpm payload generate:importmap
|
|
|
59
403
|
|
|
60
404
|
The CLI does not run migrations or build the target project.
|
|
61
405
|
|
|
406
|
+
## Payload Block Standard
|
|
407
|
+
|
|
408
|
+
### Purpose
|
|
409
|
+
|
|
410
|
+
This standard defines the required structure for Payload CMS frontend blocks. The objective is consistent markup, predictable targeting, manageable admin configuration, and block-specific CSS support.
|
|
411
|
+
|
|
412
|
+
### Component Standards
|
|
413
|
+
|
|
414
|
+
#### Top-Level Wrapper
|
|
415
|
+
|
|
416
|
+
If the original block uses a top-level `<section>`, convert it to a `<div>`. `RenderBlocks` provides the section wrapper.
|
|
417
|
+
|
|
418
|
+
The top-level wrapper must include:
|
|
419
|
+
|
|
420
|
+
```tsx
|
|
421
|
+
id={sectionId ?? undefined}
|
|
422
|
+
data-block-type="[component_name]"
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
#### Section ID
|
|
426
|
+
|
|
427
|
+
Every converted block must support `sectionId`.
|
|
428
|
+
|
|
429
|
+
Destructure it from the generated Payload block props and apply it to the top-level wrapper:
|
|
430
|
+
|
|
431
|
+
```tsx
|
|
432
|
+
id={sectionId ?? undefined}
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
#### Custom CSS
|
|
436
|
+
|
|
437
|
+
Every converted block must support `customCSS`.
|
|
438
|
+
|
|
439
|
+
```tsx
|
|
440
|
+
<>
|
|
441
|
+
{customCSS && <style dangerouslySetInnerHTML={{ __html: customCSS }} />}
|
|
442
|
+
<div>{/* block */}</div>
|
|
443
|
+
</>
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
Do not remove or rewrite supplied custom CSS.
|
|
447
|
+
|
|
448
|
+
#### `useInjectStyle` Pattern
|
|
449
|
+
|
|
450
|
+
When original component SCSS must be converted, use the project `useInjectStyle` pattern:
|
|
451
|
+
|
|
452
|
+
```tsx
|
|
453
|
+
import { useInjectStyle } from "@/hooks/useInjectStyle";
|
|
454
|
+
|
|
455
|
+
const bannerStyles = `
|
|
456
|
+
/* converted styles */
|
|
457
|
+
`;
|
|
458
|
+
|
|
459
|
+
useInjectStyle(bannerStyles, "banner-inline-styles");
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
Required naming format:
|
|
463
|
+
|
|
464
|
+
```text
|
|
465
|
+
[component_name]Styles
|
|
466
|
+
[component_name]-inline-styles
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
If no converted CSS is required, the standard commented placeholders may remain.
|
|
470
|
+
|
|
471
|
+
#### Data Attributes
|
|
472
|
+
|
|
473
|
+
The top-level block must include:
|
|
474
|
+
|
|
475
|
+
```tsx
|
|
476
|
+
data-block-type="[component_name]"
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
Inner structural elements may use `data-type` when useful for identifying block structure. This is optional and depends on block complexity.
|
|
480
|
+
|
|
481
|
+
Example:
|
|
482
|
+
|
|
483
|
+
```tsx
|
|
484
|
+
data-type="banner-style"
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
RichText components should include:
|
|
488
|
+
|
|
489
|
+
```tsx
|
|
490
|
+
data-content-type="[component_name]-richtext"
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Payload Config Standards
|
|
494
|
+
|
|
495
|
+
#### Section ID Field
|
|
496
|
+
|
|
497
|
+
```ts
|
|
498
|
+
{
|
|
499
|
+
name: 'sectionId',
|
|
500
|
+
type: 'text',
|
|
501
|
+
label: 'Section ID',
|
|
502
|
+
admin: {
|
|
503
|
+
description: 'Optional HTML ID used for anchor links and section targeting.'
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
#### Custom CSS Field
|
|
509
|
+
|
|
510
|
+
Every converted block config must include:
|
|
511
|
+
|
|
512
|
+
```ts
|
|
513
|
+
{
|
|
514
|
+
name: 'customCSS',
|
|
515
|
+
type: 'code',
|
|
516
|
+
label: 'Custom CSS',
|
|
517
|
+
admin: {
|
|
518
|
+
language: 'css'
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
Do not use a plain textarea for custom CSS.
|
|
524
|
+
|
|
525
|
+
#### Admin Viewport Management
|
|
526
|
+
|
|
527
|
+
Do not place `customCSS` directly in a long flat field list. Custom CSS can become large and create excessive vertical scrolling in the Payload admin viewport.
|
|
528
|
+
|
|
529
|
+
Place `customCSS` in either:
|
|
530
|
+
|
|
531
|
+
- A dedicated `Custom CSS` tab.
|
|
532
|
+
- A collapsible field when tabs are unnecessary.
|
|
533
|
+
|
|
534
|
+
Prefer a dedicated `Custom CSS` tab when the block already benefits from grouped admin fields.
|
|
535
|
+
|
|
536
|
+
```ts
|
|
537
|
+
{
|
|
538
|
+
type: 'tabs',
|
|
539
|
+
tabs: [
|
|
540
|
+
{
|
|
541
|
+
label: 'Content',
|
|
542
|
+
fields: [
|
|
543
|
+
// block content fields
|
|
544
|
+
]
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
label: 'Custom CSS',
|
|
548
|
+
fields: [
|
|
549
|
+
{
|
|
550
|
+
name: 'customCSS',
|
|
551
|
+
type: 'code',
|
|
552
|
+
label: 'Custom CSS',
|
|
553
|
+
admin: {
|
|
554
|
+
language: 'css'
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
]
|
|
558
|
+
}
|
|
559
|
+
]
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
#### Existing Fields and Behaviour
|
|
564
|
+
|
|
565
|
+
Preserve existing block fields, options, defaults, required states, frontend appearance, responsiveness, animations, pseudo-elements, specificity, and behaviour.
|
|
566
|
+
|
|
567
|
+
Do not invent new content fields beyond the standard `sectionId` and `customCSS` additions unless explicitly requested.
|
|
568
|
+
|
|
569
|
+
Do not manually alter generated Payload interfaces.
|
|
570
|
+
|
|
571
|
+
### Canonical Component Pattern
|
|
572
|
+
|
|
573
|
+
```tsx
|
|
574
|
+
import type { BannerBlock as BannerBlockProps } from "src/payload-types";
|
|
575
|
+
|
|
576
|
+
import { cn } from "@/utilities/ui";
|
|
577
|
+
import React from "react";
|
|
578
|
+
import RichText from "@/components/RichText";
|
|
579
|
+
|
|
580
|
+
// import { useInjectStyle } from '@/hooks/useInjectStyle' - uncomment if required
|
|
581
|
+
|
|
582
|
+
type Props = {
|
|
583
|
+
className?: string;
|
|
584
|
+
} & BannerBlockProps;
|
|
585
|
+
|
|
586
|
+
/* Inlined CSS (converted from the original SCSS to [component_name]Styles) format */
|
|
587
|
+
// const bannerStyles = `
|
|
588
|
+
// // add styles here if needed
|
|
589
|
+
// `
|
|
590
|
+
|
|
591
|
+
export const BannerBlock: React.FC<Props> = ({
|
|
592
|
+
className,
|
|
593
|
+
content,
|
|
594
|
+
style,
|
|
595
|
+
customCSS,
|
|
596
|
+
sectionId,
|
|
597
|
+
}) => {
|
|
598
|
+
// Inject styles once, regardless of how many instances are rendered.
|
|
599
|
+
// Keep format standardised: [component_name]Styles, [component_name]-inline-styles.
|
|
600
|
+
// useInjectStyle(bannerStyles, 'banner-inline-styles') - uncomment if required
|
|
601
|
+
|
|
602
|
+
return (
|
|
603
|
+
<>
|
|
604
|
+
{customCSS && <style dangerouslySetInnerHTML={{ __html: customCSS }} />}
|
|
605
|
+
<div
|
|
606
|
+
id={sectionId ?? undefined}
|
|
607
|
+
data-block-type="banner"
|
|
608
|
+
className={cn("mx-auto my-4 w-full", className)}
|
|
609
|
+
>
|
|
610
|
+
<div data-type="banner-style">
|
|
611
|
+
<RichText
|
|
612
|
+
data-content-type="banner-richtext"
|
|
613
|
+
data={content}
|
|
614
|
+
enableGutter={false}
|
|
615
|
+
enableProse={true}
|
|
616
|
+
/>
|
|
617
|
+
</div>
|
|
618
|
+
</div>
|
|
619
|
+
</>
|
|
620
|
+
);
|
|
621
|
+
};
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
### Execution Prompt
|
|
625
|
+
|
|
626
|
+
> Review the target Payload CMS block component and its block config, then update both to comply with `Payload Block Standard.md`.
|
|
627
|
+
>
|
|
628
|
+
> Inspect the existing component and config before editing. Preserve the block's current appearance, responsive behaviour, animations, pseudo-elements, selectors, specificity, field options, defaults, required states, and functionality.
|
|
629
|
+
>
|
|
630
|
+
> Apply the standard carefully:
|
|
631
|
+
>
|
|
632
|
+
> - Convert a top-level `<section>` to `<div>` because `RenderBlocks` provides the section wrapper.
|
|
633
|
+
> - Add `sectionId` support and apply `id={sectionId ?? undefined}` to the top-level block wrapper.
|
|
634
|
+
> - Add `data-block-type="[component_name]"` to the top-level block wrapper.
|
|
635
|
+
> - Add useful `data-type` attributes only where inner structural identification is beneficial.
|
|
636
|
+
> - Add `data-content-type="[component_name]-richtext"` to RichText components.
|
|
637
|
+
> - Add `customCSS` support and render it with `<style dangerouslySetInnerHTML={{ __html: customCSS }} />`.
|
|
638
|
+
> - If component SCSS exists, convert it to the `useInjectStyle` pattern using `[component_name]Styles` and `[component_name]-inline-styles`.
|
|
639
|
+
> - Add matching `sectionId` and `customCSS` fields to the Payload block config.
|
|
640
|
+
> - `customCSS` must use `type: 'code'` with `admin.language: 'css'`.
|
|
641
|
+
> - Place `customCSS` in a dedicated tab or collapsible field so long CSS does not create excessive admin viewport scrolling.
|
|
642
|
+
> - Preserve all existing block-specific fields and behaviour.
|
|
643
|
+
> - Do not invent fields, redesign the component, refactor unrelated code, or change behaviour outside this standard.
|
|
644
|
+
>
|
|
645
|
+
> Update only the files required for this block. Review the final diff against the standard before completing the task.
|
|
646
|
+
|
|
647
|
+
## Payload Rich Text Dusted Standard
|
|
648
|
+
|
|
649
|
+
### Purpose - RichText Dusted Standard
|
|
650
|
+
|
|
651
|
+
This document defines the standard folder structure and implementation rules for a reusable frontend RichText component in a Payload CMS project.
|
|
652
|
+
|
|
653
|
+
This is a standard, not a requirement that every Payload project must contain every optional feature described below. Always inspect the target project before making changes. Preserve project-specific requirements and add only the parts that the project needs.
|
|
654
|
+
|
|
655
|
+
The objective is to keep RichText rendering:
|
|
656
|
+
|
|
657
|
+
- predictable;
|
|
658
|
+
- reusable;
|
|
659
|
+
- typed;
|
|
660
|
+
- easy to extend;
|
|
661
|
+
- separated by responsibility;
|
|
662
|
+
- compatible with the target project's Payload schema;
|
|
663
|
+
- free from unrelated project-specific assumptions.
|
|
664
|
+
|
|
665
|
+
### Standard Folder Structure
|
|
666
|
+
|
|
667
|
+
```text
|
|
668
|
+
src/
|
|
669
|
+
+-- components/
|
|
670
|
+
+-- RichText/
|
|
671
|
+
+-- index.tsx
|
|
672
|
+
+-- converter/
|
|
673
|
+
+-- index.tsx
|
|
674
|
+
+-- internalLinks.tsx
|
|
675
|
+
+-- textConverter.tsx
|
|
676
|
+
+-- componentConverter/
|
|
677
|
+
+-- blocks.tsx
|
|
678
|
+
+-- types.ts
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
### Base and Optional Files
|
|
682
|
+
|
|
683
|
+
#### Base RichText structure
|
|
684
|
+
|
|
685
|
+
These files form the base structure:
|
|
686
|
+
|
|
687
|
+
```text
|
|
688
|
+
src/components/RichText/index.tsx
|
|
689
|
+
src/components/RichText/converter/index.tsx
|
|
690
|
+
src/components/RichText/converter/internalLinks.tsx
|
|
691
|
+
src/components/RichText/converter/textConverter.tsx
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
#### Optional embedded-block extension
|
|
695
|
+
|
|
696
|
+
Add this folder only when the target project permits Payload blocks to be embedded inside RichText:
|
|
697
|
+
|
|
698
|
+
```text
|
|
699
|
+
src/components/RichText/converter/componentConverter/blocks.tsx
|
|
700
|
+
src/components/RichText/converter/componentConverter/types.ts
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
Do not create placeholder block mappings when RichText does not support embedded blocks.
|
|
704
|
+
|
|
705
|
+
### Responsibility of Each File
|
|
706
|
+
|
|
707
|
+
#### `src/components/RichText/index.tsx`
|
|
708
|
+
|
|
709
|
+
This is the public RichText component and the only normal import entry point for other frontend components.
|
|
710
|
+
|
|
711
|
+
It must:
|
|
712
|
+
|
|
713
|
+
- accept the RichText value produced by the target Payload field;
|
|
714
|
+
- handle an empty or missing value safely;
|
|
715
|
+
- call the RichText renderer with the project's converter configuration;
|
|
716
|
+
- accept presentation props only when the project needs them;
|
|
717
|
+
- preserve the caller's `className` instead of replacing it;
|
|
718
|
+
- remain focused on rendering the complete RichText value.
|
|
719
|
+
|
|
720
|
+
Other files should normally import RichText from:
|
|
721
|
+
|
|
722
|
+
```tsx
|
|
723
|
+
import { RichText } from "@/components/RichText";
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
Use the actual export style already established by the target project. Do not change named exports to default exports, or default exports to named exports, unless the task explicitly requires it.
|
|
727
|
+
|
|
728
|
+
Do not place individual Lexical node conversion logic directly in this file.
|
|
729
|
+
|
|
730
|
+
#### `src/components/RichText/converter/index.tsx`
|
|
731
|
+
|
|
732
|
+
This is the converter entry point and orchestration layer.
|
|
733
|
+
|
|
734
|
+
It must:
|
|
735
|
+
|
|
736
|
+
- assemble the converters used by RichText;
|
|
737
|
+
- connect the text converter;
|
|
738
|
+
- connect the internal-link converter;
|
|
739
|
+
- connect embedded-block converters only when supported;
|
|
740
|
+
- preserve required default converters from the Payload Lexical renderer;
|
|
741
|
+
- keep converter registration in a clear and deterministic order;
|
|
742
|
+
- export the converter value or converter factory required by `RichText/index.tsx`.
|
|
743
|
+
|
|
744
|
+
Do not turn this file into one large converter containing all text, link, relationship, upload and block rendering logic.
|
|
745
|
+
|
|
746
|
+
#### `src/components/RichText/converter/internalLinks.tsx`
|
|
747
|
+
|
|
748
|
+
This file owns the rendering and URL resolution of Payload internal-document links.
|
|
749
|
+
|
|
750
|
+
It must:
|
|
751
|
+
|
|
752
|
+
- inspect the linked relationship safely;
|
|
753
|
+
- determine the linked document type using the actual project schema;
|
|
754
|
+
- resolve the URL from the linked document's real fields;
|
|
755
|
+
- support only collections or globals that exist in the target project;
|
|
756
|
+
- return a safe fallback when the relationship is missing, unresolved or unsupported;
|
|
757
|
+
- preserve link children and relevant attributes;
|
|
758
|
+
- use the project's existing link or URL utilities when available.
|
|
759
|
+
|
|
760
|
+
It must not:
|
|
761
|
+
|
|
762
|
+
- assume every project uses the same collections;
|
|
763
|
+
- assume every linked document has a `slug`;
|
|
764
|
+
- invent routes;
|
|
765
|
+
- hardcode a route copied from another project without verifying it;
|
|
766
|
+
- treat an unresolved relationship as a valid URL.
|
|
767
|
+
|
|
768
|
+
Examples of collection names, route prefixes and slug rules are project variations. They do not belong in the reusable standard unless the target project actually uses them.
|
|
769
|
+
|
|
770
|
+
#### `src/components/RichText/converter/textConverter.tsx`
|
|
771
|
+
|
|
772
|
+
This file owns the conversion and rendering of Lexical text nodes.
|
|
773
|
+
|
|
774
|
+
It must:
|
|
775
|
+
|
|
776
|
+
- preserve the text content;
|
|
777
|
+
- preserve every supported text format used by the target editor;
|
|
778
|
+
- combine compatible formats when more than one format is applied;
|
|
779
|
+
- render unsupported or unformatted text safely;
|
|
780
|
+
- use valid React elements;
|
|
781
|
+
- keep formatting behaviour independent from block rendering.
|
|
782
|
+
|
|
783
|
+
Possible text formats may include:
|
|
784
|
+
|
|
785
|
+
- bold;
|
|
786
|
+
- italic;
|
|
787
|
+
- underline;
|
|
788
|
+
- strikethrough;
|
|
789
|
+
- code;
|
|
790
|
+
- subscript;
|
|
791
|
+
- superscript.
|
|
792
|
+
|
|
793
|
+
The actual supported formats must be taken from the target project's editor configuration and existing implementation. Do not add formatting merely because it appears in this list.
|
|
794
|
+
|
|
795
|
+
#### `src/components/RichText/converter/componentConverter/blocks.tsx`
|
|
796
|
+
|
|
797
|
+
This file owns the mapping between RichText embedded-block nodes and their React components.
|
|
798
|
+
|
|
799
|
+
Create it only if blocks can be embedded in RichText.
|
|
800
|
+
|
|
801
|
+
It must:
|
|
802
|
+
|
|
803
|
+
- map each supported Payload block slug to the correct frontend component;
|
|
804
|
+
- pass the block data using the prop shape expected by that component;
|
|
805
|
+
- return a safe result for an unknown or malformed block;
|
|
806
|
+
- keep project-specific block imports in this file;
|
|
807
|
+
- make the list of supported embedded blocks easy to review;
|
|
808
|
+
- preserve type safety where the generated Payload types allow it.
|
|
809
|
+
|
|
810
|
+
It must not:
|
|
811
|
+
|
|
812
|
+
- import every block in the repository automatically;
|
|
813
|
+
- assume every page block is suitable inside RichText;
|
|
814
|
+
- reuse the main page `RenderBlocks` component unless its contract is verified as compatible;
|
|
815
|
+
- silently invent props for a block component;
|
|
816
|
+
- add block mappings that do not exist in the target Payload schema.
|
|
817
|
+
|
|
818
|
+
#### `src/components/RichText/converter/componentConverter/types.ts`
|
|
819
|
+
|
|
820
|
+
This file contains types used specifically by embedded component or block conversion.
|
|
821
|
+
|
|
822
|
+
It must:
|
|
823
|
+
|
|
824
|
+
- describe the actual embedded-block node or converter contract;
|
|
825
|
+
- reuse generated Payload types where practical;
|
|
826
|
+
- keep local helper types narrow;
|
|
827
|
+
- avoid duplicating the entire generated block schema;
|
|
828
|
+
- contain types only, unless a small type guard is genuinely required.
|
|
829
|
+
|
|
830
|
+
Do not manually edit `src/payload-types.ts` to make these types compile. Payload-generated types must be regenerated using the project's existing Payload type-generation command.
|
|
831
|
+
|
|
832
|
+
### Required Implementation Process
|
|
833
|
+
|
|
834
|
+
An AI or developer implementing this standard must complete these steps in order.
|
|
835
|
+
|
|
836
|
+
#### 1. Inspect the target project
|
|
837
|
+
|
|
838
|
+
Before writing code, locate and read:
|
|
839
|
+
|
|
840
|
+
- the Payload RichText field configuration;
|
|
841
|
+
- the Lexical editor configuration;
|
|
842
|
+
- the generated RichText data type;
|
|
843
|
+
- existing link and URL utilities;
|
|
844
|
+
- collections or globals allowed as internal links;
|
|
845
|
+
- embedded block definitions, if any;
|
|
846
|
+
- existing frontend block components;
|
|
847
|
+
- the project's import alias configuration;
|
|
848
|
+
- the project's package versions and installed RichText packages.
|
|
849
|
+
|
|
850
|
+
Do not start by copying a RichText component from another repository.
|
|
851
|
+
|
|
852
|
+
#### 2. Classify the project variation
|
|
853
|
+
|
|
854
|
+
Determine whether the project needs:
|
|
855
|
+
|
|
856
|
+
- base RichText rendering only;
|
|
857
|
+
- internal links;
|
|
858
|
+
- uploads or media rendering;
|
|
859
|
+
- custom text formats;
|
|
860
|
+
- relationships;
|
|
861
|
+
- embedded blocks;
|
|
862
|
+
- project-specific converters.
|
|
863
|
+
|
|
864
|
+
Only install the necessary variation.
|
|
865
|
+
|
|
866
|
+
#### 3. Preserve existing behaviour
|
|
867
|
+
|
|
868
|
+
If RichText already exists, preserve:
|
|
869
|
+
|
|
870
|
+
- supported node types;
|
|
871
|
+
- internal-link routes;
|
|
872
|
+
- external-link behaviour;
|
|
873
|
+
- classes and styling hooks;
|
|
874
|
+
- media behaviour;
|
|
875
|
+
- embedded blocks;
|
|
876
|
+
- generated types;
|
|
877
|
+
- public component props;
|
|
878
|
+
- current import paths.
|
|
879
|
+
|
|
880
|
+
Refactoring the folder structure does not authorise removing behaviour.
|
|
881
|
+
|
|
882
|
+
#### 4. Separate responsibilities
|
|
883
|
+
|
|
884
|
+
Move logic to the file that owns it:
|
|
885
|
+
|
|
886
|
+
| Concern | File |
|
|
887
|
+
| -------------------------------- | ------------------------------- |
|
|
888
|
+
| Public RichText component | `RichText/index.tsx` |
|
|
889
|
+
| Converter assembly | `converter/index.tsx` |
|
|
890
|
+
| Internal-document URL resolution | `converter/internalLinks.tsx` |
|
|
891
|
+
| Text-node formatting | `converter/textConverter.tsx` |
|
|
892
|
+
| Embedded-block mapping | `componentConverter/blocks.tsx` |
|
|
893
|
+
| Embedded-block converter types | `componentConverter/types.ts` |
|
|
894
|
+
|
|
895
|
+
Do not create additional files without a real project requirement.
|
|
896
|
+
|
|
897
|
+
#### 5. Validate
|
|
898
|
+
|
|
899
|
+
Run the target project's existing:
|
|
900
|
+
|
|
901
|
+
- formatter;
|
|
902
|
+
- linter;
|
|
903
|
+
- TypeScript check;
|
|
904
|
+
- relevant tests;
|
|
905
|
+
- production build, when within the task scope.
|
|
906
|
+
|
|
907
|
+
If the Payload schema or generated types changed, run the project's existing Payload type-generation command before the final type check.
|
|
908
|
+
|
|
909
|
+
Do not report completion when imports, types or converter mappings are unverified.
|
|
910
|
+
|
|
911
|
+
### Import and Dependency Rules
|
|
912
|
+
|
|
913
|
+
- Use packages already installed by the target project.
|
|
914
|
+
- Verify exact APIs against the installed package versions.
|
|
915
|
+
- Follow the project's existing alias and import conventions.
|
|
916
|
+
- Prefer generated Payload types over broad `any` types.
|
|
917
|
+
- Use `unknown` plus narrowing when incoming converter data cannot be trusted.
|
|
918
|
+
- Avoid circular imports between RichText and block components.
|
|
919
|
+
- Do not import server-only modules into client components.
|
|
920
|
+
- Add `'use client'` only when the component genuinely uses client-only React features.
|
|
921
|
+
- Do not add a package solely because another Dusted project uses it.
|
|
922
|
+
- Do not change package versions unless explicitly required.
|
|
923
|
+
|
|
924
|
+
### Data and Safety Rules
|
|
925
|
+
|
|
926
|
+
- Treat RichText data as nullable unless the project type proves otherwise.
|
|
927
|
+
- Handle missing relationships and deleted linked documents safely.
|
|
928
|
+
- Do not render `undefined`, malformed URLs or invented fallbacks as working links.
|
|
929
|
+
- Do not use `dangerouslySetInnerHTML` merely to bypass converter work.
|
|
930
|
+
- Do not discard unknown content without making the fallback behaviour deliberate.
|
|
931
|
+
- Do not log the full RichText document in production.
|
|
932
|
+
- Do not place private Payload document data into frontend URLs or attributes.
|
|
933
|
+
|
|
934
|
+
### Styling Rules
|
|
935
|
+
|
|
936
|
+
The RichText renderer provides structure and semantic output. Styling remains project-specific.
|
|
937
|
+
|
|
938
|
+
- Preserve existing classes and data attributes.
|
|
939
|
+
- Allow a caller-provided `className` when the current component contract supports it.
|
|
940
|
+
- Do not copy typography styles from another project as part of this standard.
|
|
941
|
+
- Do not hardcode a theme.
|
|
942
|
+
- Do not place an entire project's prose CSS inside the converter.
|
|
943
|
+
- Keep semantic elements such as headings, paragraphs, lists, links and code output intact.
|
|
944
|
+
|
|
945
|
+
For RichText used inside a reusable Payload block, follow the block standard for any required content hook, including:
|
|
946
|
+
|
|
947
|
+
```tsx
|
|
948
|
+
data-content-type="[component_name]-richtext"
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
Replace `[component_name]` with the actual component identifier. Do not use the placeholder literally.
|
|
952
|
+
|
|
953
|
+
### Extension Rules
|
|
954
|
+
|
|
955
|
+
The structure may be extended when the target project genuinely requires another distinct converter concern.
|
|
956
|
+
|
|
957
|
+
Examples may include:
|
|
958
|
+
|
|
959
|
+
```text
|
|
960
|
+
converter/
|
|
961
|
+
+-- uploads.tsx
|
|
962
|
+
+-- relationships.tsx
|
|
963
|
+
+-- headings.tsx
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
Before adding a file, confirm that:
|
|
967
|
+
|
|
968
|
+
1. the relevant node exists in the target editor configuration;
|
|
969
|
+
2. the logic is substantial enough to deserve separation;
|
|
970
|
+
3. the responsibility does not already belong to an existing file;
|
|
971
|
+
4. the new file does not introduce a project-specific feature into the reusable base unnecessarily.
|
|
972
|
+
|
|
973
|
+
Variations must be documented rather than forced into all projects.
|
|
974
|
+
|
|
975
|
+
### Prohibited Shortcuts
|
|
976
|
+
|
|
977
|
+
Do not:
|
|
978
|
+
|
|
979
|
+
- place all converter logic in `RichText/index.tsx`;
|
|
980
|
+
- copy imports, collection slugs or routes from another project without checking;
|
|
981
|
+
- create empty files solely to match the tree;
|
|
982
|
+
- add embedded-block support to a project that does not use it;
|
|
983
|
+
- map unsupported blocks;
|
|
984
|
+
- edit generated Payload types manually;
|
|
985
|
+
- replace strict types with `any` merely to silence errors;
|
|
986
|
+
- remove default Lexical converters accidentally;
|
|
987
|
+
- assume package APIs are identical across Payload versions;
|
|
988
|
+
- rename the public RichText import path without updating every consumer;
|
|
989
|
+
- claim the implementation is complete without running the available validation commands.
|
|
990
|
+
|
|
991
|
+
### Completion Checklist
|
|
992
|
+
|
|
993
|
+
Before marking RichText work complete, confirm every applicable item:
|
|
994
|
+
|
|
995
|
+
- [ ] The target Payload editor configuration was inspected.
|
|
996
|
+
- [ ] The target project's existing RichText behaviour was inspected.
|
|
997
|
+
- [ ] The public component is located at `src/components/RichText/index.tsx`.
|
|
998
|
+
- [ ] Converter assembly is located at `converter/index.tsx`.
|
|
999
|
+
- [ ] Internal-link logic is isolated in `internalLinks.tsx`.
|
|
1000
|
+
- [ ] Text formatting is isolated in `textConverter.tsx`.
|
|
1001
|
+
- [ ] `componentConverter/` exists only if embedded blocks are supported.
|
|
1002
|
+
- [ ] Every embedded block mapping refers to a real schema block and real component.
|
|
1003
|
+
- [ ] Internal routes are derived from verified project rules.
|
|
1004
|
+
- [ ] Empty, missing and unresolved values are handled safely.
|
|
1005
|
+
- [ ] Existing styles, classes and attributes are preserved.
|
|
1006
|
+
- [ ] No generated Payload type file was manually edited.
|
|
1007
|
+
- [ ] No unnecessary dependency was added.
|
|
1008
|
+
- [ ] Formatting passed.
|
|
1009
|
+
- [ ] Linting passed.
|
|
1010
|
+
- [ ] Type checking passed.
|
|
1011
|
+
- [ ] Relevant tests passed.
|
|
1012
|
+
- [ ] The production build passed when it was part of the requested scope.
|
|
1013
|
+
|
|
1014
|
+
### Definition of Done
|
|
1015
|
+
|
|
1016
|
+
The RichText standard is correctly implemented when:
|
|
1017
|
+
|
|
1018
|
+
1. other components have one clear RichText import entry point;
|
|
1019
|
+
2. converter responsibilities are separated into the standard files;
|
|
1020
|
+
3. the implementation matches the target Payload schema and installed package versions;
|
|
1021
|
+
4. project-specific variations are included only when needed;
|
|
1022
|
+
5. existing behaviour has not been lost;
|
|
1023
|
+
6. malformed or missing data fails safely;
|
|
1024
|
+
7. the target project's validation commands pass.
|
|
1025
|
+
|
|
62
1026
|
## Publishing Identities
|
|
63
1027
|
|
|
64
1028
|
- GitHub repository: `https://github.com/Hadizainal/blocks-dusted.git`
|
|
65
1029
|
- npm package: `blocks-dusted`
|
|
66
1030
|
- CLI executable: `blocks-dusted`
|
|
67
1031
|
|
|
68
|
-
The repository can remain private while the npm package is published separately.
|
|
1032
|
+
The repository can remain private while the npm package is published separately.
|