@morphika/andami 0.1.8 → 0.1.10
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 +3 -0
- package/components/admin/nav-builder/NavBuilder.tsx +90 -14
- package/components/admin/nav-builder/NavGeneralSettings.tsx +521 -271
- package/components/admin/nav-builder/NavItemSettings.tsx +331 -312
- package/components/admin/nav-builder/NavMobileSettings.tsx +159 -140
- package/components/admin/nav-builder/NavSettingsFields.tsx +287 -21
- package/components/admin/nav-builder/NavSettingsPanel.tsx +137 -127
- package/components/blocks/TextBlockRenderer.tsx +1 -1
- package/components/builder/SettingsPanel.tsx +29 -543
- package/components/builder/editors/ButtonBlockEditor.tsx +8 -3
- package/components/builder/editors/CoverBlockEditor.tsx +14 -6
- package/components/builder/editors/ImageBlockEditor.tsx +8 -3
- package/components/builder/editors/ImageGridBlockEditor.tsx +8 -3
- package/components/builder/editors/ProjectGridEditor.tsx +7 -46
- package/components/builder/editors/SpacerBlockEditor.tsx +4 -1
- package/components/builder/editors/StaggerSettings.tsx +2 -1
- package/components/builder/editors/TextBlockEditor.tsx +8 -3
- package/components/builder/editors/VideoBlockEditor.tsx +10 -4
- package/components/builder/editors/section-icons.tsx +492 -0
- package/components/builder/editors/shared.tsx +23 -4
- package/components/builder/live-preview/GhostCard.tsx +84 -0
- package/components/builder/live-preview/LiveProjectGridPreview.tsx +294 -1010
- package/components/builder/live-preview/LiveTextEditor.tsx +1 -1
- package/components/builder/live-preview/ProjectCardWrapper.tsx +291 -0
- package/components/builder/live-preview/drag-utils.tsx +89 -0
- package/components/builder/live-preview/useDragReorder.ts +370 -0
- package/components/builder/settings-panel/AnimationTab.tsx +152 -0
- package/components/builder/settings-panel/BlockLayoutTab.tsx +13 -58
- package/components/builder/settings-panel/CardEntranceSection.tsx +114 -0
- package/components/builder/settings-panel/ColumnV2AnimationTab.tsx +32 -0
- package/components/builder/settings-panel/ColumnV2Settings.tsx +4 -1
- package/components/builder/settings-panel/CustomSectionSettings.tsx +150 -0
- package/components/builder/settings-panel/LayoutTab.tsx +11 -47
- package/components/builder/settings-panel/PageSettings.tsx +10 -4
- package/components/builder/settings-panel/ParallaxGroupSettings.tsx +6 -2
- package/components/builder/settings-panel/ParallaxSlideSettings.tsx +8 -3
- package/components/builder/settings-panel/SectionV2LayoutTab.tsx +11 -47
- package/components/builder/settings-panel/SectionV2Settings.tsx +6 -27
- package/components/builder/settings-panel/index.ts +6 -0
- package/components/builder/settings-panel/useSettingsPanelSelection.ts +184 -0
- package/components/ui/Navbar.tsx +151 -30
- package/lib/builder/serializer/migrations.ts +107 -0
- package/lib/builder/serializer/normalizers.ts +278 -0
- package/lib/builder/serializer/serializers.ts +393 -0
- package/lib/builder/serializer/shared.ts +102 -0
- package/lib/builder/serializer.ts +11 -846
- package/lib/sanity/types.ts +22 -0
- package/package.json +13 -10
- package/styles/base.css +7 -3
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
import { useBuilderStore } from "../../../lib/builder/store";
|
|
4
4
|
import { getEffectiveValue, setResponsiveOverride } from "../../../lib/builder/responsive";
|
|
5
5
|
import type { CoverBlock, ContentBlock } from "../../../lib/sanity/types";
|
|
6
|
+
import {
|
|
7
|
+
ContentIcon,
|
|
8
|
+
CTAButtonIcon,
|
|
9
|
+
CoverBackgroundIcon,
|
|
10
|
+
CoverEffectsIcon,
|
|
11
|
+
LayoutIcon,
|
|
12
|
+
AppearanceIcon,
|
|
13
|
+
} from "./section-icons";
|
|
6
14
|
import {
|
|
7
15
|
SettingsField,
|
|
8
16
|
SettingsSection,
|
|
@@ -190,7 +198,7 @@ export default function CoverBlockEditor({ block }: Props) {
|
|
|
190
198
|
<ViewportBadge />
|
|
191
199
|
|
|
192
200
|
{/* ========== CONTENT ========== */}
|
|
193
|
-
<SettingsSection title="Content" defaultOpen>
|
|
201
|
+
<SettingsSection title="Content" defaultOpen icon={<ContentIcon />}>
|
|
194
202
|
<SettingsField label="Headline">
|
|
195
203
|
<StyledInput
|
|
196
204
|
value={block.headline || ""}
|
|
@@ -211,7 +219,7 @@ export default function CoverBlockEditor({ block }: Props) {
|
|
|
211
219
|
</SettingsSection>
|
|
212
220
|
|
|
213
221
|
{/* ========== CTA BUTTON ========== */}
|
|
214
|
-
<SettingsSection title="CTA Button">
|
|
222
|
+
<SettingsSection title="CTA Button" icon={<CTAButtonIcon />}>
|
|
215
223
|
<SettingsField label="Button Text">
|
|
216
224
|
<StyledInput
|
|
217
225
|
value={cta.text || ""}
|
|
@@ -264,7 +272,7 @@ export default function CoverBlockEditor({ block }: Props) {
|
|
|
264
272
|
</SettingsSection>
|
|
265
273
|
|
|
266
274
|
{/* ========== MEDIA BACKGROUND ========== */}
|
|
267
|
-
<SettingsSection title="Cover Background" defaultOpen>
|
|
275
|
+
<SettingsSection title="Cover Background" defaultOpen icon={<CoverBackgroundIcon />}>
|
|
268
276
|
<SettingsField label="Media Type">
|
|
269
277
|
<div className="flex gap-1">
|
|
270
278
|
{(["image", "video"] as const).map((t) => (
|
|
@@ -355,7 +363,7 @@ export default function CoverBlockEditor({ block }: Props) {
|
|
|
355
363
|
</SettingsSection>
|
|
356
364
|
|
|
357
365
|
{/* ========== OVERLAY ========== */}
|
|
358
|
-
<SettingsSection title="Cover Effects">
|
|
366
|
+
<SettingsSection title="Cover Effects" icon={<CoverEffectsIcon />}>
|
|
359
367
|
{/* Toggle: Custom gradient vs Preset overlay */}
|
|
360
368
|
<SettingsField label="Overlay Mode">
|
|
361
369
|
<div className="flex gap-1">
|
|
@@ -448,7 +456,7 @@ export default function CoverBlockEditor({ block }: Props) {
|
|
|
448
456
|
</SettingsSection>
|
|
449
457
|
|
|
450
458
|
{/* ========== LAYOUT ========== */}
|
|
451
|
-
<SettingsSection title="Layout">
|
|
459
|
+
<SettingsSection title="Layout" icon={<LayoutIcon />}>
|
|
452
460
|
<ResponsiveField
|
|
453
461
|
label="Content Pos"
|
|
454
462
|
block={block as ContentBlock}
|
|
@@ -522,7 +530,7 @@ export default function CoverBlockEditor({ block }: Props) {
|
|
|
522
530
|
</SettingsSection>
|
|
523
531
|
|
|
524
532
|
{/* ========== APPEARANCE ========== */}
|
|
525
|
-
<SettingsSection title="Appearance">
|
|
533
|
+
<SettingsSection title="Appearance" icon={<AppearanceIcon />}>
|
|
526
534
|
<SettingsField label="Text Color">
|
|
527
535
|
<ColorSwatchPicker
|
|
528
536
|
value={block.text_color || ""}
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
import { useBuilderStore } from "../../../lib/builder/store";
|
|
4
4
|
import { getEffectiveValue, setResponsiveOverride } from "../../../lib/builder/responsive";
|
|
5
5
|
import type { ImageBlock, ContentBlock } from "../../../lib/sanity/types";
|
|
6
|
+
import {
|
|
7
|
+
SourceIcon,
|
|
8
|
+
LayoutIcon,
|
|
9
|
+
AppearanceIcon,
|
|
10
|
+
} from "./section-icons";
|
|
6
11
|
import {
|
|
7
12
|
SettingsField,
|
|
8
13
|
SettingsSection,
|
|
@@ -61,7 +66,7 @@ export default function ImageBlockEditor({ block }: Props) {
|
|
|
61
66
|
<>
|
|
62
67
|
<ViewportBadge />
|
|
63
68
|
|
|
64
|
-
<SettingsSection title="Source" defaultOpen>
|
|
69
|
+
<SettingsSection title="Source" defaultOpen icon={<SourceIcon />}>
|
|
65
70
|
<SettingsField label="Asset Path" hint="Relative path from seed URL">
|
|
66
71
|
<AssetPathInput
|
|
67
72
|
value={block.asset_path || ""}
|
|
@@ -95,7 +100,7 @@ export default function ImageBlockEditor({ block }: Props) {
|
|
|
95
100
|
</SettingsField>
|
|
96
101
|
</SettingsSection>
|
|
97
102
|
|
|
98
|
-
<SettingsSection title="Layout">
|
|
103
|
+
<SettingsSection title="Layout" icon={<LayoutIcon />}>
|
|
99
104
|
<ResponsiveField
|
|
100
105
|
label="Width"
|
|
101
106
|
block={block}
|
|
@@ -147,7 +152,7 @@ export default function ImageBlockEditor({ block }: Props) {
|
|
|
147
152
|
</ResponsiveField>
|
|
148
153
|
</SettingsSection>
|
|
149
154
|
|
|
150
|
-
<SettingsSection title="Appearance">
|
|
155
|
+
<SettingsSection title="Appearance" icon={<AppearanceIcon />}>
|
|
151
156
|
<ResponsiveField
|
|
152
157
|
label="Border Radius"
|
|
153
158
|
block={block}
|
|
@@ -5,6 +5,11 @@ import { useBuilderStore } from "../../../lib/builder/store";
|
|
|
5
5
|
import { getEffectiveValue, setResponsiveOverride } from "../../../lib/builder/responsive";
|
|
6
6
|
import type { ImageGridBlock, ContentBlock } from "../../../lib/sanity/types";
|
|
7
7
|
import AssetBrowser from "../AssetBrowser";
|
|
8
|
+
import {
|
|
9
|
+
ImagesIcon,
|
|
10
|
+
SettingsIcon,
|
|
11
|
+
AppearanceIcon,
|
|
12
|
+
} from "./section-icons";
|
|
8
13
|
import {
|
|
9
14
|
SettingsField,
|
|
10
15
|
SettingsSection,
|
|
@@ -158,7 +163,7 @@ export default function ImageGridBlockEditor({ block }: Props) {
|
|
|
158
163
|
<ViewportBadge />
|
|
159
164
|
|
|
160
165
|
{/* ====== Images Section ====== */}
|
|
161
|
-
<SettingsSection title="Images" defaultOpen>
|
|
166
|
+
<SettingsSection title="Images" defaultOpen icon={<ImagesIcon />}>
|
|
162
167
|
{/* Thumbnail grid preview */}
|
|
163
168
|
{images.length > 0 && (
|
|
164
169
|
<div className="grid grid-cols-4 gap-1.5 mb-3">
|
|
@@ -209,7 +214,7 @@ export default function ImageGridBlockEditor({ block }: Props) {
|
|
|
209
214
|
</SettingsSection>
|
|
210
215
|
|
|
211
216
|
{/* ====== Settings Section ====== */}
|
|
212
|
-
<SettingsSection title="Settings" defaultOpen>
|
|
217
|
+
<SettingsSection title="Settings" defaultOpen icon={<SettingsIcon />}>
|
|
213
218
|
{/* H-Gutter & V-Gutter side by side */}
|
|
214
219
|
<div className="flex gap-3">
|
|
215
220
|
<ResponsiveField
|
|
@@ -336,7 +341,7 @@ export default function ImageGridBlockEditor({ block }: Props) {
|
|
|
336
341
|
</SettingsSection>
|
|
337
342
|
|
|
338
343
|
{/* ====== Appearance Section ====== */}
|
|
339
|
-
<SettingsSection title="Appearance">
|
|
344
|
+
<SettingsSection title="Appearance" icon={<AppearanceIcon />}>
|
|
340
345
|
<ResponsiveField
|
|
341
346
|
label="Object Fit"
|
|
342
347
|
block={block}
|
|
@@ -232,52 +232,13 @@ function CardRatioChips({
|
|
|
232
232
|
);
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
-
//
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
<rect x="1.5" y="1.5" width="4.5" height="4.5" rx="1" stroke="currentColor" strokeWidth="0.8" fill="none" opacity="0.6" />
|
|
243
|
-
<rect x="8" y="1.5" width="4.5" height="4.5" rx="1" stroke="currentColor" strokeWidth="0.8" fill="none" opacity="0.6" />
|
|
244
|
-
<rect x="1.5" y="8" width="4.5" height="4.5" rx="1" stroke="currentColor" strokeWidth="0.8" fill="none" opacity="0.6" />
|
|
245
|
-
<rect x="8" y="8" width="4.5" height="4.5" rx="1" stroke="currentColor" strokeWidth="0.8" fill="none" opacity="0.6" />
|
|
246
|
-
</svg>
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function AppearanceSectionIcon() {
|
|
251
|
-
return (
|
|
252
|
-
<svg width={14} height={14} viewBox="0 0 14 14" fill="none">
|
|
253
|
-
<circle cx="7" cy="7" r="5" stroke="currentColor" strokeWidth="0.8" fill="none" opacity="0.5" />
|
|
254
|
-
<path d="M7 2 A5 5 0 0 1 7 12 Z" fill="currentColor" opacity="0.3" />
|
|
255
|
-
<circle cx="7" cy="7" r="1.5" fill="currentColor" opacity="0.6" />
|
|
256
|
-
</svg>
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
function VideoSectionIcon() {
|
|
261
|
-
return (
|
|
262
|
-
<svg width={14} height={14} viewBox="0 0 14 14" fill="none">
|
|
263
|
-
<rect x="1.5" y="3" width="8" height="8" rx="1.5" stroke="currentColor" strokeWidth="0.8" fill="none" opacity="0.5" />
|
|
264
|
-
<path d="M10 6 L12.5 4.5 L12.5 9.5 L10 8 Z" fill="currentColor" opacity="0.5" />
|
|
265
|
-
</svg>
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
function ProjectsSectionIcon() {
|
|
270
|
-
return (
|
|
271
|
-
<svg width={14} height={14} viewBox="0 0 14 14" fill="none">
|
|
272
|
-
<rect x="1.5" y="2" width="11" height="3" rx="1" stroke="currentColor" strokeWidth="0.8" fill="none" opacity="0.5" />
|
|
273
|
-
<rect x="1.5" y="7" width="11" height="3" rx="1" stroke="currentColor" strokeWidth="0.8" fill="none" opacity="0.5" />
|
|
274
|
-
<circle cx="4" cy="3.5" r="0.8" fill="currentColor" opacity="0.6" />
|
|
275
|
-
<circle cx="4" cy="8.5" r="0.8" fill="currentColor" opacity="0.6" />
|
|
276
|
-
<rect x="6" y="3" width="4" height="1" rx="0.5" fill="currentColor" opacity="0.4" />
|
|
277
|
-
<rect x="6" y="8" width="4" height="1" rx="0.5" fill="currentColor" opacity="0.4" />
|
|
278
|
-
</svg>
|
|
279
|
-
);
|
|
280
|
-
}
|
|
235
|
+
// ── Section title icons (centralized colored icons — Session 163) ──
|
|
236
|
+
import {
|
|
237
|
+
GridIcon as GridSectionIcon,
|
|
238
|
+
AppearanceIcon as AppearanceSectionIcon,
|
|
239
|
+
VideoIcon as VideoSectionIcon,
|
|
240
|
+
ProjectsIcon as ProjectsSectionIcon,
|
|
241
|
+
} from "./section-icons";
|
|
281
242
|
|
|
282
243
|
// ============================================
|
|
283
244
|
// Main Editor
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
import { useBuilderStore } from "../../../lib/builder/store";
|
|
4
4
|
import { getEffectiveValue, setResponsiveOverride } from "../../../lib/builder/responsive";
|
|
5
5
|
import type { SpacerBlock, ContentBlock } from "../../../lib/sanity/types";
|
|
6
|
+
import {
|
|
7
|
+
HeightIcon,
|
|
8
|
+
} from "./section-icons";
|
|
6
9
|
import {
|
|
7
10
|
SettingsField,
|
|
8
11
|
SettingsSection,
|
|
@@ -68,7 +71,7 @@ export default function SpacerBlockEditor({ block }: Props) {
|
|
|
68
71
|
<>
|
|
69
72
|
<ViewportBadge />
|
|
70
73
|
|
|
71
|
-
<SettingsSection title="Height" defaultOpen>
|
|
74
|
+
<SettingsSection title="Height" defaultOpen icon={<HeightIcon />}>
|
|
72
75
|
<ResponsiveField
|
|
73
76
|
label="Preset"
|
|
74
77
|
block={block}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { StaggerIcon } from "./section-icons";
|
|
1
2
|
import { SettingsSection, SettingsField } from "./shared";
|
|
2
3
|
|
|
3
4
|
// ============================================
|
|
@@ -39,7 +40,7 @@ export default function StaggerSettings({
|
|
|
39
40
|
const direction = stagger?.direction ?? "left-to-right";
|
|
40
41
|
|
|
41
42
|
return (
|
|
42
|
-
<SettingsSection title="Stagger Children">
|
|
43
|
+
<SettingsSection title="Stagger Children" icon={<StaggerIcon />}>
|
|
43
44
|
<div className="space-y-3">
|
|
44
45
|
{/* Enable toggle */}
|
|
45
46
|
<div className="flex items-center justify-between">
|
|
@@ -5,6 +5,11 @@ import { useBuilderStore } from "../../../lib/builder/store";
|
|
|
5
5
|
import { getEffectiveValue, setResponsiveOverride } from "../../../lib/builder/responsive";
|
|
6
6
|
import type { TextBlock, ContentBlock } from "../../../lib/sanity/types";
|
|
7
7
|
import type { DeviceViewport } from "../../../lib/builder/types";
|
|
8
|
+
import {
|
|
9
|
+
TextIcon,
|
|
10
|
+
TypographyIcon,
|
|
11
|
+
ColumnsIcon,
|
|
12
|
+
} from "./section-icons";
|
|
8
13
|
import {
|
|
9
14
|
SettingsSection,
|
|
10
15
|
SettingsField,
|
|
@@ -267,7 +272,7 @@ export default function TextBlockEditor({ block }: { block: TextBlock }) {
|
|
|
267
272
|
<ViewportBadge />
|
|
268
273
|
|
|
269
274
|
{/* Text section: Style, Color, Align */}
|
|
270
|
-
<SettingsSection title="Text" defaultOpen>
|
|
275
|
+
<SettingsSection title="Text" defaultOpen icon={<TextIcon />}>
|
|
271
276
|
<SettingsField label="Style">
|
|
272
277
|
<TextStylePicker
|
|
273
278
|
presets={presets}
|
|
@@ -307,7 +312,7 @@ export default function TextBlockEditor({ block }: { block: TextBlock }) {
|
|
|
307
312
|
</SettingsSection>
|
|
308
313
|
|
|
309
314
|
{/* Typography section: Size, Weight, Line height, Letter spacing */}
|
|
310
|
-
<SettingsSection title="Typography" defaultOpen>
|
|
315
|
+
<SettingsSection title="Typography" defaultOpen icon={<TypographyIcon />}>
|
|
311
316
|
<ResponsiveStyleField label="Size" subProp="fontSize" viewport={viewport} isOverridden={viewport !== "desktop" && hasStyleOverride("fontSize")} onReset={resetStyleOverride}>
|
|
312
317
|
<div className="flex items-center gap-0 bg-[#f5f5f5] rounded-lg overflow-hidden transition-all border border-transparent focus-within:bg-white focus-within:border-[#076bff] focus-within:shadow-[0_0_0_3px_rgba(7,107,255,0.06)]">
|
|
313
318
|
<input
|
|
@@ -401,7 +406,7 @@ export default function TextBlockEditor({ block }: { block: TextBlock }) {
|
|
|
401
406
|
</SettingsSection>
|
|
402
407
|
|
|
403
408
|
{/* Columns section */}
|
|
404
|
-
<SettingsSection title="Columns">
|
|
409
|
+
<SettingsSection title="Columns" icon={<ColumnsIcon />}>
|
|
405
410
|
<ResponsiveField
|
|
406
411
|
label="Columns"
|
|
407
412
|
block={block as ContentBlock}
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
import { useBuilderStore } from "../../../lib/builder/store";
|
|
4
4
|
import { getEffectiveValue, setResponsiveOverride } from "../../../lib/builder/responsive";
|
|
5
5
|
import type { VideoBlock, ContentBlock } from "../../../lib/sanity/types";
|
|
6
|
+
import {
|
|
7
|
+
SourceIcon,
|
|
8
|
+
LayoutIcon,
|
|
9
|
+
AppearanceIcon,
|
|
10
|
+
PlaybackIcon,
|
|
11
|
+
} from "./section-icons";
|
|
6
12
|
import {
|
|
7
13
|
SettingsField,
|
|
8
14
|
SettingsSection,
|
|
@@ -89,7 +95,7 @@ export default function VideoBlockEditor({ block }: Props) {
|
|
|
89
95
|
<>
|
|
90
96
|
<ViewportBadge />
|
|
91
97
|
|
|
92
|
-
<SettingsSection title="Source" defaultOpen>
|
|
98
|
+
<SettingsSection title="Source" defaultOpen icon={<SourceIcon />}>
|
|
93
99
|
<SettingsField label="Video Type">
|
|
94
100
|
<div className="flex gap-1">
|
|
95
101
|
{(
|
|
@@ -174,7 +180,7 @@ export default function VideoBlockEditor({ block }: Props) {
|
|
|
174
180
|
</SettingsField>
|
|
175
181
|
</SettingsSection>
|
|
176
182
|
|
|
177
|
-
<SettingsSection title="Layout">
|
|
183
|
+
<SettingsSection title="Layout" icon={<LayoutIcon />}>
|
|
178
184
|
<ResponsiveField
|
|
179
185
|
label="Width"
|
|
180
186
|
block={block as ContentBlock}
|
|
@@ -224,7 +230,7 @@ export default function VideoBlockEditor({ block }: Props) {
|
|
|
224
230
|
</ResponsiveField>
|
|
225
231
|
</SettingsSection>
|
|
226
232
|
|
|
227
|
-
<SettingsSection title="Appearance">
|
|
233
|
+
<SettingsSection title="Appearance" icon={<AppearanceIcon />}>
|
|
228
234
|
<ResponsiveField
|
|
229
235
|
label="Border Radius"
|
|
230
236
|
block={block as ContentBlock}
|
|
@@ -249,7 +255,7 @@ export default function VideoBlockEditor({ block }: Props) {
|
|
|
249
255
|
</ResponsiveField>
|
|
250
256
|
</SettingsSection>
|
|
251
257
|
|
|
252
|
-
<SettingsSection title="Playback">
|
|
258
|
+
<SettingsSection title="Playback" icon={<PlaybackIcon />}>
|
|
253
259
|
<div className="space-y-1.5">
|
|
254
260
|
<StyledCheckbox
|
|
255
261
|
label="Autoplay"
|