@morphika/andami 0.5.4 → 0.5.6

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 (46) hide show
  1. package/app/admin/assets/page.tsx +3 -2
  2. package/app/admin/layout.tsx +4 -0
  3. package/components/admin/nav-builder/NavBuilder.tsx +2 -1
  4. package/components/admin/styles/FontsEditor.tsx +2 -1
  5. package/components/builder/ColumnDragOverlay.tsx +4 -4
  6. package/components/builder/CoverSectionCanvas.tsx +10 -9
  7. package/components/builder/InsertionLines.tsx +3 -3
  8. package/components/builder/SectionV2Canvas.tsx +3 -3
  9. package/components/builder/SectionV2Column.tsx +20 -20
  10. package/components/builder/SettingsPanel.tsx +14 -8
  11. package/components/builder/SortableBlock.tsx +4 -0
  12. package/components/builder/SortableRow.tsx +2 -0
  13. package/components/builder/asset-browser/useR2Operations.ts +5 -4
  14. package/components/builder/editors/AudioBlockEditor.tsx +10 -8
  15. package/components/builder/editors/BeforeAfterBlockEditor.tsx +10 -8
  16. package/components/builder/editors/ButtonBlockEditor.tsx +9 -7
  17. package/components/builder/editors/ImageBlockEditor.tsx +10 -8
  18. package/components/builder/editors/ImageGridBlockEditor.tsx +10 -8
  19. package/components/builder/editors/SpacerBlockEditor.tsx +4 -4
  20. package/components/builder/editors/TextBlockEditor.tsx +471 -468
  21. package/components/builder/editors/VideoBlockEditor.tsx +10 -8
  22. package/components/builder/live-preview/drag-utils.tsx +5 -3
  23. package/components/builder/settings-panel/AnimationTab.tsx +11 -8
  24. package/components/builder/settings-panel/BlockLayoutTab.tsx +514 -511
  25. package/components/builder/settings-panel/ColumnV2AnimationTab.tsx +2 -2
  26. package/components/builder/settings-panel/ColumnV2LayoutTab.tsx +11 -8
  27. package/components/builder/settings-panel/ColumnV2Settings.tsx +6 -5
  28. package/components/builder/settings-panel/CoverSectionLayoutTab.tsx +4 -3
  29. package/components/builder/settings-panel/CoverSectionSettings.tsx +14 -9
  30. package/components/builder/settings-panel/CustomSectionSettings.tsx +9 -7
  31. package/components/builder/settings-panel/PageSettings.tsx +39 -32
  32. package/components/builder/settings-panel/ParallaxGroupSettings.tsx +2 -2
  33. package/components/builder/settings-panel/ParallaxSlideSettings.tsx +2 -2
  34. package/components/builder/settings-panel/SectionV2AnimationTab.tsx +7 -5
  35. package/components/builder/settings-panel/SectionV2LayoutTab.tsx +13 -9
  36. package/components/builder/settings-panel/SectionV2Settings.tsx +10 -9
  37. package/components/builder/settings-panel/TRBLInputs.tsx +2 -2
  38. package/components/builder/settings-panel/useSettingsPanelSelection.ts +16 -13
  39. package/components/ui/ToastStack.tsx +142 -0
  40. package/lib/auth-token.ts +5 -1
  41. package/lib/bot-guard.ts +6 -0
  42. package/lib/builder/constants.ts +5 -10
  43. package/lib/toast/index.ts +56 -0
  44. package/lib/toast/store.ts +56 -0
  45. package/lib/version.ts +1 -1
  46. package/package.json +3 -1
@@ -52,33 +52,35 @@ function extractEmbedId(
52
52
  }
53
53
 
54
54
  export default function VideoBlockEditor({ block }: Props) {
55
- const store = useBuilderStore();
55
+ const updateBlock = useBuilderStore((s) => s.updateBlock);
56
+ const updateBlockDebounced = useBuilderStore((s) => s.updateBlockDebounced);
57
+ const _pushSnapshot = useBuilderStore((s) => s._pushSnapshot);
56
58
  const viewport = useActiveViewport();
57
59
 
58
- const snapshotOnFocus = () => store._pushSnapshot();
60
+ const snapshotOnFocus = () => _pushSnapshot();
59
61
 
60
62
  // Responsive-aware update for layout/appearance properties
61
63
  const updateResponsive = (property: string, value: unknown) => {
62
64
  if (viewport === "desktop") {
63
- store.updateBlock(block._key, { [property]: value } as Partial<ContentBlock>);
65
+ updateBlock(block._key, { [property]: value } as Partial<ContentBlock>);
64
66
  } else {
65
67
  const overrides = setResponsiveOverride(block as ContentBlock, viewport, property, value);
66
- store.updateBlock(block._key, overrides as Partial<ContentBlock>);
68
+ updateBlock(block._key, overrides as Partial<ContentBlock>);
67
69
  }
68
70
  };
69
71
 
70
72
  const resetOverride = (property: string) => {
71
73
  const overrides = setResponsiveOverride(block as ContentBlock, viewport, property, undefined);
72
- store.updateBlock(block._key, overrides as Partial<ContentBlock>);
74
+ updateBlock(block._key, overrides as Partial<ContentBlock>);
73
75
  };
74
76
 
75
77
  // Direct update (base block, not responsive)
76
78
  const update = (updates: Partial<VideoBlock>) => {
77
- store.updateBlock(block._key, updates as Partial<ContentBlock>);
79
+ updateBlock(block._key, updates as Partial<ContentBlock>);
78
80
  };
79
81
 
80
82
  const updateDebounced = (updates: Partial<VideoBlock>) => {
81
- store.updateBlockDebounced(block._key, updates as Partial<ContentBlock>);
83
+ updateBlockDebounced(block._key, updates as Partial<ContentBlock>);
82
84
  };
83
85
 
84
86
  // Effective values for the active viewport
@@ -244,7 +246,7 @@ export default function VideoBlockEditor({ block }: Props) {
244
246
  value={String(getEffectiveValue<string>(block as ContentBlock, viewport, "border_radius", block.border_radius || "")).replace(/px$/i, "")}
245
247
  onFocus={snapshotOnFocus}
246
248
  onChange={(e) => {
247
- store._pushSnapshot();
249
+ _pushSnapshot();
248
250
  updateResponsive("border_radius", e.target.value.replace(/[^0-9]/g, ""));
249
251
  }}
250
252
  className={INPUT_CLASS}
@@ -7,7 +7,7 @@
7
7
  * Session 162: Extracted from LiveProjectGridPreview.tsx (Phase B1).
8
8
  */
9
9
 
10
- import { BUILDER_BLUE } from "../../../lib/builder/constants";
10
+ import { BUILDER_BLOCK } from "../../../lib/builder/constants";
11
11
  import type { MasonryOutput } from "../../../lib/builder/masonry";
12
12
 
13
13
  // ─── Constants ───────────────────────────────────────────────────────
@@ -15,8 +15,10 @@ import type { MasonryOutput } from "../../../lib/builder/masonry";
15
15
  export const HOLD_DELAY = 150; // ms before card-body drag activates
16
16
  export const MOVE_THRESHOLD_SQ = 9; // 3px² — grabbed → dragging
17
17
  export const CANCEL_DURATION = 200; // ms — cancel fly-back animation
18
- export const ADMIN_BLUE = BUILDER_BLUE;
19
- export const DROP_BLUE = BUILDER_BLUE;
18
+ // Project-card DnD chrome inside `projectGridBlock` — semantic is block-level
19
+ // (card reorder within a block), so tracks BUILDER_BLOCK, not BUILDER_YELLOW.
20
+ export const ADMIN_BLUE = BUILDER_BLOCK;
21
+ export const DROP_BLUE = BUILDER_BLOCK;
20
22
 
21
23
  // ─── Types ───────────────────────────────────────────────────────────
22
24
 
@@ -35,13 +35,16 @@ interface AnimationTabProps {
35
35
  }
36
36
 
37
37
  export function AnimationTab({ selectedBlock }: AnimationTabProps) {
38
- const store = useBuilderStore();
38
+ const activeViewport = useBuilderStore((s) => s.activeViewport);
39
+ const updateBlock = useBuilderStore((s) => s.updateBlock);
40
+ const pageSettings = useBuilderStore((s) => s.pageSettings);
41
+ const updatePageSettings = useBuilderStore((s) => s.updatePageSettings);
39
42
 
40
43
  // Block level: type-specific enter picker + card entrance for projectGrid
41
44
  if (selectedBlock) {
42
45
  const isProjectGrid = selectedBlock.block._type === "projectGridBlock";
43
46
  const pgBlock = isProjectGrid ? (selectedBlock.block as ProjectGridBlock) : null;
44
- const bvp = store.activeViewport;
47
+ const bvp = activeViewport;
45
48
  const isBlockResponsive = bvp !== "desktop";
46
49
 
47
50
  const effectiveEnterAnim = getBlockAnimationValue(
@@ -72,7 +75,7 @@ export function AnimationTab({ selectedBlock }: AnimationTabProps) {
72
75
  <button
73
76
  onClick={() => {
74
77
  const updates = setBlockAnimationOverride(selectedBlock.block, bvp, "enter_animation", undefined);
75
- store.updateBlock(selectedBlock.block._key, updates);
78
+ updateBlock(selectedBlock.block._key, updates);
76
79
  }}
77
80
  className="text-[10px] text-neutral-400 hover:text-[var(--admin-error)] transition-colors"
78
81
  >
@@ -85,7 +88,7 @@ export function AnimationTab({ selectedBlock }: AnimationTabProps) {
85
88
  config={effectiveEnterAnim}
86
89
  onChange={(cfg) => {
87
90
  const updates = setBlockAnimationOverride(selectedBlock.block, bvp, "enter_animation", cfg);
88
- store.updateBlock(selectedBlock.block._key, updates);
91
+ updateBlock(selectedBlock.block._key, updates);
89
92
  }}
90
93
  />
91
94
  </div>
@@ -98,7 +101,7 @@ export function AnimationTab({ selectedBlock }: AnimationTabProps) {
98
101
  <button
99
102
  onClick={() => {
100
103
  const updates = setBlockAnimationOverride(selectedBlock.block, bvp, "hover_effect", undefined);
101
- store.updateBlock(selectedBlock.block._key, updates);
104
+ updateBlock(selectedBlock.block._key, updates);
102
105
  }}
103
106
  className="text-[10px] text-neutral-400 hover:text-[var(--admin-error)] transition-colors"
104
107
  >
@@ -111,7 +114,7 @@ export function AnimationTab({ selectedBlock }: AnimationTabProps) {
111
114
  config={effectiveHoverEffect ?? getBlockHoverEffect(selectedBlock.block)}
112
115
  onChange={(cfg) => {
113
116
  const updates = setBlockAnimationOverride(selectedBlock.block, bvp, "hover_effect", cfg);
114
- store.updateBlock(selectedBlock.block._key, updates);
117
+ updateBlock(selectedBlock.block._key, updates);
115
118
  }}
116
119
  />
117
120
  </div>
@@ -129,9 +132,9 @@ export function AnimationTab({ selectedBlock }: AnimationTabProps) {
129
132
  return (
130
133
  <EnterAnimationPicker
131
134
  mode={{ level: "page" }}
132
- config={store.pageSettings.enter_animation}
135
+ config={pageSettings.enter_animation}
133
136
  onChange={(cfg) => {
134
- store.updatePageSettings({ enter_animation: cfg });
137
+ updatePageSettings({ enter_animation: cfg });
135
138
  }}
136
139
  />
137
140
  );