@ohhwells/bridge 0.1.145 → 0.1.146

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);
@@ -9759,6 +9761,46 @@ function FooterSocialRowBlock({
9759
9761
  }
9760
9762
  );
9761
9763
  }
9764
+ function EmptySlotPlaceholder({ name }) {
9765
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
9766
+ "div",
9767
+ {
9768
+ "data-ai-slot": name,
9769
+ "data-ai-slot-empty": "",
9770
+ "aria-hidden": "true",
9771
+ style: {
9772
+ minHeight: 88,
9773
+ borderRadius: 12,
9774
+ border: "1px dashed #D6D3D1",
9775
+ display: "flex",
9776
+ alignItems: "center",
9777
+ justifyContent: "center",
9778
+ padding: 16,
9779
+ color: "#A8A29E",
9780
+ fontSize: 13,
9781
+ lineHeight: 1.4,
9782
+ textAlign: "center",
9783
+ pointerEvents: "none"
9784
+ },
9785
+ children: "Ask AI to add something here"
9786
+ }
9787
+ );
9788
+ }
9789
+ function splitSides(node) {
9790
+ const named = /* @__PURE__ */ new Map();
9791
+ const unnamed = [];
9792
+ (node.children ?? []).forEach((child, index) => {
9793
+ if (child.slot === "left" || child.slot === "right") {
9794
+ named.set(child.slot, { node: child, index });
9795
+ } else {
9796
+ unnamed.push({ node: child, index });
9797
+ }
9798
+ });
9799
+ return {
9800
+ left: named.get("left") ?? unnamed.shift() ?? null,
9801
+ right: named.get("right") ?? unnamed.shift() ?? null
9802
+ };
9803
+ }
9762
9804
  function renderNode(node, ctx, path, ambientAlign) {
9763
9805
  const slots = node.slots ?? {};
9764
9806
  switch (node.type) {
@@ -9766,9 +9808,11 @@ function renderNode(node, ctx, path, ambientAlign) {
9766
9808
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextBlock, { slots, ctx, path, align: node.align ?? ambientAlign });
9767
9809
  // Layout container: arranges child blocks, contributes no content of its own. `grid` is a
9768
9810
  // nested 12-column grid the children span (a collage is 3–5 media on it, bottom-aligned so
9769
- // mixed aspects read as a composition); `split` is exactly two children at a ratio; `stack`
9770
- // is a column. Children render through this same dispatcher, so edit markers, media
9771
- // resolution, and copy paths all work unchanged inside a group.
9811
+ // mixed aspects read as a composition); `split` is left and right (index order when `slot`
9812
+ // is omitted); `stack` is a column. A missing split side is a canvas placeholder only when
9813
+ // `emptySlots` names it. A one-child split used to keep a row at span 12 (a testimonial
9814
+ // under a heading) sits centered at half the row width. Children render through this same
9815
+ // dispatcher, so edit markers, media resolution, and copy paths all work unchanged.
9772
9816
  case "group": {
9773
9817
  const layout = str(slots.layout);
9774
9818
  const gap = slots.spacing === "tight" ? AI_TREE_TOKENS.spacing3 : slots.spacing === "airy" ? AI_TREE_TOKENS.spacing8 : AI_TREE_TOKENS.spacing6;
@@ -9866,24 +9910,38 @@ function renderNode(node, ctx, path, ambientAlign) {
9866
9910
  i
9867
9911
  ));
9868
9912
  if (layout === "grid") {
9869
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
9913
+ const holes = ctx.keyFor ? node.emptySlots ?? [] : [];
9914
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
9870
9915
  "div",
9871
9916
  {
9872
9917
  "data-ai-group": "grid",
9873
9918
  style: { display: "grid", gridTemplateColumns: "repeat(12, 1fr)", gap, alignItems: "end" },
9874
- children: kids
9919
+ children: [
9920
+ kids,
9921
+ 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))
9922
+ ]
9875
9923
  }
9876
9924
  );
9877
9925
  }
9878
9926
  if (layout === "split") {
9927
+ const { left, right } = splitSides(node);
9928
+ const open = new Set(ctx.keyFor ? node.emptySlots ?? [] : []);
9929
+ 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;
9930
+ if (!left && !open.has("left") || !right && !open.has("right")) {
9931
+ const only = left ?? right;
9932
+ 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;
9933
+ }
9879
9934
  const ratio = str(slots.ratio);
9880
9935
  const cols = ratio === "3:5" ? "3fr 5fr" : ratio === "5:3" ? "5fr 3fr" : "1fr 1fr";
9881
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
9936
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
9882
9937
  "div",
9883
9938
  {
9884
9939
  "data-ai-group": "split",
9885
9940
  style: { display: "grid", gridTemplateColumns: cols, gap, alignItems: "center" },
9886
- children: kids
9941
+ children: [
9942
+ side(left, "left"),
9943
+ side(right, "right")
9944
+ ]
9887
9945
  }
9888
9946
  );
9889
9947
  }
@@ -31506,7 +31564,7 @@ function OhhwellsBridge() {
31506
31564
  postToParent2({
31507
31565
  type: "ow:ready",
31508
31566
  version: "1",
31509
- bridgeVersion: "0.1.144",
31567
+ bridgeVersion: "0.1.145",
31510
31568
  path: pathname,
31511
31569
  nodes: collectEditableNodes(editContentRef.current),
31512
31570
  sections