@ohhwells/bridge 0.1.82 → 0.1.84

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.js CHANGED
@@ -183,6 +183,17 @@ var BRAND_VAR_PREFIX = "--ohw-brand-";
183
183
  var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
184
184
  (role) => `${BRAND_VAR_PREFIX}${role}`
185
185
  );
186
+ var LEGACY_BRAND_VAR_NAMES = [
187
+ "primary",
188
+ "accent",
189
+ "background",
190
+ "text",
191
+ "text-muted",
192
+ "surface",
193
+ "border",
194
+ "on-primary",
195
+ "navbar-background"
196
+ ].map((role) => `--brand-${role}`);
186
197
  var FONT_VARS = {
187
198
  heading: ["--font-heading", "--font-display", "--brand-font-heading"],
188
199
  body: ["--font-body", "--brand-font-body"]
@@ -191,14 +202,29 @@ var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
191
202
  function brandColorVars(kit) {
192
203
  const { dark, primary, accent, light } = kit.palette;
193
204
  const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
205
+ const surface = mix(light, 95, dark);
206
+ const border = mix(light, 85, dark);
207
+ const muted = mix(dark, 62, light);
194
208
  return {
195
209
  [`${BRAND_VAR_PREFIX}primary`]: primary,
196
210
  [`${BRAND_VAR_PREFIX}accent`]: accent,
197
211
  [`${BRAND_VAR_PREFIX}light`]: light,
198
212
  [`${BRAND_VAR_PREFIX}dark`]: dark,
199
- [`${BRAND_VAR_PREFIX}surface`]: mix(light, 95, dark),
200
- [`${BRAND_VAR_PREFIX}border`]: mix(light, 85, dark),
201
- [`${BRAND_VAR_PREFIX}muted`]: mix(dark, 62, light)
213
+ [`${BRAND_VAR_PREFIX}surface`]: surface,
214
+ [`${BRAND_VAR_PREFIX}border`]: border,
215
+ [`${BRAND_VAR_PREFIX}muted`]: muted,
216
+ // The BrandProvider contract every template actually renders from (see LEGACY_BRAND_VAR_NAMES).
217
+ "--brand-primary": primary,
218
+ "--brand-accent": accent,
219
+ "--brand-background": light,
220
+ "--brand-text": dark,
221
+ "--brand-text-muted": muted,
222
+ "--brand-surface": surface,
223
+ "--brand-border": border,
224
+ // Buttons/bands painted in the primary colour assume it's dark/saturated enough to need
225
+ // light text on top — the same assumption LOGO_IMAGE's light-on-dark navbar mark makes.
226
+ "--brand-on-primary": light,
227
+ "--brand-navbar-background": dark
202
228
  };
203
229
  }
204
230
  function parseBrandKit(raw) {
@@ -239,7 +265,7 @@ function loadBrandFonts(families) {
239
265
  function applyBrandToDom(kit) {
240
266
  const root = document.documentElement;
241
267
  if (!kit) {
242
- for (const name of BRAND_VAR_NAMES) root.style.removeProperty(name);
268
+ for (const name of [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES]) root.style.removeProperty(name);
243
269
  for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
244
270
  document.getElementById(BRAND_FONT_LINK_ID)?.remove();
245
271
  return;
@@ -336,7 +362,9 @@ var NODE_WROTE_ATTR = "data-ohw-style-node";
336
362
  var NODE_PROPS = ["color", "font-family", "font-size", "background"];
337
363
  function saveInline(el, prop) {
338
364
  const attr = `data-ohw-style-prev-${prop}`;
339
- if (!el.hasAttribute(attr)) el.setAttribute(attr, el.style.getPropertyValue(prop));
365
+ if (el.hasAttribute(attr)) return;
366
+ const value = el.style.getPropertyValue(prop) || (prop === "background" ? el.style.getPropertyValue("background-color") : "");
367
+ el.setAttribute(attr, value);
340
368
  }
341
369
  function restoreInline(el, prop) {
342
370
  const attr = `data-ohw-style-prev-${prop}`;
@@ -387,7 +415,8 @@ function applyStylesToDom(store) {
387
415
  const sections = document.querySelectorAll(
388
416
  `[data-ohw-section="${CSS.escape(sectionId)}"]`
389
417
  );
390
- for (const section of Array.from(sections)) {
418
+ for (const marker of Array.from(sections)) {
419
+ const section = marker.querySelector(":scope > [data-ai-section]") ?? marker;
391
420
  for (const [prop, attr] of Object.entries(SECTION_ATTRS)) {
392
421
  const value = override[prop];
393
422
  if (value === void 0) continue;
@@ -7356,6 +7385,9 @@ function applyFieldType(wrapper, type) {
7356
7385
  el.style.removeProperty("min-height");
7357
7386
  el.style.removeProperty("resize");
7358
7387
  el.removeAttribute("rows");
7388
+ if (el.className) {
7389
+ el.className = el.className.split(/\s+/).filter((token) => !/textarea/i.test(token)).join(" ");
7390
+ }
7359
7391
  };
7360
7392
  const applyDefaults = (el) => {
7361
7393
  el.setAttribute("placeholder", defaults.placeholder);
@@ -11606,7 +11638,7 @@ function applySocialsDisplayToRow(row, display) {
11606
11638
  const icon = item.querySelector(ICON_SELECTOR);
11607
11639
  if (label) label.style.display = display.text ? "" : "none";
11608
11640
  if (icon) icon.style.display = display.icon ? "" : "none";
11609
- layOutIconAndLabel(item, Boolean(display.text && display.icon));
11641
+ layOutIconAndLabel(item, Boolean(display.text));
11610
11642
  });
11611
11643
  allowRowToWrap(row);
11612
11644
  }
@@ -11618,6 +11650,9 @@ function layOutIconAndLabel(item, on) {
11618
11650
  item.style.gap = "";
11619
11651
  item.style.whiteSpace = "";
11620
11652
  item.style.flex = "";
11653
+ item.style.width = "";
11654
+ item.style.height = "";
11655
+ item.style.padding = "";
11621
11656
  return;
11622
11657
  }
11623
11658
  item.style.display = on ? "inline-flex" : "";
@@ -11625,6 +11660,9 @@ function layOutIconAndLabel(item, on) {
11625
11660
  item.style.gap = on ? "8px" : "";
11626
11661
  item.style.whiteSpace = on ? "nowrap" : "";
11627
11662
  item.style.flex = on ? "0 0 auto" : "";
11663
+ item.style.width = on ? "auto" : "";
11664
+ item.style.height = on ? "auto" : "";
11665
+ item.style.padding = on ? "0 12px" : "";
11628
11666
  }
11629
11667
  function allowRowToWrap(row) {
11630
11668
  const display = row.ownerDocument.defaultView?.getComputedStyle(row).display ?? "";
@@ -12580,6 +12618,15 @@ function resolveLogoDisplayText(text) {
12580
12618
  function isFooterLogoRoot(root) {
12581
12619
  return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
12582
12620
  }
12621
+ var NAV_IMAGE_KEYS = ["nav-logo-image", "logo-image"];
12622
+ var FOOTER_IMAGE_KEYS = ["footer-logo", "footer-logo-image", "footer-logo-img"];
12623
+ function firstNonEmptyContentValue(content, keys) {
12624
+ for (const key of keys) {
12625
+ const value = content[key];
12626
+ if (typeof value === "string" && value.trim()) return value.trim();
12627
+ }
12628
+ return null;
12629
+ }
12583
12630
  function imageKeyForRoot(root) {
12584
12631
  return isFooterLogoRoot(root) ? "footer-logo" : "nav-logo-image";
12585
12632
  }
@@ -12629,9 +12676,10 @@ function applyLogoIdentity(text, isPlaceholder) {
12629
12676
  });
12630
12677
  return display;
12631
12678
  }
12632
- function applyLogoImage(url, alt) {
12679
+ function applyLogoImage(url, alt, placement) {
12633
12680
  const displayAlt = resolveLogoDisplayText(alt);
12634
12681
  document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
12682
+ if (placement && (isFooterLogoRoot(root) ? "footer" : "navbar") !== placement) return;
12635
12683
  ensureLogoHrefKey(root);
12636
12684
  const imageKey = imageKeyForRoot(root);
12637
12685
  const textKey = textKeyForRoot(root);
@@ -12752,7 +12800,12 @@ function applyLogoFromContent(content) {
12752
12800
  const logoImageUrl = typeof rawLogoImage === "string" && rawLogoImage.trim() ? rawLogoImage.trim() : null;
12753
12801
  const imageExplicitlyCleared = LOGO_IMAGE_KEYS.some((key) => key in content) && !logoImageUrl;
12754
12802
  const logoIsPlaceholder = LOGO_PLACEHOLDER_KEY in content ? content[LOGO_PLACEHOLDER_KEY] !== "false" : !logoImageUrl && (!logoText.trim() || logoText === PLACEHOLDER_BUSINESS_NAME);
12755
- if (logoImageUrl) {
12803
+ const navImageUrl = firstNonEmptyContentValue(content, NAV_IMAGE_KEYS);
12804
+ const footerImageUrl = firstNonEmptyContentValue(content, FOOTER_IMAGE_KEYS);
12805
+ if (navImageUrl && footerImageUrl && navImageUrl !== footerImageUrl) {
12806
+ applyLogoImage(navImageUrl, logoAlt, "navbar");
12807
+ applyLogoImage(footerImageUrl, logoAlt, "footer");
12808
+ } else if (logoImageUrl) {
12756
12809
  applyLogoImage(logoImageUrl, logoAlt);
12757
12810
  } else {
12758
12811
  if (imageExplicitlyCleared) applyLogoImage(null, logoAlt);
@@ -18135,6 +18188,8 @@ function OhhwellsBridge() {
18135
18188
  };
18136
18189
  const t1 = setTimeout(measure, 50);
18137
18190
  const t2 = setTimeout(measure, 500);
18191
+ const ro = new ResizeObserver(schedule);
18192
+ ro.observe(document.body);
18138
18193
  let lastWidth = window.innerWidth;
18139
18194
  let resizeTimers = [];
18140
18195
  const clearResizeTimers = () => {
@@ -18152,6 +18207,7 @@ function OhhwellsBridge() {
18152
18207
  clearTimeout(t1);
18153
18208
  clearTimeout(t2);
18154
18209
  if (raf != null) cancelAnimationFrame(raf);
18210
+ ro.disconnect();
18155
18211
  clearResizeTimers();
18156
18212
  window.removeEventListener("resize", handleResize);
18157
18213
  };
@@ -21024,7 +21080,7 @@ function OhhwellsBridge() {
21024
21080
  postToParent2({
21025
21081
  type: "ow:ready",
21026
21082
  version: "1",
21027
- bridgeVersion: "0.1.81",
21083
+ bridgeVersion: "0.1.83",
21028
21084
  path: pathname,
21029
21085
  nodes: collectEditableNodes(editContentRef.current),
21030
21086
  sections