@ohhwells/bridge 0.1.139-next.389 → 0.1.139-next.393

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/dist/index.cjs CHANGED
@@ -6258,7 +6258,9 @@ function applyTreeToState(state, payload) {
6258
6258
  ...selfEdit ? priorEntry?.beforeSection ? { beforeSection: priorEntry.beforeSection } : {} : insertBefore && payload.targetSectionId ? { beforeSection: payload.targetSectionId } : {},
6259
6259
  ...selfEdit ? priorEntry?.replaces ? { replaces: priorEntry.replaces } : {} : payload.mode === "replace" && payload.targetSectionId ? { replaces: payload.targetSectionId } : {},
6260
6260
  tree: payload.tree,
6261
- media: payload.media ?? {},
6261
+ // A column insert rebuilds the media map from the live DOM keys. The photo
6262
+ // still points at the ref it was generated with. Keep that ref.
6263
+ media: { ...priorEntry?.media ?? {}, ...payload.media ?? {} },
6262
6264
  ...payload.brand && typeof payload.brand === "object" ? { brand: payload.brand } : {}
6263
6265
  };
6264
6266
  const others = state.sections.filter((existing) => existing.id !== entry.id);
@@ -9801,6 +9803,46 @@ function FooterSocialRowBlock({
9801
9803
  }
9802
9804
  );
9803
9805
  }
9806
+ function EmptySlotPlaceholder({ name }) {
9807
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
9808
+ "div",
9809
+ {
9810
+ "data-ai-slot": name,
9811
+ "data-ai-slot-empty": "",
9812
+ "aria-hidden": "true",
9813
+ style: {
9814
+ minHeight: 88,
9815
+ borderRadius: 12,
9816
+ border: "1px dashed #D6D3D1",
9817
+ display: "flex",
9818
+ alignItems: "center",
9819
+ justifyContent: "center",
9820
+ padding: 16,
9821
+ color: "#A8A29E",
9822
+ fontSize: 13,
9823
+ lineHeight: 1.4,
9824
+ textAlign: "center",
9825
+ pointerEvents: "none"
9826
+ },
9827
+ children: "Ask AI to add something here"
9828
+ }
9829
+ );
9830
+ }
9831
+ function splitSides(node) {
9832
+ const named = /* @__PURE__ */ new Map();
9833
+ const unnamed = [];
9834
+ (node.children ?? []).forEach((child, index) => {
9835
+ if (child.slot === "left" || child.slot === "right") {
9836
+ named.set(child.slot, { node: child, index });
9837
+ } else {
9838
+ unnamed.push({ node: child, index });
9839
+ }
9840
+ });
9841
+ return {
9842
+ left: named.get("left") ?? unnamed.shift() ?? null,
9843
+ right: named.get("right") ?? unnamed.shift() ?? null
9844
+ };
9845
+ }
9804
9846
  function renderNode(node, ctx, path, ambientAlign) {
9805
9847
  const slots = node.slots ?? {};
9806
9848
  switch (node.type) {
@@ -9808,9 +9850,11 @@ function renderNode(node, ctx, path, ambientAlign) {
9808
9850
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextBlock, { slots, ctx, path, align: node.align ?? ambientAlign });
9809
9851
  // Layout container: arranges child blocks, contributes no content of its own. `grid` is a
9810
9852
  // nested 12-column grid the children span (a collage is 3–5 media on it, bottom-aligned so
9811
- // mixed aspects read as a composition); `split` is exactly two children at a ratio; `stack`
9812
- // is a column. Children render through this same dispatcher, so edit markers, media
9813
- // resolution, and copy paths all work unchanged inside a group.
9853
+ // mixed aspects read as a composition); `split` is left and right (index order when `slot`
9854
+ // is omitted); `stack` is a column. A missing split side is a canvas placeholder only when
9855
+ // `emptySlots` names it. A one-child split used to keep a row at span 12 (a testimonial
9856
+ // under a heading) sits centered at half the row width. Children render through this same
9857
+ // dispatcher, so edit markers, media resolution, and copy paths all work unchanged.
9814
9858
  case "group": {
9815
9859
  const layout = str(slots.layout);
9816
9860
  const gap = slots.spacing === "tight" ? AI_TREE_TOKENS.spacing3 : slots.spacing === "airy" ? AI_TREE_TOKENS.spacing8 : AI_TREE_TOKENS.spacing6;
@@ -9908,24 +9952,38 @@ function renderNode(node, ctx, path, ambientAlign) {
9908
9952
  i
9909
9953
  ));
9910
9954
  if (layout === "grid") {
9911
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
9955
+ const holes = ctx.keyFor ? node.emptySlots ?? [] : [];
9956
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
9912
9957
  "div",
9913
9958
  {
9914
9959
  "data-ai-group": "grid",
9915
9960
  style: { display: "grid", gridTemplateColumns: "repeat(12, 1fr)", gap, alignItems: "end" },
9916
- children: kids
9961
+ children: [
9962
+ kids,
9963
+ holes.map((name) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { gridColumn: "span 6", minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptySlotPlaceholder, { name }) }, name))
9964
+ ]
9917
9965
  }
9918
9966
  );
9919
9967
  }
9920
9968
  if (layout === "split") {
9969
+ const { left, right } = splitSides(node);
9970
+ const open = new Set(ctx.keyFor ? node.emptySlots ?? [] : []);
9971
+ const side = (entry, name) => entry ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { minWidth: 0 }, children: renderNode(entry.node, ctx, `${path}.c${entry.index}`) }, name) : open.has(name) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptySlotPlaceholder, { name }, name) : null;
9972
+ if (!left && !open.has("left") || !right && !open.has("right")) {
9973
+ const only = left ?? right;
9974
+ return only ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "data-ai-group": "split", style: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { width: "50%", minWidth: 0 }, children: renderNode(only.node, ctx, `${path}.c${only.index}`) }) }) : null;
9975
+ }
9921
9976
  const ratio = str(slots.ratio);
9922
9977
  const cols = ratio === "3:5" ? "3fr 5fr" : ratio === "5:3" ? "5fr 3fr" : "1fr 1fr";
9923
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
9978
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
9924
9979
  "div",
9925
9980
  {
9926
9981
  "data-ai-group": "split",
9927
9982
  style: { display: "grid", gridTemplateColumns: cols, gap, alignItems: "center" },
9928
- children: kids
9983
+ children: [
9984
+ side(left, "left"),
9985
+ side(right, "right")
9986
+ ]
9929
9987
  }
9930
9988
  );
9931
9989
  }