@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 +67 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +67 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -28,6 +28,14 @@ interface AiBlockNode {
|
|
|
28
28
|
align?: 'left' | 'center' | 'right';
|
|
29
29
|
slots?: Record<string, unknown>;
|
|
30
30
|
children?: AiBlockNode[];
|
|
31
|
+
/** Stable id for ordered insertion. Omitted on trees saved before slots. */
|
|
32
|
+
ref?: string;
|
|
33
|
+
/** Fixed slot inside a split (`left`/`right`) or grid (`cell-N`). Omit to keep index order. */
|
|
34
|
+
slot?: string;
|
|
35
|
+
/** Unfilled fixed slots on a group. The published page draws none of these. */
|
|
36
|
+
emptySlots?: string[];
|
|
37
|
+
/** Stack wrapped around a slot that was filled a second time. */
|
|
38
|
+
promoted?: true;
|
|
31
39
|
/** Shape is per-block-type, defined by the backend's `BlockDef.itemFields` (accordion's
|
|
32
40
|
* question/answer, media-strip's assetId/alt/href/linkTarget, footer link-list/hours/social-row). */
|
|
33
41
|
items?: Array<Record<string, unknown>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -28,6 +28,14 @@ interface AiBlockNode {
|
|
|
28
28
|
align?: 'left' | 'center' | 'right';
|
|
29
29
|
slots?: Record<string, unknown>;
|
|
30
30
|
children?: AiBlockNode[];
|
|
31
|
+
/** Stable id for ordered insertion. Omitted on trees saved before slots. */
|
|
32
|
+
ref?: string;
|
|
33
|
+
/** Fixed slot inside a split (`left`/`right`) or grid (`cell-N`). Omit to keep index order. */
|
|
34
|
+
slot?: string;
|
|
35
|
+
/** Unfilled fixed slots on a group. The published page draws none of these. */
|
|
36
|
+
emptySlots?: string[];
|
|
37
|
+
/** Stack wrapped around a slot that was filled a second time. */
|
|
38
|
+
promoted?: true;
|
|
31
39
|
/** Shape is per-block-type, defined by the backend's `BlockDef.itemFields` (accordion's
|
|
32
40
|
* question/answer, media-strip's assetId/alt/href/linkTarget, footer link-list/hours/social-row). */
|
|
33
41
|
items?: Array<Record<string, unknown>>;
|
package/dist/index.js
CHANGED
|
@@ -6164,7 +6164,9 @@ function applyTreeToState(state, payload) {
|
|
|
6164
6164
|
...selfEdit ? priorEntry?.beforeSection ? { beforeSection: priorEntry.beforeSection } : {} : insertBefore && payload.targetSectionId ? { beforeSection: payload.targetSectionId } : {},
|
|
6165
6165
|
...selfEdit ? priorEntry?.replaces ? { replaces: priorEntry.replaces } : {} : payload.mode === "replace" && payload.targetSectionId ? { replaces: payload.targetSectionId } : {},
|
|
6166
6166
|
tree: payload.tree,
|
|
6167
|
-
media
|
|
6167
|
+
// A column insert rebuilds the media map from the live DOM keys. The photo
|
|
6168
|
+
// still points at the ref it was generated with. Keep that ref.
|
|
6169
|
+
media: { ...priorEntry?.media ?? {}, ...payload.media ?? {} },
|
|
6168
6170
|
...payload.brand && typeof payload.brand === "object" ? { brand: payload.brand } : {}
|
|
6169
6171
|
};
|
|
6170
6172
|
const others = state.sections.filter((existing) => existing.id !== entry.id);
|
|
@@ -9665,6 +9667,46 @@ function FooterSocialRowBlock({
|
|
|
9665
9667
|
}
|
|
9666
9668
|
);
|
|
9667
9669
|
}
|
|
9670
|
+
function EmptySlotPlaceholder({ name }) {
|
|
9671
|
+
return /* @__PURE__ */ jsx(
|
|
9672
|
+
"div",
|
|
9673
|
+
{
|
|
9674
|
+
"data-ai-slot": name,
|
|
9675
|
+
"data-ai-slot-empty": "",
|
|
9676
|
+
"aria-hidden": "true",
|
|
9677
|
+
style: {
|
|
9678
|
+
minHeight: 88,
|
|
9679
|
+
borderRadius: 12,
|
|
9680
|
+
border: "1px dashed #D6D3D1",
|
|
9681
|
+
display: "flex",
|
|
9682
|
+
alignItems: "center",
|
|
9683
|
+
justifyContent: "center",
|
|
9684
|
+
padding: 16,
|
|
9685
|
+
color: "#A8A29E",
|
|
9686
|
+
fontSize: 13,
|
|
9687
|
+
lineHeight: 1.4,
|
|
9688
|
+
textAlign: "center",
|
|
9689
|
+
pointerEvents: "none"
|
|
9690
|
+
},
|
|
9691
|
+
children: "Ask AI to add something here"
|
|
9692
|
+
}
|
|
9693
|
+
);
|
|
9694
|
+
}
|
|
9695
|
+
function splitSides(node) {
|
|
9696
|
+
const named = /* @__PURE__ */ new Map();
|
|
9697
|
+
const unnamed = [];
|
|
9698
|
+
(node.children ?? []).forEach((child, index) => {
|
|
9699
|
+
if (child.slot === "left" || child.slot === "right") {
|
|
9700
|
+
named.set(child.slot, { node: child, index });
|
|
9701
|
+
} else {
|
|
9702
|
+
unnamed.push({ node: child, index });
|
|
9703
|
+
}
|
|
9704
|
+
});
|
|
9705
|
+
return {
|
|
9706
|
+
left: named.get("left") ?? unnamed.shift() ?? null,
|
|
9707
|
+
right: named.get("right") ?? unnamed.shift() ?? null
|
|
9708
|
+
};
|
|
9709
|
+
}
|
|
9668
9710
|
function renderNode(node, ctx, path, ambientAlign) {
|
|
9669
9711
|
const slots = node.slots ?? {};
|
|
9670
9712
|
switch (node.type) {
|
|
@@ -9672,9 +9714,11 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9672
9714
|
return /* @__PURE__ */ jsx(TextBlock, { slots, ctx, path, align: node.align ?? ambientAlign });
|
|
9673
9715
|
// Layout container: arranges child blocks, contributes no content of its own. `grid` is a
|
|
9674
9716
|
// nested 12-column grid the children span (a collage is 3–5 media on it, bottom-aligned so
|
|
9675
|
-
// mixed aspects read as a composition); `split` is
|
|
9676
|
-
// is a column.
|
|
9677
|
-
//
|
|
9717
|
+
// mixed aspects read as a composition); `split` is left and right (index order when `slot`
|
|
9718
|
+
// is omitted); `stack` is a column. A missing split side is a canvas placeholder only when
|
|
9719
|
+
// `emptySlots` names it. A one-child split used to keep a row at span 12 (a testimonial
|
|
9720
|
+
// under a heading) sits centered at half the row width. Children render through this same
|
|
9721
|
+
// dispatcher, so edit markers, media resolution, and copy paths all work unchanged.
|
|
9678
9722
|
case "group": {
|
|
9679
9723
|
const layout = str(slots.layout);
|
|
9680
9724
|
const gap = slots.spacing === "tight" ? AI_TREE_TOKENS.spacing3 : slots.spacing === "airy" ? AI_TREE_TOKENS.spacing8 : AI_TREE_TOKENS.spacing6;
|
|
@@ -9772,24 +9816,38 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9772
9816
|
i
|
|
9773
9817
|
));
|
|
9774
9818
|
if (layout === "grid") {
|
|
9775
|
-
|
|
9819
|
+
const holes = ctx.keyFor ? node.emptySlots ?? [] : [];
|
|
9820
|
+
return /* @__PURE__ */ jsxs(
|
|
9776
9821
|
"div",
|
|
9777
9822
|
{
|
|
9778
9823
|
"data-ai-group": "grid",
|
|
9779
9824
|
style: { display: "grid", gridTemplateColumns: "repeat(12, 1fr)", gap, alignItems: "end" },
|
|
9780
|
-
children:
|
|
9825
|
+
children: [
|
|
9826
|
+
kids,
|
|
9827
|
+
holes.map((name) => /* @__PURE__ */ jsx("div", { style: { gridColumn: "span 6", minWidth: 0 }, children: /* @__PURE__ */ jsx(EmptySlotPlaceholder, { name }) }, name))
|
|
9828
|
+
]
|
|
9781
9829
|
}
|
|
9782
9830
|
);
|
|
9783
9831
|
}
|
|
9784
9832
|
if (layout === "split") {
|
|
9833
|
+
const { left, right } = splitSides(node);
|
|
9834
|
+
const open = new Set(ctx.keyFor ? node.emptySlots ?? [] : []);
|
|
9835
|
+
const side = (entry, name) => entry ? /* @__PURE__ */ jsx("div", { style: { minWidth: 0 }, children: renderNode(entry.node, ctx, `${path}.c${entry.index}`) }, name) : open.has(name) ? /* @__PURE__ */ jsx(EmptySlotPlaceholder, { name }, name) : null;
|
|
9836
|
+
if (!left && !open.has("left") || !right && !open.has("right")) {
|
|
9837
|
+
const only = left ?? right;
|
|
9838
|
+
return only ? /* @__PURE__ */ jsx("div", { "data-ai-group": "split", style: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsx("div", { style: { width: "50%", minWidth: 0 }, children: renderNode(only.node, ctx, `${path}.c${only.index}`) }) }) : null;
|
|
9839
|
+
}
|
|
9785
9840
|
const ratio = str(slots.ratio);
|
|
9786
9841
|
const cols = ratio === "3:5" ? "3fr 5fr" : ratio === "5:3" ? "5fr 3fr" : "1fr 1fr";
|
|
9787
|
-
return /* @__PURE__ */
|
|
9842
|
+
return /* @__PURE__ */ jsxs(
|
|
9788
9843
|
"div",
|
|
9789
9844
|
{
|
|
9790
9845
|
"data-ai-group": "split",
|
|
9791
9846
|
style: { display: "grid", gridTemplateColumns: cols, gap, alignItems: "center" },
|
|
9792
|
-
children:
|
|
9847
|
+
children: [
|
|
9848
|
+
side(left, "left"),
|
|
9849
|
+
side(right, "right")
|
|
9850
|
+
]
|
|
9793
9851
|
}
|
|
9794
9852
|
);
|
|
9795
9853
|
}
|
|
@@ -31418,7 +31476,7 @@ function OhhwellsBridge() {
|
|
|
31418
31476
|
postToParent2({
|
|
31419
31477
|
type: "ow:ready",
|
|
31420
31478
|
version: "1",
|
|
31421
|
-
bridgeVersion: "0.1.
|
|
31479
|
+
bridgeVersion: "0.1.145",
|
|
31422
31480
|
path: pathname,
|
|
31423
31481
|
nodes: collectEditableNodes(editContentRef.current),
|
|
31424
31482
|
sections
|