@ohhwells/bridge 0.1.117-next.323 → 0.1.117-next.325
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 +159 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +159 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -572,6 +572,40 @@ function applyBrandToDom(kit) {
|
|
|
572
572
|
}
|
|
573
573
|
}
|
|
574
574
|
|
|
575
|
+
// src/lib/custom-code.ts
|
|
576
|
+
var ALLOWED_HEAD_TAGS = /* @__PURE__ */ new Set(["style", "meta", "link", "script", "noscript", "base"]);
|
|
577
|
+
var CUSTOM_CODE_AFTER_HEAD_KEY = "__ohw_custom_code_after_head";
|
|
578
|
+
var CUSTOM_CODE_BEFORE_HEAD_KEY = "__ohw_custom_code_before_head";
|
|
579
|
+
function clearExisting(slot) {
|
|
580
|
+
document.querySelectorAll(`[data-ohw-custom-code="${slot}"]`).forEach((el) => el.remove());
|
|
581
|
+
}
|
|
582
|
+
function buildNodes(raw, slot) {
|
|
583
|
+
if (!raw || !raw.trim()) return [];
|
|
584
|
+
const parsed = new DOMParser().parseFromString(raw, "text/html");
|
|
585
|
+
const source = [...parsed.head.childNodes, ...parsed.body.childNodes];
|
|
586
|
+
const nodes = [];
|
|
587
|
+
for (const node of source) {
|
|
588
|
+
if (node.nodeType !== Node.ELEMENT_NODE) continue;
|
|
589
|
+
const el = node;
|
|
590
|
+
const tag = el.tagName.toLowerCase();
|
|
591
|
+
if (!ALLOWED_HEAD_TAGS.has(tag)) continue;
|
|
592
|
+
const built = document.createElement(tag);
|
|
593
|
+
for (const attr of Array.from(el.attributes)) built.setAttribute(attr.name, attr.value);
|
|
594
|
+
if (tag === "script" || tag === "style" || tag === "noscript") built.textContent = el.textContent;
|
|
595
|
+
built.dataset.ohwCustomCode = slot;
|
|
596
|
+
nodes.push(built);
|
|
597
|
+
}
|
|
598
|
+
return nodes;
|
|
599
|
+
}
|
|
600
|
+
function applyCustomCodeToHead(content) {
|
|
601
|
+
clearExisting("after");
|
|
602
|
+
clearExisting("before");
|
|
603
|
+
const afterNodes = buildNodes(content[CUSTOM_CODE_AFTER_HEAD_KEY], "after");
|
|
604
|
+
if (afterNodes.length > 0) document.head.prepend(...afterNodes);
|
|
605
|
+
const beforeNodes = buildNodes(content[CUSTOM_CODE_BEFORE_HEAD_KEY], "before");
|
|
606
|
+
if (beforeNodes.length > 0) document.head.append(...beforeNodes);
|
|
607
|
+
}
|
|
608
|
+
|
|
575
609
|
// src/lib/section-styles.ts
|
|
576
610
|
var STYLE_STORE_KEY = "__ohw_styles";
|
|
577
611
|
var STYLE_SHEET_ID = "ohw-section-styles";
|
|
@@ -10155,6 +10189,14 @@ function setMediaStripItemAsset(tree, index, assetId) {
|
|
|
10155
10189
|
return true;
|
|
10156
10190
|
});
|
|
10157
10191
|
}
|
|
10192
|
+
function setMediaStripItemAlt(tree, index, alt) {
|
|
10193
|
+
return withMediaStrip(tree, (block) => {
|
|
10194
|
+
const items = block.items;
|
|
10195
|
+
if (index < 0 || index >= items.length) return false;
|
|
10196
|
+
items[index] = { ...items[index], alt };
|
|
10197
|
+
return true;
|
|
10198
|
+
});
|
|
10199
|
+
}
|
|
10158
10200
|
|
|
10159
10201
|
// src/ui/ai-section/AiMediaStripOverlay.tsx
|
|
10160
10202
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
@@ -10273,6 +10315,74 @@ function Pill({
|
|
|
10273
10315
|
}
|
|
10274
10316
|
);
|
|
10275
10317
|
}
|
|
10318
|
+
function AltInput({ value, onCommit }) {
|
|
10319
|
+
const [draft, setDraft] = (0, import_react9.useState)(value);
|
|
10320
|
+
(0, import_react9.useEffect)(() => setDraft(value), [value]);
|
|
10321
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
10322
|
+
"div",
|
|
10323
|
+
{
|
|
10324
|
+
style: {
|
|
10325
|
+
display: "flex",
|
|
10326
|
+
alignItems: "center",
|
|
10327
|
+
gap: 6,
|
|
10328
|
+
height: 28,
|
|
10329
|
+
padding: "0 12px",
|
|
10330
|
+
borderRadius: 999,
|
|
10331
|
+
background: "#ffffff",
|
|
10332
|
+
width: "100%",
|
|
10333
|
+
maxWidth: 260,
|
|
10334
|
+
boxSizing: "border-box"
|
|
10335
|
+
},
|
|
10336
|
+
children: [
|
|
10337
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
10338
|
+
"span",
|
|
10339
|
+
{
|
|
10340
|
+
style: {
|
|
10341
|
+
flex: "0 0 auto",
|
|
10342
|
+
color: OHW_BLUE_DARK,
|
|
10343
|
+
fontSize: 10,
|
|
10344
|
+
fontWeight: 700,
|
|
10345
|
+
textTransform: "uppercase",
|
|
10346
|
+
letterSpacing: 0.4
|
|
10347
|
+
},
|
|
10348
|
+
children: "Alt"
|
|
10349
|
+
}
|
|
10350
|
+
),
|
|
10351
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
10352
|
+
"input",
|
|
10353
|
+
{
|
|
10354
|
+
type: "text",
|
|
10355
|
+
value: draft,
|
|
10356
|
+
onChange: (e) => setDraft(e.target.value),
|
|
10357
|
+
onBlur: () => {
|
|
10358
|
+
if (draft !== value) onCommit(draft);
|
|
10359
|
+
},
|
|
10360
|
+
onKeyDown: (e) => {
|
|
10361
|
+
if (e.key === "Enter") e.currentTarget.blur();
|
|
10362
|
+
if (e.key === "Escape") {
|
|
10363
|
+
setDraft(value);
|
|
10364
|
+
e.currentTarget.blur();
|
|
10365
|
+
}
|
|
10366
|
+
},
|
|
10367
|
+
placeholder: "Describe this image",
|
|
10368
|
+
"aria-label": "Image alt text",
|
|
10369
|
+
style: {
|
|
10370
|
+
flex: 1,
|
|
10371
|
+
minWidth: 0,
|
|
10372
|
+
border: "none",
|
|
10373
|
+
outline: "none",
|
|
10374
|
+
background: "transparent",
|
|
10375
|
+
fontSize: 12,
|
|
10376
|
+
lineHeight: "16px",
|
|
10377
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
10378
|
+
color: "#1f2937"
|
|
10379
|
+
}
|
|
10380
|
+
}
|
|
10381
|
+
)
|
|
10382
|
+
]
|
|
10383
|
+
}
|
|
10384
|
+
);
|
|
10385
|
+
}
|
|
10276
10386
|
var VARIANTS = [
|
|
10277
10387
|
{ value: "logos", label: "Logos" },
|
|
10278
10388
|
{ value: "reel", label: "Reel" }
|
|
@@ -10302,6 +10412,7 @@ function MediaStripToolbar({
|
|
|
10302
10412
|
onSetHover,
|
|
10303
10413
|
onSetTreatment,
|
|
10304
10414
|
onResize,
|
|
10415
|
+
onSetAlt,
|
|
10305
10416
|
onAddItem,
|
|
10306
10417
|
onRemoveItem,
|
|
10307
10418
|
onChangeImage,
|
|
@@ -10310,13 +10421,24 @@ function MediaStripToolbar({
|
|
|
10310
10421
|
}) {
|
|
10311
10422
|
const items = mediaStripItems(entry.tree);
|
|
10312
10423
|
const itemCount = items.length;
|
|
10424
|
+
const currentAlt = items[index]?.alt ?? "";
|
|
10313
10425
|
const slots = findMediaStripSlots(entry.tree);
|
|
10314
10426
|
const variant = slots?.variant === "reel" ? "reel" : "logos";
|
|
10315
10427
|
const align = slots?.align === "left" || slots?.align === "right" ? slots.align : "center";
|
|
10316
10428
|
const hover = slots?.hover === "none" || slots?.hover === "lift" || slots?.hover === "zoom" || slots?.hover === "fade" ? slots.hover : "none";
|
|
10317
10429
|
const treatment = slots?.treatment === "color" || slots?.treatment === "grayscale" ? slots.treatment : variant === "logos" ? "grayscale" : "color";
|
|
10318
10430
|
const sizeValue = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
10319
|
-
const
|
|
10431
|
+
const isMobile = window.innerWidth <= 480;
|
|
10432
|
+
const rowStyle = isMobile ? {
|
|
10433
|
+
display: "flex",
|
|
10434
|
+
gap: 6,
|
|
10435
|
+
flexWrap: "nowrap",
|
|
10436
|
+
justifyContent: "center",
|
|
10437
|
+
overflowX: "auto",
|
|
10438
|
+
WebkitOverflowScrolling: "touch",
|
|
10439
|
+
width: "100%",
|
|
10440
|
+
scrollbarWidth: "none"
|
|
10441
|
+
} : { display: "flex", gap: 6, flexWrap: "nowrap", justifyContent: "center" };
|
|
10320
10442
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
10321
10443
|
"div",
|
|
10322
10444
|
{
|
|
@@ -10334,14 +10456,14 @@ function MediaStripToolbar({
|
|
|
10334
10456
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
10335
10457
|
pointerEvents: pending ? "none" : "auto",
|
|
10336
10458
|
opacity: pending ? 0.6 : 1,
|
|
10337
|
-
maxWidth:
|
|
10459
|
+
maxWidth: isMobile ? "calc(100vw - 24px)" : "none"
|
|
10338
10460
|
},
|
|
10339
10461
|
children: [
|
|
10340
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style:
|
|
10462
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: rowStyle, children: [
|
|
10341
10463
|
VARIANTS.map((v) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: v.label, active: variant === v.value, onClick: () => onSetVariant(v.value) }, v.value)),
|
|
10342
10464
|
ALIGNS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: a.label, active: align === a.value, onClick: () => onSetAlign(a.value) }, a.value))
|
|
10343
10465
|
] }),
|
|
10344
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style:
|
|
10466
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: rowStyle, children: [
|
|
10345
10467
|
HOVERS.map((h) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: h.label, active: hover === h.value, onClick: () => onSetHover(h.value) }, h.value)),
|
|
10346
10468
|
TREATMENTS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: t.label, active: treatment === t.value, onClick: () => onSetTreatment(t.value) }, t.value))
|
|
10347
10469
|
] }),
|
|
@@ -10353,10 +10475,13 @@ function MediaStripToolbar({
|
|
|
10353
10475
|
] }),
|
|
10354
10476
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "+", onClick: () => onResize(8) })
|
|
10355
10477
|
] }),
|
|
10356
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.
|
|
10478
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { display: "flex", justifyContent: "center", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(AltInput, { value: currentAlt, onCommit: onSetAlt }) }),
|
|
10479
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: rowStyle, children: [
|
|
10357
10480
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "Change Image", onClick: onChangeImage }),
|
|
10358
10481
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "+ Item", onClick: onAddItem }),
|
|
10359
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "\u2212 Item", onClick: onRemoveItem, disabled: itemCount <= 1 })
|
|
10482
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "\u2212 Item", onClick: onRemoveItem, disabled: itemCount <= 1 })
|
|
10483
|
+
] }),
|
|
10484
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: rowStyle, children: [
|
|
10360
10485
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "\u2190 Move", onClick: onMoveLeft, disabled: index <= 0 }),
|
|
10361
10486
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Pill, { label: "\u2192 Move", onClick: onMoveRight, disabled: index >= itemCount - 1 })
|
|
10362
10487
|
] }),
|
|
@@ -10377,7 +10502,8 @@ function findMediaStripSlots(tree) {
|
|
|
10377
10502
|
function AiMediaStripOverlay({
|
|
10378
10503
|
postToParent: postToParent2,
|
|
10379
10504
|
aiSectionsRef,
|
|
10380
|
-
applyTreeLocalRef
|
|
10505
|
+
applyTreeLocalRef,
|
|
10506
|
+
clearInteractionChromeRef
|
|
10381
10507
|
}) {
|
|
10382
10508
|
const [hover, setHover] = (0, import_react9.useState)(null);
|
|
10383
10509
|
const [active, setActive] = (0, import_react9.useState)(null);
|
|
@@ -10494,7 +10620,10 @@ function AiMediaStripOverlay({
|
|
|
10494
10620
|
{
|
|
10495
10621
|
type: "button",
|
|
10496
10622
|
"data-ohw-toolbar": "",
|
|
10497
|
-
onClick: () =>
|
|
10623
|
+
onClick: () => {
|
|
10624
|
+
clearInteractionChromeRef.current();
|
|
10625
|
+
setActive(hover);
|
|
10626
|
+
},
|
|
10498
10627
|
"aria-label": "Configure media item",
|
|
10499
10628
|
style: {
|
|
10500
10629
|
position: "fixed",
|
|
@@ -10539,6 +10668,9 @@ function AiMediaStripOverlay({
|
|
|
10539
10668
|
const current = variant === "logos" ? typeof slots?.logoMaxHeight === "number" ? slots.logoMaxHeight : 48 : typeof slots?.cardWidth === "number" ? slots.cardWidth : 240;
|
|
10540
10669
|
void runMutation(active.sectionId, (tree) => setMediaStripSizing(tree, current + delta));
|
|
10541
10670
|
},
|
|
10671
|
+
onSetAlt: (alt) => {
|
|
10672
|
+
void runMutation(active.sectionId, (tree) => setMediaStripItemAlt(tree, active.index, alt));
|
|
10673
|
+
},
|
|
10542
10674
|
onAddItem: () => {
|
|
10543
10675
|
void requestAssetPick(postToParent2).then((picked) => {
|
|
10544
10676
|
if (!picked) return;
|
|
@@ -20547,6 +20679,8 @@ function OhhwellsBridge() {
|
|
|
20547
20679
|
const addNavAfterAnchorRef = (0, import_react18.useRef)(null);
|
|
20548
20680
|
const editContentRef = (0, import_react18.useRef)({});
|
|
20549
20681
|
const aiSectionsRef = (0, import_react18.useRef)("");
|
|
20682
|
+
const clearInteractionChromeRef = (0, import_react18.useRef)(() => {
|
|
20683
|
+
});
|
|
20550
20684
|
const brandKitRef = (0, import_react18.useRef)("");
|
|
20551
20685
|
const stylesRef = (0, import_react18.useRef)("");
|
|
20552
20686
|
const appliedDrawerRef = (0, import_react18.useRef)(null);
|
|
@@ -22106,6 +22240,7 @@ function OhhwellsBridge() {
|
|
|
22106
22240
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
22107
22241
|
}
|
|
22108
22242
|
applyBrandChrome(content);
|
|
22243
|
+
applyCustomCodeToHead(content);
|
|
22109
22244
|
initSectionInstancesFromContent(content, window.location.pathname);
|
|
22110
22245
|
for (const [key, val] of Object.entries(content)) {
|
|
22111
22246
|
if (key === "__ohw_sections") continue;
|
|
@@ -22115,6 +22250,7 @@ function OhhwellsBridge() {
|
|
|
22115
22250
|
if (key === BRAND_KIT_KEY) continue;
|
|
22116
22251
|
if (key === STYLE_STORE_KEY) continue;
|
|
22117
22252
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
22253
|
+
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
22118
22254
|
if (applyVideoSettingNode(key, val)) continue;
|
|
22119
22255
|
if (applyCarouselNode(key, val)) continue;
|
|
22120
22256
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -24526,6 +24662,7 @@ function OhhwellsBridge() {
|
|
|
24526
24662
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
24527
24663
|
}
|
|
24528
24664
|
applyBrandChrome(content);
|
|
24665
|
+
applyCustomCodeToHead(content);
|
|
24529
24666
|
initSectionInstancesFromContent(content, window.location.pathname);
|
|
24530
24667
|
let sectionsJson = null;
|
|
24531
24668
|
for (const [key, val] of Object.entries(content)) {
|
|
@@ -24539,6 +24676,7 @@ function OhhwellsBridge() {
|
|
|
24539
24676
|
if (key === BRAND_KIT_KEY) continue;
|
|
24540
24677
|
if (key === STYLE_STORE_KEY) continue;
|
|
24541
24678
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
24679
|
+
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
24542
24680
|
if (applyVideoSettingNode(key, val)) continue;
|
|
24543
24681
|
if (applyCarouselNode(key, val)) continue;
|
|
24544
24682
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -24660,6 +24798,7 @@ function OhhwellsBridge() {
|
|
|
24660
24798
|
deselectRef.current();
|
|
24661
24799
|
clearMediaSelectionRef.current();
|
|
24662
24800
|
};
|
|
24801
|
+
clearInteractionChromeRef.current = clearInteractionChrome;
|
|
24663
24802
|
const applyTreeToLocalState = (payload) => {
|
|
24664
24803
|
clearInteractionChrome();
|
|
24665
24804
|
const previous = aiSectionsRef.current;
|
|
@@ -25255,6 +25394,16 @@ function OhhwellsBridge() {
|
|
|
25255
25394
|
if (brandKitRef.current) {
|
|
25256
25395
|
nodes.push({ key: BRAND_KIT_KEY, type: "brand", text: brandKitRef.current });
|
|
25257
25396
|
}
|
|
25397
|
+
nodes.push({
|
|
25398
|
+
key: CUSTOM_CODE_BEFORE_HEAD_KEY,
|
|
25399
|
+
type: "text",
|
|
25400
|
+
text: editContentRef.current[CUSTOM_CODE_BEFORE_HEAD_KEY] ?? ""
|
|
25401
|
+
});
|
|
25402
|
+
nodes.push({
|
|
25403
|
+
key: CUSTOM_CODE_AFTER_HEAD_KEY,
|
|
25404
|
+
type: "text",
|
|
25405
|
+
text: editContentRef.current[CUSTOM_CODE_AFTER_HEAD_KEY] ?? ""
|
|
25406
|
+
});
|
|
25258
25407
|
document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
|
|
25259
25408
|
const formKey = formKeyOf(form);
|
|
25260
25409
|
if (!formKey) return;
|
|
@@ -26550,7 +26699,8 @@ function OhhwellsBridge() {
|
|
|
26550
26699
|
{
|
|
26551
26700
|
postToParent: postToParent2,
|
|
26552
26701
|
aiSectionsRef,
|
|
26553
|
-
applyTreeLocalRef
|
|
26702
|
+
applyTreeLocalRef,
|
|
26703
|
+
clearInteractionChromeRef
|
|
26554
26704
|
}
|
|
26555
26705
|
),
|
|
26556
26706
|
isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|