@dani-builder/strapi-client 0.2.0 → 0.4.0

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 (101) hide show
  1. package/AGENTS.md +9 -5
  2. package/LICENSE +21 -0
  3. package/README.md +50 -0
  4. package/dist/api/articles.d.ts +3 -0
  5. package/dist/api/articles.d.ts.map +1 -1
  6. package/dist/api/articles.js +8 -5
  7. package/dist/api/articles.js.map +1 -1
  8. package/dist/api/authors.d.ts +2 -0
  9. package/dist/api/authors.d.ts.map +1 -1
  10. package/dist/api/authors.js +5 -2
  11. package/dist/api/authors.js.map +1 -1
  12. package/dist/api/categories.d.ts +2 -0
  13. package/dist/api/categories.d.ts.map +1 -1
  14. package/dist/api/categories.js +4 -1
  15. package/dist/api/categories.js.map +1 -1
  16. package/dist/api/faqs.d.ts +2 -0
  17. package/dist/api/faqs.d.ts.map +1 -1
  18. package/dist/api/faqs.js +4 -1
  19. package/dist/api/faqs.js.map +1 -1
  20. package/dist/api/global.js +1 -1
  21. package/dist/api/global.js.map +1 -1
  22. package/dist/api/inquiry.js +1 -1
  23. package/dist/api/inquiry.js.map +1 -1
  24. package/dist/api/navigation.js +1 -1
  25. package/dist/api/navigation.js.map +1 -1
  26. package/dist/api/pages.d.ts +9 -1
  27. package/dist/api/pages.d.ts.map +1 -1
  28. package/dist/api/pages.js +26 -9
  29. package/dist/api/pages.js.map +1 -1
  30. package/dist/api/series.d.ts +2 -0
  31. package/dist/api/series.d.ts.map +1 -1
  32. package/dist/api/series.js +5 -2
  33. package/dist/api/series.js.map +1 -1
  34. package/dist/api/site-settings.js +1 -1
  35. package/dist/api/site-settings.js.map +1 -1
  36. package/dist/api/tags.d.ts +2 -0
  37. package/dist/api/tags.d.ts.map +1 -1
  38. package/dist/api/tags.js +4 -1
  39. package/dist/api/tags.js.map +1 -1
  40. package/dist/client/create-client.d.ts +7 -3
  41. package/dist/client/create-client.d.ts.map +1 -1
  42. package/dist/client/create-client.js +13 -5
  43. package/dist/client/create-client.js.map +1 -1
  44. package/dist/client/index.d.ts +2 -2
  45. package/dist/client/index.d.ts.map +1 -1
  46. package/dist/client/index.js +1 -1
  47. package/dist/client/index.js.map +1 -1
  48. package/dist/index.d.ts +7 -7
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +4 -4
  51. package/dist/index.js.map +1 -1
  52. package/dist/populate/builders.d.ts +12 -0
  53. package/dist/populate/builders.d.ts.map +1 -1
  54. package/dist/populate/builders.js +10 -0
  55. package/dist/populate/builders.js.map +1 -1
  56. package/dist/populate/core-blocks.d.ts.map +1 -1
  57. package/dist/populate/core-blocks.js +15 -9
  58. package/dist/populate/core-blocks.js.map +1 -1
  59. package/dist/types/components/blocks.d.ts +12 -11
  60. package/dist/types/components/blocks.d.ts.map +1 -1
  61. package/dist/types/components/index.d.ts +1 -1
  62. package/dist/types/components/index.d.ts.map +1 -1
  63. package/dist/types/components/shared.d.ts +14 -3
  64. package/dist/types/components/shared.d.ts.map +1 -1
  65. package/dist/types/components/shared.js +1 -1
  66. package/dist/types/content-types/article.d.ts +3 -1
  67. package/dist/types/content-types/article.d.ts.map +1 -1
  68. package/dist/types/content-types/article.js +1 -1
  69. package/dist/types/content-types/article.js.map +1 -1
  70. package/dist/types/content-types/author.js +1 -1
  71. package/dist/types/content-types/author.js.map +1 -1
  72. package/dist/types/content-types/category.js +1 -1
  73. package/dist/types/content-types/category.js.map +1 -1
  74. package/dist/types/content-types/faq.js +1 -1
  75. package/dist/types/content-types/faq.js.map +1 -1
  76. package/dist/types/content-types/global.js +1 -1
  77. package/dist/types/content-types/global.js.map +1 -1
  78. package/dist/types/content-types/inquiry.js +1 -1
  79. package/dist/types/content-types/inquiry.js.map +1 -1
  80. package/dist/types/content-types/navigation.js +1 -1
  81. package/dist/types/content-types/navigation.js.map +1 -1
  82. package/dist/types/content-types/page.d.ts +12 -3
  83. package/dist/types/content-types/page.d.ts.map +1 -1
  84. package/dist/types/content-types/page.js +1 -1
  85. package/dist/types/content-types/page.js.map +1 -1
  86. package/dist/types/content-types/series.js +1 -1
  87. package/dist/types/content-types/series.js.map +1 -1
  88. package/dist/types/content-types/site-settings.js +1 -1
  89. package/dist/types/content-types/site-settings.js.map +1 -1
  90. package/dist/types/content-types/tag.js +1 -1
  91. package/dist/types/content-types/tag.js.map +1 -1
  92. package/dist/types/index.d.ts +2 -2
  93. package/dist/types/index.d.ts.map +1 -1
  94. package/dist/types/strapi.d.ts +10 -0
  95. package/dist/types/strapi.d.ts.map +1 -1
  96. package/docs/api-guide.md +22 -22
  97. package/docs/block-reference.md +147 -554
  98. package/docs/components.md +234 -0
  99. package/docs/content-types.md +173 -382
  100. package/docs/elements.md +50 -0
  101. package/package.json +25 -8
@@ -1,601 +1,194 @@
1
- # Block Reference
2
-
3
- ## Quick Reference Table
4
-
5
- | Block | `__component` | Variants | Media Policy | Items Type |
6
- |-------|--------------|----------|-------------|-----------|
7
- | Hero | `blocks.hero` | `side-by-side`, `media-extending`, `fullscreen-media`, `stacked-media` | heroMedia: images+videos | — |
8
- | Features | `blocks.features` | `simple-grid`, `dual-column`, `media-aside`, `media-aside-compact` | media: images only | `FeatureItem[]` |
9
- | CTA | `blocks.cta` | `inline-spread`, `inline-centered`, `inline-stacked`, `card-stacked`, `card-centered`, `card-horizontal` | ctaMedia: images+videos | — |
10
- | Slider | `blocks.slider` | `cover-flow`, `card-slider` | — | `SliderItem[]` |
11
- | InquiryForm | `blocks.inquiry-form` | — | — | — |
12
- | FAQ | `blocks.faq` | — | — | `FaqDocument[]` (relation) |
13
- | Highlights | `blocks.highlights` | `dual-column`, `triple-column`, `alternating` | media: images+videos | `HighlightItem[]` |
14
- | BentoGrid | `blocks.bento-grid` | — (layout via `columns` + item spans) | — | `BentoItem[]` |
15
- | Testimonials | `blocks.testimonials` | `centered`, `side-by-side`, `card-grid`, `subtle-grid` | media: images+videos | `TestimonialItem[]` |
16
- | LogoCloud | `blocks.logo-cloud` | `inline`, `grid`, `split` | — | `LogoItem[]` |
17
- | Stats | `blocks.stats` | `simple`, `card-grid`, `split` | media: images+videos | `StatItem[]` |
18
- | Pricing | `blocks.pricing` | `two-column`, `three-column`, `single`, `with-comparison` | — | `PricingTier[]` |
19
- | Content | `blocks.content` | `prose`, `wide`, `full-width` | — | — |
20
- | Team | `blocks.team` | `grid`, `large-image`, `compact` | — | `TeamMember[]` |
21
-
22
- ---
23
-
24
- ## Media Policy Summary
25
-
26
- ### Images + Videos
27
-
28
- These fields accept both image and video uploads. Render `<video>` or `<img>` based on `asset.mime`.
29
-
30
- | Field | Component |
31
- |-------|-----------|
32
- | `heroMedia` | `blocks.hero` |
33
- | `ctaMedia` | `blocks.cta` |
34
- | `media` | `blocks.highlights` |
35
- | `media` | `blocks.testimonials` |
36
- | `media` | `blocks.stats` |
37
- | `media` | `shared.highlight-item` |
38
- | `media` | `shared.slider-item` |
39
-
40
- ### Images Only
41
-
42
- These fields reject video uploads. Always render as `<img>`.
43
-
44
- | Field | Component |
45
- |-------|-----------|
46
- | `media` | `blocks.features` |
47
- | `backgroundImage` | `elements.section` |
48
- | `logo` | `elements.footer` |
49
- | `logo` | `shared.logo-item` |
50
- | `avatar` | `shared.testimonial-item` |
51
- | `logo` | `shared.testimonial-item` |
52
- | `media` | `shared.bento-item` |
53
- | `photo` | `shared.team-member` |
54
- | `ogImage` | `shared.seo` |
55
- | `mainLogo` | Navigation CT |
56
- | `darkLogo` | Navigation CT |
57
- | `favicon` | Global CT |
58
- | `cover` | Article CT |
59
- | `gallery` | Article CT |
60
- | `avatar` | Author CT |
61
- | `cover` | Series CT |
62
-
63
- ---
64
-
65
- ## Section (`elements.section`)
66
-
67
- Every block has an optional `section: Section | null` field. Section provides the heading, theme, and background for the block. It can also appear standalone in `Page.blocks` as a separator.
68
-
69
- | Field | Type | Description |
70
- |-------|------|-------------|
71
- | `heading` | `string \| null` | Section heading |
72
- | `subheading` | `string \| null` | Subheading |
73
- | `kickerText` | `string \| null` | Small text above heading |
74
- | `anchorId` | `string \| null` | Anchor ID for in-page navigation |
75
- | `headerAlign` | `'auto' \| 'left' \| 'center' \| 'right' \| null` | Heading alignment |
76
- | `theme` | `'default' \| 'light' \| 'dark' \| 'accent' \| 'muted' \| 'contrast'` | Tailwind preset key |
77
- | `backgroundImage` | `StrapiMedia \| null` | Background image (images only) |
78
- | `backgroundImageOpacity` | `number \| null` | Opacity 0–1 for background image overlay |
79
-
80
- **Constraints:**
81
- - `theme` maps to a Tailwind preset in the frontend theme config. DO NOT use arbitrary CSS colors.
82
- - `backgroundImage` is images-only. DO NOT attempt to use video backgrounds here.
83
-
84
- ---
85
-
86
- ## Hero (`blocks.hero`)
87
-
88
- **`__component`: `'blocks.hero'`**
89
- **Used in:** Page.blocks, Global.siteWideBlocks
90
-
91
- ### Variants
92
-
93
- | Value | Layout |
94
- |-------|--------|
95
- | `side-by-side` | Text on one side, media on the other — split layout |
96
- | `media-extending` | Media extends beyond container bounds |
97
- | `fullscreen-media` | Full-viewport background media with text overlay |
98
- | `stacked-media` | Media below the text content |
99
-
100
- ### Fields
101
-
102
- | Field | Type | Description |
103
- |-------|------|-------------|
104
- | `variant` | enum | Layout variant (see above) |
105
- | `section` | `Section \| null` | Section wrapper |
106
- | `heroMedia` | `StrapiMedia \| null` | Hero media — **images+videos** |
107
- | `ctaText` | `string \| null` | Supplementary CTA text |
108
- | `ctaLink` | `Link \| null` | Primary CTA link |
109
- | `secondaryLink` | `Link \| null` | Secondary link |
110
- | `headerMode` | `'none' \| 'transparent-black' \| 'transparent-white'` | Header overlay mode for navigation |
111
-
112
- **Constraints:**
113
- - `heroMedia` accepts images+videos. Check `mime` to decide between `<img>` and `<video>`.
114
- - `headerMode` controls how the page header (navigation) renders over this hero. `none` = default header, `transparent-*` = transparent with light/dark text.
115
- - DO NOT confuse `headerMode` here with `Page.headerMode` (`'overlay' | 'offset'`).
116
-
117
- ---
118
-
119
- ## Features (`blocks.features`)
120
-
121
- **`__component`: `'blocks.features'`**
122
- **Used in:** Page.blocks, Global.siteWideBlocks
123
-
124
- ### Variants
125
-
126
- | Value | Layout |
127
- |-------|--------|
128
- | `simple-grid` | Icon+text items in a uniform grid |
129
- | `dual-column` | Two-column grid layout |
130
- | `media-aside` | Items on one side, media image on the other |
131
- | `media-aside-compact` | Compact version of media-aside |
132
-
133
- ### Fields
134
-
135
- | Field | Type | Description |
136
- |-------|------|-------------|
137
- | `name` | `string \| null` | Admin label — DO NOT display |
138
- | `variant` | enum | Layout variant |
139
- | `section` | `Section \| null` | Section wrapper |
140
- | `media` | `StrapiMedia \| null` | Supporting image — **images only** |
141
- | `items` | `FeatureItem[]` | Feature items list |
142
-
143
- **Constraints:**
144
- - `media` is images-only and only relevant for `media-aside` / `media-aside-compact` variants.
145
- - DO NOT render the `media` field for `simple-grid` or `dual-column` variants.
146
-
147
- ---
148
-
149
- ## CTA (`blocks.cta`)
150
-
151
- **`__component`: `'blocks.cta'`**
152
- **Used in:** Page.blocks
153
-
154
- ### Variants
155
-
156
- | Value | Layout |
157
- |-------|--------|
158
- | `inline-spread` | Text and buttons spread horizontally |
159
- | `inline-centered` | Centered text with buttons below |
160
- | `inline-stacked` | Text and buttons stacked vertically |
161
- | `card-stacked` | Card container with stacked content |
162
- | `card-centered` | Card container with centered content |
163
- | `card-horizontal` | Card container with horizontal layout |
164
-
165
- ### Fields
166
-
167
- | Field | Type | Description |
168
- |-------|------|-------------|
169
- | `section` | `Section \| null` | Section wrapper |
170
- | `variant` | enum | Layout variant |
171
- | `ctaMedia` | `StrapiMedia \| null` | CTA media — **images+videos** |
172
- | `ctaText` | `string \| null` | Supplementary text |
173
- | `ctaLink` | `Link \| null` | Primary CTA link |
174
- | `secondaryLink` | `Link \| null` | Secondary link |
175
-
176
- **Constraints:**
177
- - `ctaMedia` accepts images+videos. Most relevant for `card-*` variants.
178
- - `inline-*` variants are borderless/background-less; `card-*` variants have a card container.
179
-
180
- ---
181
-
182
- ## Slider (`blocks.slider`)
183
-
184
- **`__component`: `'blocks.slider'`**
185
- **Used in:** Page.blocks, Global.siteWideBlocks
186
-
187
- ### Variants
188
-
189
- | Value | Layout |
190
- |-------|--------|
191
- | `cover-flow` | Cover-flow style with center-focused active slide |
192
- | `card-slider` | Card-based slider/carousel |
193
-
194
- ### Fields
195
-
196
- | Field | Type | Description |
197
- |-------|------|-------------|
198
- | `name` | `string \| null` | Admin label — DO NOT display |
199
- | `variant` | enum | Slider style |
200
- | `section` | `Section \| null` | Section wrapper |
201
- | `items` | `SliderItem[]` | Slider items (media required per item) |
202
-
203
- **Constraints:**
204
- - Each `SliderItem.media` is required (images+videos). Always render media for each slide.
205
-
206
- ---
207
-
208
- ## InquiryForm (`blocks.inquiry-form`)
209
-
210
- **`__component`: `'blocks.inquiry-form'`**
211
- **Used in:** Page.blocks, Global.siteWideBlocks
212
-
213
- ### Fields
214
-
215
- | Field | Type | Description |
216
- |-------|------|-------------|
217
- | `section` | `Section \| null` | Section wrapper |
218
- | `successMessage` | `string \| null` | Message displayed after successful submission |
219
-
220
- **Constraints:**
221
- - The form UI is rendered by the frontend (not from CMS data). Submit to `postInquiry(client, data)`.
222
- - Form fields: `name` (required), `email`, `phone`, `subject`, `message` — see `InquiryFormData` type.
223
-
224
- ---
225
-
226
- ## FAQ (`blocks.faq`)
227
-
228
- **`__component`: `'blocks.faq'`**
229
- **Used in:** Page.blocks
230
-
231
- ### Fields
232
-
233
- | Field | Type | Description |
234
- |-------|------|-------------|
235
- | `section` | `Section \| null` | Section wrapper |
236
- | `items` | `FaqDocument[]` | FAQ entries (relation: oneToMany → `api::faq.faq`) |
237
-
238
- **Constraints:**
239
- - `items` are full FAQ documents (with `question`, `answer`, `category`, `sortOrder`).
240
- - `answer` is `BlocksContent | null` — use a Blocks renderer, not markdown.
241
- - No variant — use a single accordion/expandable pattern.
242
-
243
- ---
244
-
245
- ## Highlights (`blocks.highlights`)
246
-
247
- **`__component`: `'blocks.highlights'`**
248
- **Used in:** Page.blocks
249
-
250
- ### Variants
251
-
252
- | Value | Layout |
253
- |-------|--------|
254
- | `dual-column` | Two-column image+text grid |
255
- | `triple-column` | Three-column grid |
256
- | `alternating` | Zigzag layout — alternating image/text sides |
257
-
258
- ### Fields
259
-
260
- | Field | Type | Description |
261
- |-------|------|-------------|
262
- | `name` | `string \| null` | Admin label — DO NOT display |
263
- | `variant` | enum | Layout variant |
264
- | `media` | `StrapiMedia \| null` | Block-level supporting media — **images+videos** |
265
- | `section` | `Section \| null` | Section wrapper |
266
- | `items` | `HighlightItem[]` | Highlight items (each has required media) |
267
-
268
- **Constraints:**
269
- - Block-level `media` is a supporting visual, not per-item media.
270
- - Each `HighlightItem.media` is required (images+videos).
271
- - For `alternating` variant, items alternate between text-left/media-right and media-left/text-right.
272
-
273
1
  ---
274
-
275
- ## BentoGrid (`blocks.bento-grid`)
276
-
277
- **`__component`: `'blocks.bento-grid'`**
278
- **Used in:** Page.blocks
279
-
280
- ### Fields
281
-
282
- | Field | Type | Description |
283
- |-------|------|-------------|
284
- | `name` | `string \| null` | Admin label — DO NOT display |
285
- | `section` | `Section \| null` | Section wrapper |
286
- | `columns` | `number` | Grid columns (2–4, default 3) |
287
- | `items` | `BentoItem[]` | Grid items with colSpan/rowSpan |
288
-
289
- **Constraints:**
290
- - No variant — layout is controlled by `columns` + each item's `colSpan`/`rowSpan`.
291
- - Use CSS Grid: `grid-template-columns: repeat(columns, 1fr)`.
292
- - `BentoItem.media` is images-only.
293
- - Each item's `colSpan` (1–4) and `rowSpan` (1–3) define its grid area.
294
-
2
+ type: reference
3
+ status: current
4
+ generated: true
5
+ generator: .claude/skills/docs-steward/scripts/gen-reference.mjs
6
+ sources:
7
+ - packages/strapi-plugin-builder/server/src/components/blocks/*.json
295
8
  ---
296
9
 
297
- ## Testimonials (`blocks.testimonials`)
298
-
299
- **`__component`: `'blocks.testimonials'`**
300
- **Used in:** Page.blocks
301
-
302
- ### Variants
10
+ <!-- DO NOT EDIT. Run `pnpm docs:gen` after changing the schemas. -->
303
11
 
304
- | Value | Layout |
305
- |-------|--------|
306
- | `centered` | Single/few quotes centered, large format |
307
- | `side-by-side` | Quote + supporting media in split layout |
308
- | `card-grid` | Multiple testimonials as cards in a grid |
309
- | `subtle-grid` | Multiple testimonials in a minimal grid |
12
+ # Blocks
310
13
 
311
- ### Fields
14
+ Top-level components usable in the `Page.blocks` dynamic zone.
15
+ Every block object must carry `__component`. Heading and subheading text
16
+ lives inside the nested `section` component, not at the block root.
312
17
 
313
- | Field | Type | Description |
314
- |-------|------|-------------|
315
- | `name` | `string \| null` | Admin label — DO NOT display |
316
- | `variant` | enum | Layout variant |
317
- | `section` | `Section \| null` | Section wrapper |
318
- | `media` | `StrapiMedia \| null` | Block-level supporting media — **images+videos** |
319
- | `items` | `TestimonialItem[]` | Testimonial items |
18
+ ## Quick reference
320
19
 
321
- **Constraints:**
322
- - Block-level `media` is primarily used with `side-by-side` variant.
323
- - `TestimonialItem.avatar` and `TestimonialItem.logo` are images-only.
324
- - `TestimonialItem.rating` is 1–5 integer or null. Render as star rating when present.
20
+ | Component | `__component` | Variants |
21
+ |---|---|---|
22
+ | Bento Grid | `blocks.bento-grid` | — |
23
+ | Content | `blocks.content` | `prose`, `wide`, `full-width` |
24
+ | CTA | `blocks.cta` | `inline-spread`, `inline-centered`, `inline-stacked`, `card-stacked`, `card-centered`, `card-horizontal` |
25
+ | FAQ | `blocks.faq` | — |
26
+ | Features | `blocks.features` | `simple-grid`, `dual-column`, `media-aside`, `media-aside-compact` |
27
+ | Hero | `blocks.hero` | `side-by-side`, `media-extending`, `fullscreen-media`, `stacked-media` |
28
+ | Highlights | `blocks.highlights` | `dual-column`, `triple-column`, `alternating` |
29
+ | Inquiry Form | `blocks.inquiry-form` | — |
30
+ | Logo Cloud | `blocks.logo-cloud` | `inline`, `grid`, `split`, `marquee` |
31
+ | Pricing | `blocks.pricing` | `two-column`, `three-column`, `single`, `with-comparison` |
32
+ | Slider | `blocks.slider` | `cover-flow`, `card-slider` |
33
+ | Stats | `blocks.stats` | `simple`, `card-grid`, `split` |
34
+ | Team | `blocks.team` | `grid`, `large-image`, `compact` |
35
+ | Testimonials | `blocks.testimonials` | `centered`, `side-by-side`, `card-grid`, `subtle-grid` |
325
36
 
326
- ---
327
-
328
- ## LogoCloud (`blocks.logo-cloud`)
37
+ ## Bento Grid
329
38
 
330
- **`__component`: `'blocks.logo-cloud'`**
331
- **Used in:** Page.blocks
39
+ `blocks.bento-grid` — Asymmetric grid layout with per-item span control
332
40
 
333
- ### Variants
41
+ | Attribute | Type | Required | Default | Notes |
42
+ |---|---|---|---|---|
43
+ | `name` | string | — | — | — |
44
+ | `section` | component `elements.section` | — | — | — |
45
+ | `columns` | integer | — | `3` | — |
46
+ | `items` | component `shared.bento-item` (repeatable) | — | — | — |
334
47
 
335
- | Value | Layout |
336
- |-------|--------|
337
- | `inline` | Logos in a single horizontal row (4–8 logos) |
338
- | `grid` | Logos in a grid layout (8+ logos) |
339
- | `split` | Text on left (section heading/subheading) + logo grid on right |
48
+ ## Content
340
49
 
341
- ### Fields
50
+ `blocks.content` — Rich text content block using Strapi Blocks editor
342
51
 
343
- | Field | Type | Description |
344
- |-------|------|-------------|
345
- | `name` | `string \| null` | Admin label — DO NOT display |
346
- | `variant` | enum | Layout variant |
347
- | `section` | `Section \| null` | Section wrapper |
348
- | `items` | `LogoItem[]` | Logo items |
52
+ | Attribute | Type | Required | Default | Notes |
53
+ |---|---|---|---|---|
54
+ | `section` | component `elements.section` | — | — | — |
55
+ | `variant` | enumeration | — | — | `prose`, `wide`, `full-width` |
56
+ | `body` | blocks | yes | — | — |
349
57
 
350
- **Constraints:**
351
- - No block-level media. `split` variant uses `section.heading`/`subheading` for text.
352
- - `LogoItem.logo` is required (images only).
58
+ ## CTA
353
59
 
354
- ---
60
+ `blocks.cta` — Call-to-Action block with media and action links
355
61
 
356
- ## Stats (`blocks.stats`)
62
+ | Attribute | Type | Required | Default | Notes |
63
+ |---|---|---|---|---|
64
+ | `section` | component `elements.section` | — | — | — |
65
+ | `variant` | enumeration | — | `inline-spread` | `inline-spread`, `inline-centered`, `inline-stacked`, `card-stacked`, `card-centered`, `card-horizontal` |
66
+ | `image` | component `shared.image` | — | — | — |
67
+ | `ctaText` | text | — | — | — |
68
+ | `ctaLink` | component `shared.link` | — | — | — |
69
+ | `secondaryLink` | component `shared.link` | — | — | — |
357
70
 
358
- **`__component`: `'blocks.stats'`**
359
- **Used in:** Page.blocks
71
+ ## FAQ
360
72
 
361
- ### Variants
73
+ `blocks.faq` — FAQ list block linked to FAQ content type via relation
362
74
 
363
- | Value | Layout |
364
- |-------|--------|
365
- | `simple` | Horizontal row of stats (use section.theme for dark/light) |
366
- | `card-grid` | Stats displayed as cards in a grid |
367
- | `split` | Stats on one side + media on the other |
75
+ | Attribute | Type | Required | Default | Notes |
76
+ |---|---|---|---|---|
77
+ | `section` | component `elements.section` | — | — | — |
78
+ | `items` | relation `oneToMany` → `plugin::builder.faq` | — | — | — |
368
79
 
369
- ### Fields
80
+ ## Features
370
81
 
371
- | Field | Type | Description |
372
- |-------|------|-------------|
373
- | `name` | `string \| null` | Admin label — DO NOT display |
374
- | `variant` | enum | Layout variant |
375
- | `section` | `Section \| null` | Section wrapper |
376
- | `media` | `StrapiMedia \| null` | Supporting media — **images+videos** |
377
- | `items` | `StatItem[]` | Stat items |
82
+ `blocks.features` — Feature/service showcase with icon+text items
378
83
 
379
- **Constraints:**
380
- - `media` is only relevant for `split` variant. DO NOT render it for `simple` or `card-grid`.
381
- - `StatItem.value` is a string (e.g. `"10,000+"`, `"99.9%"`). DO NOT parse it as a number.
84
+ | Attribute | Type | Required | Default | Notes |
85
+ |---|---|---|---|---|
86
+ | `name` | string | — | — | — |
87
+ | `variant` | enumeration | — | — | `simple-grid`, `dual-column`, `media-aside`, `media-aside-compact` |
88
+ | `section` | component `elements.section` | — | — | — |
89
+ | `image` | component `shared.image` | — | — | — |
90
+ | `items` | component `shared.feature-item` (repeatable) | — | — | — |
382
91
 
383
- ---
92
+ ## Hero
384
93
 
385
- ## Pricing (`blocks.pricing`)
94
+ `blocks.hero` — Hero banner with media, CTA links, and layout variants
386
95
 
387
- **`__component`: `'blocks.pricing'`**
388
- **Used in:** Page.blocks
96
+ | Attribute | Type | Required | Default | Notes |
97
+ |---|---|---|---|---|
98
+ | `variant` | enumeration | — | — | `side-by-side`, `media-extending`, `fullscreen-media`, `stacked-media` |
99
+ | `section` | component `elements.section` | — | — | — |
100
+ | `image` | component `shared.image` | — | — | — |
101
+ | `ctaText` | text | — | — | — |
102
+ | `ctaLink` | component `shared.link` | — | — | — |
103
+ | `secondaryLink` | component `shared.link` | — | — | — |
104
+ | `headerMode` | enumeration | — | `none` | `none`, `transparent-black`, `transparent-white` |
389
105
 
390
- ### Variants
106
+ ## Highlights
391
107
 
392
- | Value | Layout |
393
- |-------|--------|
394
- | `two-column` | Side-by-side comparison of 2 plans |
395
- | `three-column` | Three plans (Good/Better/Best) |
396
- | `single` | Single plan detail view |
397
- | `with-comparison` | Plans + feature comparison table below |
108
+ `blocks.highlights` — Highlight/feature showcase with media+text items
398
109
 
399
- ### Fields
110
+ | Attribute | Type | Required | Default | Notes |
111
+ |---|---|---|---|---|
112
+ | `name` | string | — | — | — |
113
+ | `variant` | enumeration | — | — | `dual-column`, `triple-column`, `alternating` |
114
+ | `image` | component `shared.image` | — | — | — |
115
+ | `section` | component `elements.section` | — | — | — |
116
+ | `items` | component `shared.highlight-item` (repeatable) | — | — | — |
400
117
 
401
- | Field | Type | Description |
402
- |-------|------|-------------|
403
- | `name` | `string \| null` | Admin label — DO NOT display |
404
- | `variant` | enum | Layout variant |
405
- | `section` | `Section \| null` | Section wrapper |
406
- | `items` | `PricingTier[]` | Pricing tiers |
118
+ ## Inquiry Form
119
+
120
+ `blocks.inquiry-form` — Contact form block that submits to Inquiry content type
121
+
122
+ | Attribute | Type | Required | Default | Notes |
123
+ |---|---|---|---|---|
124
+ | `section` | component `elements.section` | — | — | — |
125
+ | `successMessage` | text | — | — | — |
126
+ | `errorMessage` | text | — | — | — |
407
127
 
408
- **Constraints:**
409
- - `PricingTier.price` is a string (e.g. `"$29"`, `"Free"`, `"Contact us"`). DO NOT parse as number.
410
- - `PricingTier.featureList` is richtext (Markdown). Render as a bullet list.
411
- - `PricingTier.highlighted` marks the recommended plan — apply visual emphasis (ribbon, border, etc.).
128
+ ## Logo Cloud
412
129
 
413
- ---
130
+ `blocks.logo-cloud` — Client/partner logo showcase block
414
131
 
415
- ## Content (`blocks.content`)
132
+ | Attribute | Type | Required | Default | Notes |
133
+ |---|---|---|---|---|
134
+ | `name` | string | — | — | — |
135
+ | `variant` | enumeration | — | — | `inline`, `grid`, `split`, `marquee` |
136
+ | `section` | component `elements.section` | — | — | — |
137
+ | `items` | component `shared.logo-item` (repeatable) | — | — | — |
416
138
 
417
- **`__component`: `'blocks.content'`**
418
- **Used in:** Page.blocks
139
+ ## Pricing
419
140
 
420
- ### Variants
141
+ `blocks.pricing` — Pricing plans/tiers comparison block
421
142
 
422
- | Value | Layout |
423
- |-------|--------|
424
- | `prose` | Reading-optimized width (max-w-prose). For long-form text. |
425
- | `wide` | Wider container. For content with images/tables. |
426
- | `full-width` | Full container width. For notices, terms. |
143
+ | Attribute | Type | Required | Default | Notes |
144
+ |---|---|---|---|---|
145
+ | `name` | string | — | — | — |
146
+ | `variant` | enumeration | — | — | `two-column`, `three-column`, `single`, `with-comparison` |
147
+ | `section` | component `elements.section` | — | — | — |
148
+ | `items` | component `shared.pricing-tier` (repeatable) | — | — | — |
427
149
 
428
- ### Fields
150
+ ## Slider
429
151
 
430
- | Field | Type | Description |
431
- |-------|------|-------------|
432
- | `section` | `Section \| null` | Section wrapper |
433
- | `variant` | enum | Content width variant |
434
- | `body` | `BlocksContent` | Rich text body — **required** |
152
+ `blocks.slider` — Slider/carousel block with media+text items
435
153
 
436
- **Constraints:**
437
- - `body` is `BlocksContent` (structured JSON), NOT HTML or Markdown. Use a Blocks renderer.
438
- - No `name`, no `items`, no `media` — the Blocks editor supports inline images.
154
+ | Attribute | Type | Required | Default | Notes |
155
+ |---|---|---|---|---|
156
+ | `name` | string | — | — | — |
157
+ | `variant` | enumeration | — | — | `cover-flow`, `card-slider` |
158
+ | `section` | component `elements.section` | — | — | — |
159
+ | `items` | component `shared.slider-item` (repeatable) | — | — | — |
439
160
 
440
- ---
161
+ ## Stats
441
162
 
442
- ## Team (`blocks.team`)
163
+ `blocks.stats` — Key metrics/numbers showcase block
443
164
 
444
- **`__component`: `'blocks.team'`**
445
- **Used in:** Page.blocks
165
+ | Attribute | Type | Required | Default | Notes |
166
+ |---|---|---|---|---|
167
+ | `name` | string | — | — | — |
168
+ | `variant` | enumeration | — | — | `simple`, `card-grid`, `split` |
169
+ | `section` | component `elements.section` | — | — | — |
170
+ | `image` | component `shared.image` | — | — | — |
171
+ | `items` | component `shared.stat-item` (repeatable) | — | — | — |
446
172
 
447
- ### Variants
173
+ ## Team
448
174
 
449
- | Value | Layout |
450
- |-------|--------|
451
- | `grid` | Standard grid — circular/square photos + name/role/bio. For 4–12 members. |
452
- | `large-image` | Large photo emphasis. For leadership/key members. |
453
- | `compact` | Small photos + minimal info. For large teams (12+). |
175
+ `blocks.team` — Team member showcase block
454
176
 
455
- ### Fields
177
+ | Attribute | Type | Required | Default | Notes |
178
+ |---|---|---|---|---|
179
+ | `name` | string | — | — | — |
180
+ | `variant` | enumeration | — | — | `grid`, `large-image`, `compact` |
181
+ | `section` | component `elements.section` | — | — | — |
182
+ | `items` | component `shared.team-member` (repeatable) | — | — | — |
456
183
 
457
- | Field | Type | Description |
458
- |-------|------|-------------|
459
- | `name` | `string \| null` | Admin label — DO NOT display |
460
- | `variant` | enum | Layout variant |
461
- | `section` | `Section \| null` | Section wrapper |
462
- | `items` | `TeamMember[]` | Team members |
184
+ ## Testimonials
463
185
 
464
- **Constraints:**
465
- - `TeamMember.photo` is images-only.
466
- - `TeamMember.socialLinks` is `Link[]` — render as icon links.
467
-
468
- ---
469
-
470
- ## Shared Sub-Components
471
-
472
- ### FeatureItem (`shared.feature-item`)
473
-
474
- | Field | Type | Description |
475
- |-------|------|-------------|
476
- | `label` | `string \| null` | Item label |
477
- | `description` | `string \| null` | Markdown richtext |
478
- | `icon` | `string \| null` | Icon picker value |
479
- | `infoText` | `string \| null` | Supplementary info text |
480
- | `link` | `Link \| null` | Optional link |
481
-
482
- ### HighlightItem (`shared.highlight-item`)
483
-
484
- | Field | Type | Description |
485
- |-------|------|-------------|
486
- | `label` | `string \| null` | Item label |
487
- | `description` | `string \| null` | Markdown richtext |
488
- | `media` | `StrapiMedia` | **Required** — images+videos |
489
- | `link` | `Link \| null` | Optional link |
490
-
491
- ### SliderItem (`shared.slider-item`)
492
-
493
- | Field | Type | Description |
494
- |-------|------|-------------|
495
- | `label` | `string \| null` | Item label |
496
- | `description` | `string \| null` | Description text |
497
- | `link` | `Link \| null` | Optional link |
498
- | `media` | `StrapiMedia` | **Required** — images+videos |
499
-
500
- ### BentoItem (`shared.bento-item`)
501
-
502
- | Field | Type | Description |
503
- |-------|------|-------------|
504
- | `title` | `string \| null` | Item title |
505
- | `description` | `string \| null` | Description text |
506
- | `media` | `StrapiMedia \| null` | Screenshot/illustration — images only |
507
- | `icon` | `string \| null` | Decorative icon |
508
- | `colSpan` | `number` | Column span (1–4, default 1) |
509
- | `rowSpan` | `number` | Row span (1–3, default 1) |
510
- | `link` | `Link \| null` | Optional link |
511
-
512
- ### TestimonialItem (`shared.testimonial-item`)
513
-
514
- | Field | Type | Description |
515
- |-------|------|-------------|
516
- | `quote` | `string` | **Required** — testimonial text |
517
- | `authorName` | `string \| null` | Author name |
518
- | `authorRole` | `string \| null` | Author title/role |
519
- | `avatar` | `StrapiMedia \| null` | Profile image — images only |
520
- | `logo` | `StrapiMedia \| null` | Company logo — images only |
521
- | `rating` | `number \| null` | Star rating 1–5 |
522
-
523
- ### LogoItem (`shared.logo-item`)
524
-
525
- | Field | Type | Description |
526
- |-------|------|-------------|
527
- | `logo` | `StrapiMedia` | **Required** — images only |
528
- | `companyName` | `string \| null` | Company name (for alt text/accessibility) |
529
- | `link` | `Link \| null` | Optional link |
530
-
531
- ### StatItem (`shared.stat-item`)
532
-
533
- | Field | Type | Description |
534
- |-------|------|-------------|
535
- | `value` | `string` | **Required** — formatted value string |
536
- | `label` | `string \| null` | Short label |
537
- | `description` | `string \| null` | Supplementary description |
538
-
539
- ### PricingTier (`shared.pricing-tier`)
540
-
541
- | Field | Type | Description |
542
- |-------|------|-------------|
543
- | `planName` | `string` | **Required** — plan name |
544
- | `price` | `string` | **Required** — formatted price string |
545
- | `billingPeriod` | `string \| null` | e.g. "/mo", "/year" |
546
- | `description` | `string \| null` | Plan description |
547
- | `featureList` | `string \| null` | Markdown bullet list |
548
- | `ctaLink` | `Link \| null` | CTA link |
549
- | `highlighted` | `boolean` | Recommended plan flag |
550
-
551
- ### TeamMember (`shared.team-member`)
552
-
553
- | Field | Type | Description |
554
- |-------|------|-------------|
555
- | `memberName` | `string` | **Required** — member name |
556
- | `role` | `string \| null` | Title/role |
557
- | `bio` | `string \| null` | Short bio |
558
- | `photo` | `StrapiMedia \| null` | Profile photo — images only |
559
- | `socialLinks` | `Link[]` | Social media links |
560
-
561
- ### Link (`shared.link`)
562
-
563
- | Field | Type | Description |
564
- |-------|------|-------------|
565
- | `label` | `string` | **Required** — link label |
566
- | `href` | `string` | **Required** — URL |
567
- | `newWindow` | `boolean` | Open in new window (default false) |
568
- | `icon` | `string \| null` | Icon picker value |
569
-
570
- ---
186
+ `blocks.testimonials` — Customer testimonials/reviews block
571
187
 
572
- ## DZ Discrimination Pattern
573
-
574
- ```ts
575
- import type { PageBlocks, SiteWideBlocks } from '@dani-builder/strapi-client/types';
576
-
577
- function renderBlock(block: PageBlocks) {
578
- switch (block.__component) {
579
- case 'blocks.hero': return <HeroSection block={block} />;
580
- case 'blocks.features': return <FeaturesSection block={block} />;
581
- case 'blocks.cta': return <CtaSection block={block} />;
582
- case 'blocks.slider': return <SliderSection block={block} />;
583
- case 'blocks.inquiry-form': return <InquiryFormSection block={block} />;
584
- case 'blocks.faq': return <FaqSection block={block} />;
585
- case 'blocks.highlights': return <HighlightsSection block={block} />;
586
- case 'blocks.bento-grid': return <BentoGridSection block={block} />;
587
- case 'blocks.testimonials': return <TestimonialsSection block={block} />;
588
- case 'blocks.logo-cloud': return <LogoCloudSection block={block} />;
589
- case 'blocks.stats': return <StatsSection block={block} />;
590
- case 'blocks.pricing': return <PricingSection block={block} />;
591
- case 'blocks.content': return <ContentSection block={block} />;
592
- case 'blocks.team': return <TeamSection block={block} />;
593
- case 'elements.section': return <SectionDivider section={block} />;
594
- default: return null;
595
- }
596
- }
597
- ```
598
-
599
- **PageBlocks union** (15 members): `Section | HeroBlock | FeaturesBlock | CtaBlock | SliderBlock | InquiryFormBlock | FaqBlock | HighlightsBlock | BentoGridBlock | TestimonialsBlock | LogoCloudBlock | StatsBlock | PricingBlock | ContentBlock | TeamBlock`
600
-
601
- **SiteWideBlocks union** (4 members): `SliderBlock | InquiryFormBlock | HeroBlock | FeaturesBlock`
188
+ | Attribute | Type | Required | Default | Notes |
189
+ |---|---|---|---|---|
190
+ | `name` | string | — | — | — |
191
+ | `variant` | enumeration | — | — | `centered`, `side-by-side`, `card-grid`, `subtle-grid` |
192
+ | `section` | component `elements.section` | — | — | — |
193
+ | `image` | component `shared.image` | — | — | — |
194
+ | `items` | component `shared.testimonial-item` (repeatable) | — | — | — |