@morphika/andami 0.2.2 → 0.2.3

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.
@@ -226,8 +226,14 @@ export default function ProjectGridBlockRenderer({
226
226
  // animations at once (with stagger). No per-card observer needed.
227
227
  const [gridVisible, setGridVisible] = useState(false);
228
228
 
229
+ // Track whether we have projects loaded — needed as a dep so the
230
+ // IntersectionObserver effect re-runs after the async fetch populates
231
+ // resolvedProjects (on the first render the grid div isn't mounted yet
232
+ // because the component returns null when resolvedProjects is empty).
233
+ const hasProjects = resolvedProjects.length > 0;
234
+
229
235
  useEffect(() => {
230
- if (!entranceEnabled || gridVisible) return;
236
+ if (!entranceEnabled || gridVisible || !hasProjects) return;
231
237
  const el = containerRef.current;
232
238
  if (!el) return;
233
239
 
@@ -249,7 +255,7 @@ export default function ProjectGridBlockRenderer({
249
255
 
250
256
  observer.observe(el);
251
257
  return () => observer.disconnect();
252
- }, [entranceEnabled, gridVisible]);
258
+ }, [entranceEnabled, gridVisible, hasProjects]);
253
259
 
254
260
  // ─── Compute stagger indices sorted by vertical position ───
255
261
  // Cards at similar y positions (within half of gapV) share the same rank.
@@ -330,6 +336,10 @@ export default function ProjectGridBlockRenderer({
330
336
  top: item.y,
331
337
  width: item.width,
332
338
  height: item.height,
339
+ // Clip the card when hover scale-up overflows the cell bounds
340
+ // so border-radius is preserved visually.
341
+ overflow: "hidden",
342
+ borderRadius: borderRadius > 0 ? borderRadius : undefined,
333
343
  }}
334
344
  >
335
345
  {entranceEnabled && entranceAnimConfig ? (
@@ -10,6 +10,7 @@ import { useBuilderStore } from "../../lib/builder/store";
10
10
  import { makeBlockId, makeColumnDroppableId } from "./DndWrapper";
11
11
  import type { SectionColumn, ContentBlock, PageSectionV2 } from "../../lib/sanity/types";
12
12
  import { getColumnVerticalAlign } from "../../lib/builder/layout-styles";
13
+ import { isSectionBlockType } from "../../lib/builder/types";
13
14
  import { BUILDER_BLUE } from "../../lib/builder/constants";
14
15
 
15
16
  // ============================================
@@ -174,10 +175,26 @@ export default function SectionV2Column({
174
175
  );
175
176
 
176
177
  // ---- Stable callbacks ----
178
+
179
+ // When the column contains a single section-level block (e.g. projectGridBlock),
180
+ // that block fills the entire column visually. Clicking anywhere in the column
181
+ // should select the block — not the column — because users expect to reach the
182
+ // block's settings panel (Settings / Layout / Animation tabs).
183
+ const selectBlock = useBuilderStore((s) => s.selectBlock);
184
+ const singleSectionBlock = (() => {
185
+ const blocks = column.blocks || [];
186
+ if (blocks.length === 1 && isSectionBlockType(blocks[0]._type)) return blocks[0];
187
+ return null;
188
+ })();
189
+
177
190
  const handleClick = useCallback((e: React.MouseEvent) => {
178
191
  e.stopPropagation();
179
- onSelect();
180
- }, [onSelect]);
192
+ if (singleSectionBlock) {
193
+ selectBlock(singleSectionBlock._key);
194
+ } else {
195
+ onSelect();
196
+ }
197
+ }, [onSelect, singleSectionBlock, selectBlock]);
181
198
 
182
199
  const handleMouseEnter = useCallback(() => setIsHovered(true), []);
183
200
  const handleMouseLeave = useCallback(() => setIsHovered(false), []);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@morphika/andami",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
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",