@morphika/andami 0.2.12 → 0.2.14

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 (58) hide show
  1. package/README.md +2 -1
  2. package/app/admin/pages/[slug]/page.tsx +39 -2
  3. package/components/blocks/BlockRenderer.tsx +0 -7
  4. package/components/blocks/CoverSectionRenderer.tsx +295 -0
  5. package/components/blocks/ImageBlockRenderer.tsx +12 -10
  6. package/components/blocks/PageRenderer.tsx +13 -9
  7. package/components/blocks/VideoBlockRenderer.tsx +11 -6
  8. package/components/builder/BlockLivePreview.tsx +0 -5
  9. package/components/builder/BlockTypePicker.tsx +0 -1
  10. package/components/builder/ColorSwatchPicker.tsx +2 -2
  11. package/components/builder/CoverRowResizeHandle.tsx +180 -0
  12. package/components/builder/CoverSectionCanvas.tsx +260 -0
  13. package/components/builder/ReadOnlyFrame.tsx +127 -3
  14. package/components/builder/SectionTypePicker.tsx +29 -0
  15. package/components/builder/SectionV2Canvas.tsx +4 -1
  16. package/components/builder/SectionV2Column.tsx +15 -20
  17. package/components/builder/SettingsPanel.tsx +14 -0
  18. package/components/builder/SortableRow.tsx +7 -21
  19. package/components/builder/blockStyles.tsx +13 -14
  20. package/components/builder/editors/ImageBlockEditor.tsx +1 -0
  21. package/components/builder/editors/VideoBlockEditor.tsx +1 -0
  22. package/components/builder/editors/index.ts +0 -1
  23. package/components/builder/index.ts +1 -0
  24. package/components/builder/live-preview/LiveImagePreview.tsx +21 -2
  25. package/components/builder/live-preview/LiveVideoPreview.tsx +8 -3
  26. package/components/builder/live-preview/RichTextEditor.tsx +23 -2
  27. package/components/builder/live-preview/index.ts +0 -1
  28. package/components/builder/settings-panel/BlockSettings.tsx +0 -7
  29. package/components/builder/settings-panel/CoverSectionSettings.tsx +296 -0
  30. package/components/builder/settings-panel/index.ts +1 -0
  31. package/components/builder/settings-panel/useSettingsPanelSelection.ts +36 -2
  32. package/lib/animation/enter-types.ts +0 -1
  33. package/lib/animation/hover-effect-types.ts +0 -1
  34. package/lib/builder/defaults.ts +43 -22
  35. package/lib/builder/serializer/normalizers.ts +34 -1
  36. package/lib/builder/serializer/serializers.ts +39 -2
  37. package/lib/builder/store-blocks.ts +11 -3
  38. package/lib/builder/store-cover.ts +220 -0
  39. package/lib/builder/store-helpers.ts +81 -4
  40. package/lib/builder/store-sections.ts +12 -2
  41. package/lib/builder/store.ts +11 -2
  42. package/lib/builder/types.ts +15 -2
  43. package/lib/sanity/queries.ts +18 -4
  44. package/lib/sanity/types.ts +81 -45
  45. package/lib/version.ts +1 -1
  46. package/package.json +1 -1
  47. package/sanity/schemas/blocks/imageBlock.ts +1 -0
  48. package/sanity/schemas/blocks/index.ts +1 -2
  49. package/sanity/schemas/blocks/videoBlock.ts +1 -0
  50. package/sanity/schemas/index.ts +5 -3
  51. package/sanity/schemas/objects/coverSection.ts +317 -0
  52. package/sanity/schemas/objects/parallaxSlide.ts +0 -1
  53. package/sanity/schemas/page.ts +1 -1
  54. package/sanity/schemas/pageSectionV2.ts +0 -1
  55. package/components/blocks/CoverBlockRenderer.tsx +0 -261
  56. package/components/builder/editors/CoverBlockEditor.tsx +0 -550
  57. package/components/builder/live-preview/LiveCoverPreview.tsx +0 -146
  58. package/sanity/schemas/blocks/coverBlock.ts +0 -229
@@ -135,7 +135,7 @@ export interface ImageBlock {
135
135
  asset_path: string;
136
136
  alt?: string;
137
137
  caption?: string;
138
- width?: "full" | "contained" | "small";
138
+ width?: "full" | "contained" | "small" | "fill";
139
139
  aspect_ratio?: "auto" | "16:9" | "4:3" | "1:1" | "21:9";
140
140
  lazy?: boolean;
141
141
  border_radius?: string;
@@ -174,7 +174,7 @@ export interface VideoBlock {
174
174
  loop?: boolean;
175
175
  muted?: boolean;
176
176
  controls?: boolean;
177
- width?: "full" | "contained";
177
+ width?: "full" | "contained" | "fill";
178
178
  aspect_ratio?: "16:9" | "21:9" | "4:3" | "auto";
179
179
  border_radius?: string;
180
180
  enter_animation?: import("../../lib/animation/enter-types").EnterAnimationConfig;
@@ -210,47 +210,6 @@ export interface ButtonBlock {
210
210
  responsive?: ResponsiveOverrides<ButtonBlock>;
211
211
  }
212
212
 
213
- export interface CoverBlock {
214
- _type: "coverBlock";
215
- _key: string;
216
- // Content
217
- headline?: string;
218
- subheadline?: string;
219
- cta_button?: {
220
- text?: string;
221
- url?: string;
222
- target_blank?: boolean;
223
- style?: "primary" | "secondary" | "outline" | "text";
224
- };
225
- // Media
226
- media_type?: "image" | "video";
227
- media_path?: string;
228
- video_poster?: string;
229
- background_size?: "cover" | "contain" | "none";
230
- background_position?: string;
231
- background_repeat?: "no-repeat" | "repeat" | "repeat-x" | "repeat-y";
232
- // Overlay
233
- overlay?: "none" | "dark" | "light" | "gradient-bottom" | "gradient-top";
234
- overlay_opacity?: number;
235
- /** Custom overlay gradient (Phase 4). JSON-serialized ColorField.
236
- * When set, takes precedence over overlay + overlay_opacity. */
237
- overlay_gradient?: string;
238
- // Layout
239
- content_align_h?: "left" | "center" | "right";
240
- content_align_v?: "top" | "center" | "bottom";
241
- content_max_width?: string;
242
- height?: "100vh" | "80vh" | "60vh" | "40vh" | "custom";
243
- custom_height?: string;
244
- mobile_height?: "same" | "100vh" | "80vh" | "60vh" | "500px" | "400px";
245
- // Appearance
246
- text_color?: string;
247
- show_scroll_indicator?: boolean;
248
- enter_animation?: import("../../lib/animation/enter-types").EnterAnimationConfig;
249
- hover_effect?: import("../../lib/animation/hover-effect-types").HoverEffectConfig;
250
- layout?: BlockLayout;
251
- responsive?: ResponsiveOverrides<CoverBlock>;
252
- }
253
-
254
213
  // ============================================
255
214
  // Project Grid Block v2 (template-only, Session 105)
256
215
  // ============================================
@@ -477,11 +436,84 @@ export interface CustomSectionInstance {
477
436
  responsive_overrides?: PageSectionV2["responsive"];
478
437
  }
479
438
 
439
+ // ============================================
440
+ // Cover Section — proportional rows (Session 176)
441
+ // ============================================
442
+ // Full-viewport section with fixed-height rows and background media.
443
+ // Uses the same SectionColumn/block system as V2 but with explicit
444
+ // row heights (percentages) instead of content-driven auto rows.
445
+
446
+ export type CoverSectionHeight = "100vh" | "80vh" | "50vh";
447
+
448
+ /** A single proportional row within a Cover Section */
449
+ export interface CoverRow {
450
+ _key: string;
451
+ height_percent: number; // 5–95, all rows must sum to 100
452
+ vertical_align: "start" | "center" | "end";
453
+ }
454
+
455
+ /** Cover Section settings (subset of SectionV2Settings — no background/border) */
456
+ export interface CoverSectionSettings {
457
+ grid_columns: number; // default 12
458
+ col_gap: number;
459
+ row_gap: number;
460
+ spacing_top?: string;
461
+ spacing_right?: string;
462
+ spacing_bottom?: string;
463
+ spacing_left?: string;
464
+ enter_animation?: import("../../lib/animation/enter-types").EnterAnimationConfig;
465
+ stagger?: {
466
+ enabled?: boolean;
467
+ delayPerChild?: number;
468
+ direction?: "left-to-right" | "right-to-left";
469
+ };
470
+ }
471
+
472
+ /** Responsive override for Cover Sections */
473
+ export interface CoverSectionResponsiveOverride {
474
+ columns?: ColumnOverride[];
475
+ cover_rows?: Array<{ _key: string; height_percent?: number }>;
476
+ settings?: Partial<CoverSectionSettings>;
477
+ }
478
+
479
+ /** Cover Section — full-viewport section with background and proportional rows */
480
+ export interface CoverSection {
481
+ _type: "coverSection";
482
+ _key: string;
483
+
484
+ // Background
485
+ background_type: "image" | "video";
486
+ background_image?: string;
487
+ background_video?: string;
488
+ background_position?: string;
489
+ background_size?: "cover" | "contain" | "auto";
490
+ background_overlay_color?: string;
491
+ background_overlay_opacity?: number; // 0–100
492
+
493
+ // Height
494
+ height: CoverSectionHeight;
495
+
496
+ // Rows (explicit proportional heights)
497
+ cover_rows: CoverRow[];
498
+
499
+ // Columns (same as V2 — flat array with grid_row referencing cover_rows index)
500
+ columns: SectionColumn[];
501
+
502
+ // Settings
503
+ settings: CoverSectionSettings;
504
+
505
+ // Responsive
506
+ responsive?: {
507
+ tablet?: CoverSectionResponsiveOverride;
508
+ phone?: CoverSectionResponsiveOverride;
509
+ };
510
+ }
511
+
480
512
  // ============================================
481
513
  // Content Item — union of section types in content_rows
482
514
  // ============================================
483
515
 
484
- export type ContentItem = PageSectionV2 | CustomSectionInstance | ParallaxGroup;
516
+ export type ContentItem = PageSectionV2 | CustomSectionInstance | ParallaxGroup | CoverSection;
485
517
 
486
518
  /** Type guard: check if a content item is a PageSectionV2 */
487
519
  export function isPageSectionV2(item: ContentItem): item is PageSectionV2 {
@@ -498,6 +530,11 @@ export function isParallaxGroup(item: ContentItem): item is ParallaxGroup {
498
530
  return (item as ParallaxGroup)._type === "parallaxGroup";
499
531
  }
500
532
 
533
+ /** Type guard: check if a content item is a CoverSection (Session 176) */
534
+ export function isCoverSection(item: ContentItem): item is CoverSection {
535
+ return (item as CoverSection)._type === "coverSection";
536
+ }
537
+
501
538
  // ============================================
502
539
  // Shared references
503
540
  // ============================================
@@ -520,7 +557,6 @@ export type ContentBlock =
520
557
  | VideoBlock
521
558
  | SpacerBlock
522
559
  | ButtonBlock
523
- | CoverBlock
524
560
  | ProjectGridBlock;
525
561
 
526
562
  // ============================================
package/lib/version.ts CHANGED
@@ -6,4 +6,4 @@
6
6
  * Exposed as a plain constant so it can be imported without reading
7
7
  * package.json at runtime.
8
8
  */
9
- export const ANDAMI_VERSION = "0.2.12";
9
+ export const ANDAMI_VERSION = "0.2.14";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morphika/andami",
3
- "version": "0.2.12",
3
+ "version": "0.2.14",
4
4
  "description": "Visual Page Builder — core library. A reusable website builder with visual editing, CMS integration, and asset management.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -24,6 +24,7 @@ export const imageBlock = defineType({
24
24
  { title: "Full", value: "full" },
25
25
  { title: "Contained", value: "contained" },
26
26
  { title: "Small", value: "small" },
27
+ { title: "Fill", value: "fill" },
27
28
  ],
28
29
  },
29
30
  initialValue: "full",
@@ -1,9 +1,8 @@
1
- // Block schemas (8)
1
+ // Block schemas (7)
2
2
  export { textBlock } from "./textBlock";
3
3
  export { imageBlock } from "./imageBlock";
4
4
  export { imageGridBlock } from "./imageGridBlock";
5
5
  export { videoBlock } from "./videoBlock";
6
6
  export { spacerBlock } from "./spacerBlock";
7
7
  export { buttonBlock } from "./buttonBlock";
8
- export { coverBlock } from "./coverBlock";
9
8
  export { projectGridBlock } from "./projectGridBlock";
@@ -45,6 +45,7 @@ export const videoBlock = defineType({
45
45
  list: [
46
46
  { title: "Full", value: "full" },
47
47
  { title: "Contained", value: "contained" },
48
+ { title: "Fill", value: "fill" },
48
49
  ],
49
50
  },
50
51
  initialValue: "full",
@@ -10,6 +10,7 @@ import hoverEffectConfig from "./objects/hoverEffectConfig";
10
10
  import typewriterConfig from "./objects/typewriterConfig";
11
11
  import parallaxSlide from "./objects/parallaxSlide";
12
12
  import parallaxGroup from "./objects/parallaxGroup";
13
+ import coverSection from "./objects/coverSection";
13
14
  import {
14
15
  textBlock,
15
16
  imageBlock,
@@ -17,7 +18,6 @@ import {
17
18
  videoBlock,
18
19
  spacerBlock,
19
20
  buttonBlock,
20
- coverBlock,
21
21
  projectGridBlock,
22
22
  } from "./blocks";
23
23
 
@@ -58,6 +58,9 @@ export {
58
58
  export {
59
59
  default as parallaxGroup,
60
60
  } from "./objects/parallaxGroup";
61
+ export {
62
+ default as coverSection,
63
+ } from "./objects/coverSection";
61
64
  export {
62
65
  textBlock,
63
66
  imageBlock,
@@ -65,7 +68,6 @@ export {
65
68
  videoBlock,
66
69
  spacerBlock,
67
70
  buttonBlock,
68
- coverBlock,
69
71
  projectGridBlock,
70
72
  } from "./blocks";
71
73
 
@@ -87,6 +89,7 @@ export const schemaTypes = [
87
89
  typewriterConfig, // Typewriter config for textBlock (Session 117)
88
90
  parallaxSlide, // Parallax V2 slide (Session 123)
89
91
  parallaxGroup, // Parallax V2 group (Session 123)
92
+ coverSection, // Cover Section — proportional rows (Session 176)
90
93
 
91
94
  // Blocks (8)
92
95
  textBlock,
@@ -95,7 +98,6 @@ export const schemaTypes = [
95
98
  videoBlock,
96
99
  spacerBlock,
97
100
  buttonBlock,
98
- coverBlock,
99
101
  projectGridBlock,
100
102
  ];
101
103
 
@@ -0,0 +1,317 @@
1
+ import { defineField, defineType } from "sanity";
2
+
3
+ /**
4
+ * coverSection — Full-viewport section with proportional rows and background media.
5
+ *
6
+ * A new ContentItem type alongside pageSectionV2, parallaxGroup, and customSectionInstance.
7
+ * Uses the same column/block system as V2 but with fixed-height proportional rows
8
+ * instead of content-driven rows. Overflow is always hidden.
9
+ *
10
+ * Session 176: Cover Sections — Phase 1 (Schema).
11
+ */
12
+
13
+ const columnFields = [
14
+ defineField({
15
+ name: "grid_column",
16
+ title: "Grid Column",
17
+ type: "number",
18
+ description: "1-based start position (1–12)",
19
+ validation: (Rule) => Rule.required().min(1).max(12),
20
+ }),
21
+ defineField({
22
+ name: "grid_row",
23
+ title: "Grid Row",
24
+ type: "number",
25
+ description: "1-based row index (maps to cover_rows)",
26
+ validation: (Rule) => Rule.required().min(1),
27
+ }),
28
+ defineField({
29
+ name: "span",
30
+ title: "Column Span",
31
+ type: "number",
32
+ description: "How many grid columns (1–12)",
33
+ validation: (Rule) => Rule.required().min(1).max(12),
34
+ }),
35
+ defineField({
36
+ name: "blocks",
37
+ title: "Blocks",
38
+ type: "array",
39
+ of: [
40
+ { type: "textBlock" },
41
+ { type: "imageBlock" },
42
+ { type: "imageGridBlock" },
43
+ { type: "videoBlock" },
44
+ { type: "spacerBlock" },
45
+ { type: "buttonBlock" },
46
+ ],
47
+ }),
48
+ defineField({
49
+ name: "enter_animation",
50
+ title: "Enter Animation",
51
+ type: "enterAnimationConfig",
52
+ }),
53
+ ];
54
+
55
+ const responsiveColumnOverrideFields = [
56
+ defineField({
57
+ name: "columns",
58
+ title: "Column Overrides",
59
+ type: "array",
60
+ of: [
61
+ {
62
+ type: "object",
63
+ name: "columnOverride",
64
+ fields: [
65
+ defineField({ name: "grid_column", title: "Grid Column", type: "number" }),
66
+ defineField({ name: "grid_row", title: "Grid Row", type: "number" }),
67
+ defineField({ name: "span", title: "Span", type: "number" }),
68
+ ],
69
+ },
70
+ ],
71
+ }),
72
+ ];
73
+
74
+ const responsiveRowOverrideFields = [
75
+ defineField({
76
+ name: "cover_rows",
77
+ title: "Row Height Overrides",
78
+ type: "array",
79
+ of: [
80
+ {
81
+ type: "object",
82
+ name: "coverRowOverride",
83
+ fields: [
84
+ defineField({ name: "height_percent", title: "Height %", type: "number" }),
85
+ ],
86
+ },
87
+ ],
88
+ }),
89
+ ];
90
+
91
+ const responsiveSettingsFields = [
92
+ defineField({ name: "col_gap", title: "Column Gap", type: "number" }),
93
+ defineField({ name: "row_gap", title: "Row Gap", type: "number" }),
94
+ defineField({ name: "spacing_top", type: "string", title: "Spacing Top" }),
95
+ defineField({ name: "spacing_right", type: "string", title: "Spacing Right" }),
96
+ defineField({ name: "spacing_bottom", type: "string", title: "Spacing Bottom" }),
97
+ defineField({ name: "spacing_left", type: "string", title: "Spacing Left" }),
98
+ ];
99
+
100
+ export default defineType({
101
+ name: "coverSection",
102
+ title: "Cover Section",
103
+ type: "object",
104
+ fields: [
105
+ // ── Background ──
106
+ defineField({
107
+ name: "background_type",
108
+ title: "Background Type",
109
+ type: "string",
110
+ options: {
111
+ list: [
112
+ { title: "Image", value: "image" },
113
+ { title: "Video", value: "video" },
114
+ ],
115
+ },
116
+ initialValue: "image",
117
+ }),
118
+ defineField({
119
+ name: "background_image",
120
+ title: "Background Image",
121
+ type: "string",
122
+ description: "Asset path for background image",
123
+ }),
124
+ defineField({
125
+ name: "background_video",
126
+ title: "Background Video",
127
+ type: "string",
128
+ description: "Asset path for background video",
129
+ }),
130
+ defineField({
131
+ name: "background_position",
132
+ title: "Background Position",
133
+ type: "string",
134
+ description: "CSS background-position value",
135
+ initialValue: "center center",
136
+ }),
137
+ defineField({
138
+ name: "background_size",
139
+ title: "Background Size",
140
+ type: "string",
141
+ options: {
142
+ list: [
143
+ { title: "Cover", value: "cover" },
144
+ { title: "Contain", value: "contain" },
145
+ { title: "Auto", value: "auto" },
146
+ ],
147
+ },
148
+ initialValue: "cover",
149
+ }),
150
+ defineField({
151
+ name: "background_overlay_color",
152
+ title: "Overlay Color",
153
+ type: "string",
154
+ description: "Hex color for background overlay",
155
+ initialValue: "#000000",
156
+ }),
157
+ defineField({
158
+ name: "background_overlay_opacity",
159
+ title: "Overlay Opacity",
160
+ type: "number",
161
+ description: "0–100",
162
+ initialValue: 0,
163
+ validation: (Rule) => Rule.min(0).max(100),
164
+ }),
165
+
166
+ // ── Section Height ──
167
+ defineField({
168
+ name: "height",
169
+ title: "Section Height",
170
+ type: "string",
171
+ options: {
172
+ list: [
173
+ { title: "Full Viewport (100vh)", value: "100vh" },
174
+ { title: "80% Viewport (80vh)", value: "80vh" },
175
+ { title: "50% Viewport (50vh)", value: "50vh" },
176
+ ],
177
+ },
178
+ initialValue: "100vh",
179
+ }),
180
+
181
+ // ── Cover Rows (explicit, proportional) ──
182
+ defineField({
183
+ name: "cover_rows",
184
+ title: "Cover Rows",
185
+ type: "array",
186
+ description: "Proportional rows — heights must sum to 100%",
187
+ of: [
188
+ {
189
+ type: "object",
190
+ name: "coverRow",
191
+ fields: [
192
+ defineField({
193
+ name: "height_percent",
194
+ title: "Height (%)",
195
+ type: "number",
196
+ description: "Row height as percentage of section (5–95)",
197
+ validation: (Rule) => Rule.required().min(5).max(95),
198
+ }),
199
+ defineField({
200
+ name: "vertical_align",
201
+ title: "Vertical Alignment",
202
+ type: "string",
203
+ description: "How content is aligned vertically within this row",
204
+ options: {
205
+ list: [
206
+ { title: "Top", value: "start" },
207
+ { title: "Center", value: "center" },
208
+ { title: "Bottom", value: "end" },
209
+ ],
210
+ },
211
+ initialValue: "start",
212
+ }),
213
+ ],
214
+ preview: {
215
+ select: { height: "height_percent", align: "vertical_align" },
216
+ prepare({ height, align }) {
217
+ return { title: `${height ?? 0}%`, subtitle: align ?? "start" };
218
+ },
219
+ },
220
+ },
221
+ ],
222
+ validation: (Rule) => Rule.required().min(1).max(5),
223
+ }),
224
+
225
+ // ── Columns (same structure as V2) ──
226
+ defineField({
227
+ name: "columns",
228
+ title: "Columns",
229
+ type: "array",
230
+ of: [
231
+ {
232
+ type: "object",
233
+ name: "sectionColumn",
234
+ fields: columnFields,
235
+ },
236
+ ],
237
+ }),
238
+
239
+ // ── Section Settings (subset of V2 — no background/border, those are section-level) ──
240
+ defineField({
241
+ name: "settings",
242
+ title: "Section Settings",
243
+ type: "object",
244
+ fields: [
245
+ defineField({ name: "grid_columns", title: "Grid Columns", type: "number" }),
246
+ defineField({ name: "col_gap", title: "Column Gap", type: "number" }),
247
+ defineField({ name: "row_gap", title: "Row Gap", type: "number" }),
248
+ // Spacing (padding TRBL)
249
+ defineField({ name: "spacing_top", title: "Spacing Top", type: "string" }),
250
+ defineField({ name: "spacing_right", title: "Spacing Right", type: "string" }),
251
+ defineField({ name: "spacing_bottom", title: "Spacing Bottom", type: "string" }),
252
+ defineField({ name: "spacing_left", title: "Spacing Left", type: "string" }),
253
+ // Animation
254
+ defineField({
255
+ name: "enter_animation",
256
+ title: "Enter Animation",
257
+ type: "enterAnimationConfig",
258
+ }),
259
+ defineField({
260
+ name: "stagger",
261
+ title: "Stagger",
262
+ type: "object",
263
+ fields: [
264
+ defineField({ name: "enabled", title: "Enabled", type: "boolean" }),
265
+ defineField({ name: "delayPerChild", title: "Delay Per Child", type: "number" }),
266
+ defineField({
267
+ name: "direction",
268
+ title: "Direction",
269
+ type: "string",
270
+ options: { list: ["left-to-right", "right-to-left"] },
271
+ }),
272
+ ],
273
+ }),
274
+ ],
275
+ }),
276
+
277
+ // ── Responsive Overrides ──
278
+ defineField({
279
+ name: "responsive",
280
+ title: "Responsive Overrides",
281
+ type: "object",
282
+ hidden: true,
283
+ fields: [
284
+ defineField({
285
+ name: "tablet",
286
+ title: "Tablet",
287
+ type: "object",
288
+ fields: [
289
+ ...responsiveColumnOverrideFields,
290
+ ...responsiveRowOverrideFields,
291
+ ...responsiveSettingsFields,
292
+ ],
293
+ }),
294
+ defineField({
295
+ name: "phone",
296
+ title: "Phone",
297
+ type: "object",
298
+ fields: [
299
+ ...responsiveColumnOverrideFields,
300
+ ...responsiveRowOverrideFields,
301
+ ...responsiveSettingsFields,
302
+ ],
303
+ }),
304
+ ],
305
+ }),
306
+ ],
307
+ preview: {
308
+ select: { height: "height", rows: "cover_rows" },
309
+ prepare({ height, rows }) {
310
+ const rowCount = Array.isArray(rows) ? rows.length : 0;
311
+ return {
312
+ title: "Cover Section",
313
+ subtitle: `${height || "100vh"} · ${rowCount} row${rowCount !== 1 ? "s" : ""}`,
314
+ };
315
+ },
316
+ },
317
+ });
@@ -108,7 +108,6 @@ export default defineType({
108
108
  { type: "videoBlock" },
109
109
  { type: "spacerBlock" },
110
110
  { type: "buttonBlock" },
111
- { type: "coverBlock" },
112
111
  ],
113
112
  }),
114
113
  defineField({
@@ -42,7 +42,7 @@ export default defineType({
42
42
  name: "content_rows",
43
43
  title: "Content Rows",
44
44
  type: "array",
45
- of: [{ type: "pageSectionV2" }, { type: "parallaxGroup" }, { type: "customSectionInstance" }],
45
+ of: [{ type: "pageSectionV2" }, { type: "parallaxGroup" }, { type: "customSectionInstance" }, { type: "coverSection" }],
46
46
  }),
47
47
  defineField({
48
48
  name: "metadata",
@@ -66,7 +66,6 @@ export default defineType({
66
66
  { type: "videoBlock" },
67
67
  { type: "spacerBlock" },
68
68
  { type: "buttonBlock" },
69
- { type: "coverBlock" },
70
69
  { type: "projectGridBlock" },
71
70
  ],
72
71
  }),