@morphika/andami 0.1.3 → 0.1.5
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/app/(site)/[slug]/page.tsx +2 -2
- package/app/(site)/layout.tsx +1 -0
- package/app/(site)/page.tsx +2 -2
- package/app/(site)/preview/page.tsx +4 -4
- package/app/(site)/work/[slug]/page.tsx +2 -2
- package/app/admin/layout.tsx +2 -2
- package/app/admin/login/page.tsx +5 -5
- package/app/admin/navigation/page.tsx +255 -157
- package/app/api/admin/assets/relink/confirm/route.ts +1 -1
- package/app/api/admin/pages/[slug]/route.ts +1 -1
- package/app/api/admin/settings/route.ts +40 -15
- package/app/api/admin/setup/complete/route.ts +1 -1
- package/app/api/admin/setup/route.ts +6 -3
- package/components/admin/index.ts +7 -0
- package/components/admin/nav-builder/NavGeneralSettings.tsx +11 -15
- package/components/admin/nav-builder/NavItemSettings.tsx +29 -5
- package/components/admin/nav-builder/NavLivePreview.tsx +4 -1
- package/components/admin/nav-builder/NavMobileLivePreview.tsx +226 -0
- package/components/admin/nav-builder/NavMobileSettings.tsx +223 -0
- package/components/admin/nav-builder/index.ts +2 -0
- package/components/blocks/BlockRenderer.tsx +65 -13
- package/components/blocks/ButtonBlockRenderer.tsx +29 -6
- package/components/blocks/CoverBlockRenderer.tsx +36 -14
- package/components/blocks/ImageBlockRenderer.tsx +5 -3
- package/components/blocks/ImageGridBlockRenderer.tsx +13 -6
- package/components/blocks/PageRenderer.tsx +4 -2
- package/components/blocks/ProjectGridBlockRenderer.tsx +18 -3
- package/components/blocks/SectionRenderer.tsx +9 -8
- package/components/blocks/SectionV2Renderer.tsx +8 -8
- package/components/blocks/SpacerBlockRenderer.tsx +4 -2
- package/components/blocks/TextBlockRenderer.tsx +9 -4
- package/components/builder/BuilderCanvas.tsx +10 -4
- package/components/builder/ColorPicker.tsx +51 -243
- package/components/builder/ColorSwatchPicker.tsx +214 -274
- package/components/builder/DndWrapper.tsx +5 -2
- package/components/builder/SectionV2Canvas.tsx +15 -4
- package/components/builder/asset-browser/useAssetBrowser.ts +9 -1
- package/components/builder/color-picker/AlphaSlider.tsx +141 -0
- package/components/builder/color-picker/AngleControl.tsx +138 -0
- package/components/builder/color-picker/ColorInputs.tsx +105 -0
- package/components/builder/color-picker/EyedropperButton.tsx +74 -0
- package/components/builder/color-picker/GradientBar.tsx +222 -0
- package/components/builder/color-picker/GradientPreview.tsx +53 -0
- package/components/builder/color-picker/HueSlider.tsx +124 -0
- package/components/builder/color-picker/MeshCanvas.tsx +172 -0
- package/components/builder/color-picker/MeshPointEditor.tsx +133 -0
- package/components/builder/color-picker/MeshPointList.tsx +200 -0
- package/components/builder/color-picker/PositionControl.tsx +158 -0
- package/components/builder/color-picker/SaturationCanvas.tsx +142 -0
- package/components/builder/color-picker/StopEditor.tsx +178 -0
- package/components/builder/color-picker/SwatchBar.tsx +93 -0
- package/components/builder/color-picker/UnifiedColorPicker.tsx +713 -0
- package/components/builder/color-picker/index.ts +62 -0
- package/components/builder/color-picker/types.ts +115 -0
- package/components/builder/color-picker/utils.ts +138 -0
- package/components/builder/editors/CoverBlockEditor.tsx +86 -32
- package/components/builder/editors/ProjectGridEditor.tsx +51 -4
- package/components/builder/hooks/useColumnDrag.ts +25 -27
- package/components/builder/settings-panel/BlockLayoutTab.tsx +29 -7
- package/components/builder/settings-panel/LayoutTab.tsx +382 -310
- package/components/builder/settings-panel/PageSettings.tsx +6 -4
- package/components/builder/settings-panel/ParallaxSlideSettings.tsx +2 -2
- package/components/builder/settings-panel/SectionV2LayoutTab.tsx +392 -312
- package/components/builder/settings-panel/SectionV2Settings.tsx +65 -35
- package/components/ui/Navbar.tsx +95 -25
- package/components/ui/PortfolioTracker.tsx +3 -3
- package/lib/assets.ts +1 -1
- package/lib/auth.ts +1 -1
- package/lib/builder/gradient-presets.ts +128 -0
- package/lib/builder/layout-styles.ts +16 -10
- package/lib/builder/serializer.ts +1 -0
- package/lib/builder/store-blocks.ts +48 -61
- package/lib/builder/store-helpers.ts +31 -14
- package/lib/builder/store.ts +59 -41
- package/lib/builder/types.ts +14 -0
- package/lib/color-utils.ts +200 -0
- package/lib/revalidate.ts +2 -2
- package/lib/sanity/queries.ts +4 -3
- package/lib/sanity/types.ts +76 -1
- package/lib/setup/detect.ts +1 -1
- package/package.json +8 -2
- package/sanity/schemas/siteSettings.ts +34 -0
- package/styles/base.css +3 -3
- package/app/globals.css +0 -7
package/lib/sanity/types.ts
CHANGED
|
@@ -232,6 +232,9 @@ export interface CoverBlock {
|
|
|
232
232
|
// Overlay
|
|
233
233
|
overlay?: "none" | "dark" | "light" | "gradient-bottom" | "gradient-top";
|
|
234
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;
|
|
235
238
|
// Layout
|
|
236
239
|
content_align_h?: "left" | "center" | "right";
|
|
237
240
|
content_align_v?: "top" | "center" | "bottom";
|
|
@@ -676,7 +679,8 @@ export interface NavItem {
|
|
|
676
679
|
|
|
677
680
|
export interface NavDesign {
|
|
678
681
|
logo_text?: string;
|
|
679
|
-
color
|
|
682
|
+
/** Nav text color — legacy NavColorVariant preset OR hex string (e.g. "#d4ff00"). */
|
|
683
|
+
color?: NavColorVariant | string;
|
|
680
684
|
position?: "fixed" | "sticky" | "static";
|
|
681
685
|
hide_on_scroll?: boolean;
|
|
682
686
|
font_size?: number;
|
|
@@ -702,6 +706,31 @@ export interface NavDesign {
|
|
|
702
706
|
entrance_stagger_delay?: number; // ms between items, default 80
|
|
703
707
|
}
|
|
704
708
|
|
|
709
|
+
// ============================================
|
|
710
|
+
// Mobile Nav Design — independent mobile menu styles (Session 158)
|
|
711
|
+
// ============================================
|
|
712
|
+
// These styles apply ONLY to the hamburger mobile menu.
|
|
713
|
+
// Page-level nav_color and parallax slide color overrides do NOT
|
|
714
|
+
// affect the mobile menu — it always uses these dedicated values
|
|
715
|
+
// (with fallback to desktop NavDesign where noted).
|
|
716
|
+
|
|
717
|
+
export interface MobileNavDesign {
|
|
718
|
+
// ── Overlay (expanded fullscreen menu) ──
|
|
719
|
+
overlay_bg?: string; // hex color, default "#0a0a0a" (brand-dark)
|
|
720
|
+
text_color?: string; // hex color, empty = inherit from desktop design.color
|
|
721
|
+
font_size?: number; // px, default 24
|
|
722
|
+
text_transform?: "none" | "uppercase" | "lowercase" | "capitalize";
|
|
723
|
+
items_gap?: number; // px, default 32
|
|
724
|
+
items_align?: "left" | "center" | "right";
|
|
725
|
+
|
|
726
|
+
// ── Navbar bar (logo + hamburger row, visible before menu opens) ──
|
|
727
|
+
navbar_bg?: string; // hex color, empty = transparent
|
|
728
|
+
navbar_bg_opacity?: number; // 0–100, default 0
|
|
729
|
+
hamburger_color?: string; // hex color, empty = inherit from desktop design.color
|
|
730
|
+
padding_h?: number; // px, default 24
|
|
731
|
+
padding_v?: number; // px, default 27
|
|
732
|
+
}
|
|
733
|
+
|
|
705
734
|
// ============================================
|
|
706
735
|
// Storage Provider
|
|
707
736
|
// ============================================
|
|
@@ -765,6 +794,7 @@ export interface AssetRegistry {
|
|
|
765
794
|
export interface SiteSettings {
|
|
766
795
|
nav_items?: NavItem[];
|
|
767
796
|
nav_design?: NavDesign;
|
|
797
|
+
nav_mobile_design?: MobileNavDesign;
|
|
768
798
|
default_title?: string;
|
|
769
799
|
default_description?: string;
|
|
770
800
|
default_og_image?: string;
|
|
@@ -811,6 +841,51 @@ export interface ColorSwatch {
|
|
|
811
841
|
hex: string;
|
|
812
842
|
}
|
|
813
843
|
|
|
844
|
+
// ─── Color Field (Phase 2 — gradient-ready) ───
|
|
845
|
+
|
|
846
|
+
/** A stop in a linear or radial gradient */
|
|
847
|
+
export interface GradientStop {
|
|
848
|
+
color: string; // hex #RRGGBB
|
|
849
|
+
alpha: number; // 0-1
|
|
850
|
+
position: number; // 0-100 (%)
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
/** A point in a mesh gradient */
|
|
854
|
+
export interface MeshPoint {
|
|
855
|
+
color: string; // hex #RRGGBB
|
|
856
|
+
x: number; // 0-100 (%)
|
|
857
|
+
y: number; // 0-100 (%)
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
export interface LinearGradient {
|
|
861
|
+
type: "linear";
|
|
862
|
+
stops: GradientStop[]; // min 2
|
|
863
|
+
angle: number; // 0-360
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
export interface RadialGradient {
|
|
867
|
+
type: "radial";
|
|
868
|
+
stops: GradientStop[]; // min 2
|
|
869
|
+
position: { x: number; y: number }; // center, 0-100
|
|
870
|
+
shape: "circle" | "ellipse";
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
export interface MeshGradient {
|
|
874
|
+
type: "mesh";
|
|
875
|
+
points: MeshPoint[]; // min 2
|
|
876
|
+
background: string; // hex
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/** Gradient value — only for fields that support gradients */
|
|
880
|
+
export type GradientValue = LinearGradient | RadialGradient | MeshGradient;
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* Color field value in Sanity.
|
|
884
|
+
* - string: solid hex color (backward compatible with existing data)
|
|
885
|
+
* - GradientValue: gradient (Phase 3 UI, renderers ready now)
|
|
886
|
+
*/
|
|
887
|
+
export type ColorField = string | GradientValue;
|
|
888
|
+
|
|
814
889
|
export interface ColorPalette {
|
|
815
890
|
swatches: ColorSwatch[];
|
|
816
891
|
// Legacy fields (backward compat, may be empty)
|
package/lib/setup/detect.ts
CHANGED
|
@@ -103,7 +103,7 @@ export async function isSetupMarkedComplete(): Promise<boolean> {
|
|
|
103
103
|
|
|
104
104
|
try {
|
|
105
105
|
const result = await client.fetch<{ complete: boolean }>(
|
|
106
|
-
`*[
|
|
106
|
+
`*[_id == "siteSettings"][0]{ "complete": setup_complete == true }`
|
|
107
107
|
);
|
|
108
108
|
return !!result?.complete;
|
|
109
109
|
} catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morphika/andami",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
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",
|
|
@@ -53,14 +53,21 @@
|
|
|
53
53
|
"./components/builder/editors/*": "./components/builder/editors/*.tsx",
|
|
54
54
|
"./components/builder/settings-panel": "./components/builder/settings-panel/index.ts",
|
|
55
55
|
"./components/builder/settings-panel/*": "./components/builder/settings-panel/*.tsx",
|
|
56
|
+
"./components/builder/settings-panel/responsive-helpers": "./components/builder/settings-panel/responsive-helpers.ts",
|
|
56
57
|
"./components/builder/asset-browser": "./components/builder/asset-browser/index.ts",
|
|
57
58
|
"./components/builder/asset-browser/*": "./components/builder/asset-browser/*.tsx",
|
|
59
|
+
"./components/builder/asset-browser/helpers": "./components/builder/asset-browser/helpers.ts",
|
|
60
|
+
"./components/builder/asset-browser/types": "./components/builder/asset-browser/types.ts",
|
|
61
|
+
"./components/builder/asset-browser/useAssetBrowser": "./components/builder/asset-browser/useAssetBrowser.ts",
|
|
62
|
+
"./components/builder/asset-browser/useR2DragDrop": "./components/builder/asset-browser/useR2DragDrop.ts",
|
|
63
|
+
"./components/builder/asset-browser/useR2Operations": "./components/builder/asset-browser/useR2Operations.ts",
|
|
58
64
|
"./components/builder/live-preview": "./components/builder/live-preview/index.ts",
|
|
59
65
|
"./components/builder/live-preview/*": "./components/builder/live-preview/*.tsx",
|
|
60
66
|
"./components/admin": "./components/admin/index.ts",
|
|
61
67
|
"./components/admin/*": "./components/admin/*.tsx",
|
|
62
68
|
"./components/admin/nav-builder": "./components/admin/nav-builder/index.ts",
|
|
63
69
|
"./components/admin/nav-builder/*": "./components/admin/nav-builder/*.tsx",
|
|
70
|
+
"./components/admin/nav-builder/nav-builder-utils": "./components/admin/nav-builder/nav-builder-utils.ts",
|
|
64
71
|
"./components/admin/styles": "./components/admin/styles/index.ts",
|
|
65
72
|
"./components/admin/styles/*": "./components/admin/styles/*.tsx",
|
|
66
73
|
"./components/ui/*": "./components/ui/*.tsx",
|
|
@@ -173,7 +180,6 @@
|
|
|
173
180
|
"@aws-sdk/client-s3": "^3.1021.0",
|
|
174
181
|
"@aws-sdk/s3-request-presigner": "^3.1021.0",
|
|
175
182
|
"@dnd-kit/core": "^6.3.1",
|
|
176
|
-
"@dnd-kit/modifiers": "^9.0.0",
|
|
177
183
|
"@dnd-kit/sortable": "^10.0.0",
|
|
178
184
|
"@dnd-kit/utilities": "^3.2.2",
|
|
179
185
|
"next-sanity": "^12.1.5",
|
|
@@ -213,6 +213,40 @@ export default defineType({
|
|
|
213
213
|
],
|
|
214
214
|
}),
|
|
215
215
|
|
|
216
|
+
// === MOBILE NAV DESIGN (Session 158) ===
|
|
217
|
+
defineField({
|
|
218
|
+
name: "nav_mobile_design",
|
|
219
|
+
title: "Mobile Navigation Design",
|
|
220
|
+
type: "object",
|
|
221
|
+
group: "nav_design",
|
|
222
|
+
description: "Independent styles for the mobile hamburger menu",
|
|
223
|
+
fields: [
|
|
224
|
+
defineField({ name: "overlay_bg", title: "Overlay Background", type: "string", description: "Hex color for fullscreen menu background" }),
|
|
225
|
+
defineField({ name: "text_color", title: "Text Color", type: "string", description: "Hex color, empty = inherit from desktop" }),
|
|
226
|
+
defineField({ name: "font_size", title: "Font Size (px)", type: "number", initialValue: 24 }),
|
|
227
|
+
defineField({
|
|
228
|
+
name: "text_transform",
|
|
229
|
+
title: "Text Transform",
|
|
230
|
+
type: "string",
|
|
231
|
+
options: { list: [{ title: "None", value: "none" }, { title: "Uppercase", value: "uppercase" }, { title: "Lowercase", value: "lowercase" }, { title: "Capitalize", value: "capitalize" }] },
|
|
232
|
+
initialValue: "uppercase",
|
|
233
|
+
}),
|
|
234
|
+
defineField({ name: "items_gap", title: "Items Gap (px)", type: "number", initialValue: 32 }),
|
|
235
|
+
defineField({
|
|
236
|
+
name: "items_align",
|
|
237
|
+
title: "Items Align",
|
|
238
|
+
type: "string",
|
|
239
|
+
options: { list: [{ title: "Left", value: "left" }, { title: "Center", value: "center" }, { title: "Right", value: "right" }] },
|
|
240
|
+
initialValue: "center",
|
|
241
|
+
}),
|
|
242
|
+
defineField({ name: "navbar_bg", title: "Navbar Bar Background", type: "string", description: "Hex color for the logo+hamburger bar" }),
|
|
243
|
+
defineField({ name: "navbar_bg_opacity", title: "Navbar Bar BG Opacity (%)", type: "number", initialValue: 0 }),
|
|
244
|
+
defineField({ name: "hamburger_color", title: "Hamburger Icon Color", type: "string", description: "Hex color, empty = inherit from desktop" }),
|
|
245
|
+
defineField({ name: "padding_h", title: "Horizontal Padding (px)", type: "number", initialValue: 24 }),
|
|
246
|
+
defineField({ name: "padding_v", title: "Vertical Padding (px)", type: "number", initialValue: 27 }),
|
|
247
|
+
],
|
|
248
|
+
}),
|
|
249
|
+
|
|
216
250
|
// === METADATA ===
|
|
217
251
|
defineField({ name: "default_title", title: "Default Title", type: "string", group: "meta", initialValue: _cfg.defaults.metaTitle }),
|
|
218
252
|
defineField({ name: "default_description", title: "Default Description", type: "text", rows: 3, group: "meta" }),
|
package/styles/base.css
CHANGED
|
@@ -46,7 +46,7 @@ html {
|
|
|
46
46
|
body {
|
|
47
47
|
background: var(--color-brand-dark);
|
|
48
48
|
color: var(--color-brand-text);
|
|
49
|
-
font-family: var(--font-
|
|
49
|
+
font-family: var(--font-sans);
|
|
50
50
|
overflow-x: clip;
|
|
51
51
|
width: 100%;
|
|
52
52
|
transition: background-color 300ms ease;
|
|
@@ -91,7 +91,7 @@ img[data-asset-failed]::after {
|
|
|
91
91
|
align-items: center;
|
|
92
92
|
justify-content: center;
|
|
93
93
|
font-size: 11px;
|
|
94
|
-
font-family: var(--font-
|
|
94
|
+
font-family: var(--font-sans);
|
|
95
95
|
letter-spacing: 0.05em;
|
|
96
96
|
text-transform: uppercase;
|
|
97
97
|
color: rgba(255, 255, 255, 0.7);
|
|
@@ -101,4 +101,4 @@ img[data-asset-failed]::after {
|
|
|
101
101
|
video[data-asset-failed] {
|
|
102
102
|
background: #1a1a1a;
|
|
103
103
|
min-height: 60px;
|
|
104
|
-
}
|
|
104
|
+
}
|
package/app/globals.css
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/* Morphika instance — imports all core styles.
|
|
2
|
-
This is the monolith entry point; equivalent to:
|
|
3
|
-
@import "@morphika/andami/styles/globals.css";
|
|
4
|
-
but uses relative paths since we're inside the monorepo. */
|
|
5
|
-
@import "../packages/core/styles/base.css";
|
|
6
|
-
@import "../packages/core/styles/animations.css";
|
|
7
|
-
@import "../packages/core/styles/admin.css";
|