@ohhwells/bridge 0.1.14-next.3 → 0.1.14

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
@@ -3435,9 +3435,7 @@ function ToggleGroupItem({
3435
3435
  Toggle,
3436
3436
  {
3437
3437
  pressed: groupValue === value,
3438
- onPressedChange: (pressed) => {
3439
- if (pressed) onValueChange(value);
3440
- },
3438
+ onPressedChange: () => onValueChange(value),
3441
3439
  className: cn(
3442
3440
  "text-foreground cursor-pointer hover:bg-transparent hover:text-foreground",
3443
3441
  "data-[state=on]:bg-background data-[state=on]:shadow-sm",
@@ -3832,7 +3830,7 @@ function StateToggle({
3832
3830
  left: rect.right - 8,
3833
3831
  transform: "translateX(-100%)"
3834
3832
  },
3835
- children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
3833
+ children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ToggleGroupItem, { value: state, children: state }, state))
3836
3834
  }
3837
3835
  );
3838
3836
  }
@@ -3842,19 +3840,20 @@ function OhhwellsBridge() {
3842
3840
  const router = (0, import_navigation.useRouter)();
3843
3841
  const searchParams = (0, import_navigation.useSearchParams)();
3844
3842
  const isEditMode = isEditSessionActive();
3843
+ (0, import_react.useEffect)(() => {
3844
+ if (!isEditMode) return;
3845
+ const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
3846
+ const preconnect2 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.gstatic.com", crossOrigin: "" });
3847
+ const stylesheet = Object.assign(document.createElement("link"), { rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&display=swap" });
3848
+ document.head.append(preconnect1, preconnect2, stylesheet);
3849
+ return () => {
3850
+ preconnect1.remove();
3851
+ preconnect2.remove();
3852
+ stylesheet.remove();
3853
+ };
3854
+ }, [isEditMode]);
3845
3855
  const [bridgeRoot, setBridgeRoot] = (0, import_react.useState)(null);
3846
3856
  (0, import_react.useEffect)(() => {
3847
- const figtreeFontId = "ohw-figtree-font";
3848
- if (!document.getElementById(figtreeFontId)) {
3849
- const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
3850
- const preconnect2 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.gstatic.com", crossOrigin: "" });
3851
- const stylesheet = Object.assign(document.createElement("link"), {
3852
- id: figtreeFontId,
3853
- rel: "stylesheet",
3854
- href: "https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&display=swap"
3855
- });
3856
- document.head.append(preconnect1, preconnect2, stylesheet);
3857
- }
3858
3857
  const el = document.createElement("div");
3859
3858
  el.setAttribute("data-ohw-bridge-root", "");
3860
3859
  el.setAttribute("data-ohw-bridge", "");
@@ -3885,9 +3884,6 @@ function OhhwellsBridge() {
3885
3884
  const toolbarElRef = (0, import_react.useRef)(null);
3886
3885
  const glowElRef = (0, import_react.useRef)(null);
3887
3886
  const hoveredImageRef = (0, import_react.useRef)(null);
3888
- const hoveredImageHasTextOverlapRef = (0, import_react.useRef)(false);
3889
- const imageUnhoverTimerRef = (0, import_react.useRef)(null);
3890
- const imageShowTimerRef = (0, import_react.useRef)(null);
3891
3887
  const editStylesRef = (0, import_react.useRef)(null);
3892
3888
  const activateRef = (0, import_react.useRef)(() => {
3893
3889
  });
@@ -3950,10 +3946,6 @@ function OhhwellsBridge() {
3950
3946
  const activate = (0, import_react.useCallback)((el) => {
3951
3947
  if (activeElRef.current === el) return;
3952
3948
  deactivate();
3953
- if (hoveredImageRef.current) {
3954
- hoveredImageRef.current = null;
3955
- postToParentRef.current({ type: "ow:image-unhover" });
3956
- }
3957
3949
  el.setAttribute("contenteditable", "true");
3958
3950
  el.removeAttribute("data-ohw-hovered");
3959
3951
  activeElRef.current = el;
@@ -4001,7 +3993,7 @@ function OhhwellsBridge() {
4001
3993
  }
4002
3994
  let cancelled = false;
4003
3995
  setFetchState("loading");
4004
- const apiUrl = globalThis.process?.env?.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
3996
+ const apiUrl = globalThis.process?.env?.NEXT_PUBLIC_FLOWOPS_API_URL ?? "http://localhost:4005";
4005
3997
  fetch(`${apiUrl}/api/public/sites/${subdomain}/content`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
4006
3998
  if (cancelled) return;
4007
3999
  const content = data?.content ?? {};
@@ -4128,7 +4120,6 @@ function OhhwellsBridge() {
4128
4120
  [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY}59 !important; }
4129
4121
  [data-ohw-editable-state], [data-ohw-editable-state] * { pointer-events: none !important; }
4130
4122
  [data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
4131
- [data-ohw-editable-state][data-ohw-active-state][data-ohw-editable] { pointer-events: auto !important; }
4132
4123
  `;
4133
4124
  const forceHover = document.createElement("style");
4134
4125
  forceHover.setAttribute("data-ohw-active-state-style", "");
@@ -4155,12 +4146,10 @@ function OhhwellsBridge() {
4155
4146
  if (editable) {
4156
4147
  if (editable.dataset.ohwEditable === "image" || editable.dataset.ohwEditable === "bg-image") {
4157
4148
  e.preventDefault();
4158
- e.stopPropagation();
4159
4149
  postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "" });
4160
4150
  return;
4161
4151
  }
4162
4152
  e.preventDefault();
4163
- e.stopPropagation();
4164
4153
  activateRef.current(editable);
4165
4154
  return;
4166
4155
  }
@@ -4223,15 +4212,12 @@ function OhhwellsBridge() {
4223
4212
  }
4224
4213
  return { top, left, width: Math.max(0, right - left), height: Math.max(0, bottom - top) };
4225
4214
  };
4226
- const postImageHover = (imgEl, isDragOver = false, forceTextOverlap) => {
4215
+ const postImageHover = (imgEl, isDragOver = false) => {
4227
4216
  const r2 = getVisibleRect(imgEl);
4228
- const hasTextOverlap = forceTextOverlap ?? false;
4229
- hoveredImageHasTextOverlapRef.current = hasTextOverlap;
4230
4217
  postToParentRef.current({
4231
4218
  type: "ow:image-hover",
4232
4219
  key: imgEl.dataset.ohwKey ?? "",
4233
4220
  rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
4234
- hasTextOverlap,
4235
4221
  ...isDragOver ? { isDragOver: true } : {}
4236
4222
  });
4237
4223
  const track = imgEl.closest("[data-ohw-hover-pause]");
@@ -4278,7 +4264,7 @@ function OhhwellsBridge() {
4278
4264
  }
4279
4265
  return smallest;
4280
4266
  };
4281
- const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
4267
+ const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false, fromOverlay = false) => {
4282
4268
  const toggleEl = document.querySelector("[data-ohw-state-toggle]");
4283
4269
  if (toggleEl) {
4284
4270
  const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
@@ -4304,52 +4290,33 @@ function OhhwellsBridge() {
4304
4290
  }
4305
4291
  return;
4306
4292
  }
4307
- const isStateCardImage = !!imgEl.closest("[data-ohw-editable-state]");
4308
- const textEditable = Array.from(
4309
- document.querySelectorAll('[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])')
4310
- ).find((el) => {
4311
- const er = el.getBoundingClientRect();
4312
- return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
4313
- });
4314
- if (imageUnhoverTimerRef.current) {
4315
- clearTimeout(imageUnhoverTimerRef.current);
4316
- imageUnhoverTimerRef.current = null;
4317
- }
4318
- if (imageShowTimerRef.current) {
4319
- clearTimeout(imageShowTimerRef.current);
4320
- imageShowTimerRef.current = null;
4293
+ const topEditable = topEl?.closest("[data-ohw-editable]");
4294
+ if (topEditable && topEditable.dataset.ohwEditable !== "image" && topEditable.dataset.ohwEditable !== "bg-image") {
4295
+ if (topEditable.hasAttribute("contenteditable") && fromOverlay) return;
4296
+ if (hoveredImageRef.current) {
4297
+ hoveredImageRef.current = null;
4298
+ resumeAnimTracks();
4299
+ postToParentRef.current({ type: "ow:image-unhover" });
4300
+ }
4301
+ document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
4302
+ topEditable.setAttribute("data-ohw-hovered", "");
4303
+ return;
4321
4304
  }
4322
- if (textEditable) {
4323
- if (textEditable.hasAttribute("contenteditable")) {
4305
+ const activeHovered = document.querySelector("[data-ohw-hovered]");
4306
+ if (activeHovered) {
4307
+ const outlinePad = 8;
4308
+ const hr = activeHovered.getBoundingClientRect();
4309
+ if (x >= hr.left - outlinePad && x <= hr.right + outlinePad && y >= hr.top - outlinePad && y <= hr.bottom + outlinePad) {
4324
4310
  if (hoveredImageRef.current) {
4325
4311
  hoveredImageRef.current = null;
4326
- hoveredImageHasTextOverlapRef.current = false;
4327
4312
  resumeAnimTracks();
4328
4313
  postToParentRef.current({ type: "ow:image-unhover" });
4329
4314
  }
4330
4315
  return;
4331
4316
  }
4332
- if (isStateCardImage) {
4333
- if (imgEl !== hoveredImageRef.current || !hoveredImageHasTextOverlapRef.current) {
4334
- hoveredImageRef.current = imgEl;
4335
- postImageHover(imgEl, isDragOver, true);
4336
- }
4337
- document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
4338
- textEditable.setAttribute("data-ohw-hovered", "");
4339
- return;
4340
- }
4341
- if (hoveredImageRef.current) {
4342
- hoveredImageRef.current = null;
4343
- hoveredImageHasTextOverlapRef.current = false;
4344
- resumeAnimTracks();
4345
- postToParentRef.current({ type: "ow:image-unhover" });
4346
- }
4347
- document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
4348
- textEditable.setAttribute("data-ohw-hovered", "");
4349
- return;
4350
4317
  }
4351
4318
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
4352
- if (imgEl !== hoveredImageRef.current || hoveredImageHasTextOverlapRef.current) {
4319
+ if (imgEl !== hoveredImageRef.current) {
4353
4320
  hoveredImageRef.current = imgEl;
4354
4321
  postImageHover(imgEl, isDragOver);
4355
4322
  } else if (isDragOver) {
@@ -4358,29 +4325,9 @@ function OhhwellsBridge() {
4358
4325
  } else {
4359
4326
  const inIframeView = clientX >= 0 && clientY >= 0 && clientX <= window.innerWidth && clientY <= window.innerHeight;
4360
4327
  if (!inIframeView) return;
4361
- if (imageUnhoverTimerRef.current) {
4362
- clearTimeout(imageUnhoverTimerRef.current);
4363
- imageUnhoverTimerRef.current = null;
4364
- }
4365
- if (imageShowTimerRef.current) {
4366
- clearTimeout(imageShowTimerRef.current);
4367
- imageShowTimerRef.current = null;
4368
- }
4369
- if (hoveredImageRef.current) {
4370
- hoveredImageRef.current = null;
4371
- hoveredImageHasTextOverlapRef.current = false;
4372
- resumeAnimTracks();
4373
- postToParentRef.current({ type: "ow:image-unhover" });
4374
- }
4375
- const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
4376
- const textEl = Array.from(
4377
- document.querySelectorAll('[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])')
4378
- ).find((el) => {
4379
- const er = el.getBoundingClientRect();
4380
- return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
4381
- });
4382
- document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
4383
- if (textEl && !textEl.hasAttribute("contenteditable")) textEl.setAttribute("data-ohw-hovered", "");
4328
+ hoveredImageRef.current = null;
4329
+ resumeAnimTracks();
4330
+ postToParentRef.current({ type: "ow:image-unhover" });
4384
4331
  }
4385
4332
  };
4386
4333
  const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
@@ -4399,18 +4346,15 @@ function OhhwellsBridge() {
4399
4346
  }) ?? null;
4400
4347
  const currentLocked = activeStateElRef.current?.hasAttribute("data-ohw-active-state") ? activeStateElRef.current : null;
4401
4348
  const active = found ?? currentLocked;
4402
- const prev = activeStateElRef.current;
4403
4349
  activeStateElRef.current = active;
4404
- if (active !== prev) {
4405
- if (prev) prev.removeAttribute("data-ohw-state-hovered");
4406
- if (active) {
4407
- if (active.querySelector("[data-ohw-state-view]")) active.setAttribute("data-ohw-state-hovered", "");
4408
- const states = deriveStates(active.dataset.ohwEditableState ?? "");
4409
- const activeState = active.hasAttribute("data-ohw-active-state") ? (active.getAttribute("data-ohw-active-state") ?? "Default").charAt(0).toUpperCase() + (active.getAttribute("data-ohw-active-state") ?? "").slice(1) : "Default";
4410
- setToggleState({ rect: active.getBoundingClientRect(), activeState, states });
4411
- } else {
4412
- setToggleState(null);
4413
- }
4350
+ document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => el.removeAttribute("data-ohw-state-hovered"));
4351
+ if (active) {
4352
+ if (active.querySelector("[data-ohw-state-view]")) active.setAttribute("data-ohw-state-hovered", "");
4353
+ const states = deriveStates(active.dataset.ohwEditableState ?? "");
4354
+ const activeState = active.hasAttribute("data-ohw-active-state") ? (active.getAttribute("data-ohw-active-state") ?? "Default").charAt(0).toUpperCase() + (active.getAttribute("data-ohw-active-state") ?? "").slice(1) : "Default";
4355
+ setToggleState({ rect: active.getBoundingClientRect(), activeState, states });
4356
+ } else {
4357
+ setToggleState(null);
4414
4358
  }
4415
4359
  };
4416
4360
  const handleMouseMove = (e) => {
@@ -4420,9 +4364,9 @@ function OhhwellsBridge() {
4420
4364
  };
4421
4365
  const handlePointerSync = (e) => {
4422
4366
  if (e.data?.type !== "ow:pointer-sync") return;
4423
- const { clientX, clientY } = e.data;
4367
+ const { clientX, clientY, fromOverlay } = e.data;
4424
4368
  if (typeof clientX !== "number" || typeof clientY !== "number") return;
4425
- probeImageAt(clientX, clientY);
4369
+ probeImageAt(clientX, clientY, false, false, fromOverlay ?? false);
4426
4370
  probeHoverCardsAt(clientX, clientY);
4427
4371
  };
4428
4372
  const handleDragOver = (e) => {
@@ -4435,8 +4379,7 @@ function OhhwellsBridge() {
4435
4379
  e.dataTransfer.dropEffect = "copy";
4436
4380
  if (hoveredImageRef.current !== el) {
4437
4381
  hoveredImageRef.current = el;
4438
- const isStateCard = !!el.closest("[data-ohw-editable-state]");
4439
- postImageHover(el, true, isStateCard ? true : void 0);
4382
+ postImageHover(el, true);
4440
4383
  }
4441
4384
  };
4442
4385
  const handleDragLeave = (e) => {
@@ -4622,13 +4565,11 @@ function OhhwellsBridge() {
4622
4565
  setToggleState((prev) => prev ? { ...prev, rect } : null);
4623
4566
  }
4624
4567
  if (hoveredImageRef.current) {
4625
- const el = hoveredImageRef.current;
4626
- const r2 = el.getBoundingClientRect();
4568
+ const r2 = hoveredImageRef.current.getBoundingClientRect();
4627
4569
  postToParentRef.current({
4628
4570
  type: "ow:image-hover",
4629
- key: el.dataset.ohwKey ?? "",
4630
- rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
4631
- hasTextOverlap: hoveredImageHasTextOverlapRef.current
4571
+ key: hoveredImageRef.current.dataset.ohwKey ?? "",
4572
+ rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height }
4632
4573
  });
4633
4574
  }
4634
4575
  };
@@ -4702,49 +4643,12 @@ function OhhwellsBridge() {
4702
4643
  parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
4703
4644
  if (activeElRef.current) applyToolbarPos(activeElRef.current.getBoundingClientRect());
4704
4645
  };
4705
- const handleClickAt = (e) => {
4706
- if (e.data?.type !== "ow:click-at") return;
4707
- const { clientX, clientY } = e.data;
4708
- const allImages = Array.from(
4709
- document.querySelectorAll('[data-ohw-editable="image"], [data-ohw-editable="bg-image"]')
4710
- ).filter((el) => !!el.closest("[data-ohw-editable-state]"));
4711
- const stateCardImage = allImages.find((el) => {
4712
- const ownerCard = el.closest("[data-ohw-editable-state]");
4713
- if (ownerCard) {
4714
- const inHoverState = ownerCard.getAttribute("data-ohw-active-state") === "hover";
4715
- const elState = el.dataset.ohwState;
4716
- if (el === ownerCard && inHoverState) return false;
4717
- if (elState === "default" && inHoverState) return false;
4718
- if (elState === "hover" && !inHoverState) return false;
4719
- }
4720
- const r2 = el.getBoundingClientRect();
4721
- return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
4722
- });
4723
- if (stateCardImage) {
4724
- postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "" });
4725
- return;
4726
- }
4727
- const textEditable = Array.from(
4728
- document.querySelectorAll(
4729
- '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])'
4730
- )
4731
- ).find((el) => {
4732
- const r2 = el.getBoundingClientRect();
4733
- return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
4734
- });
4735
- if (textEditable) {
4736
- activateRef.current(textEditable);
4737
- return;
4738
- }
4739
- deactivateRef.current();
4740
- };
4741
4646
  window.addEventListener("message", handleSave);
4742
4647
  window.addEventListener("message", handleImageUrl);
4743
4648
  window.addEventListener("message", handleAnimLock);
4744
4649
  window.addEventListener("message", handleCanvasHeight);
4745
4650
  window.addEventListener("message", handleParentScroll);
4746
4651
  window.addEventListener("message", handlePointerSync);
4747
- window.addEventListener("message", handleClickAt);
4748
4652
  document.addEventListener("click", handleClick, true);
4749
4653
  document.addEventListener("paste", handlePaste, true);
4750
4654
  document.addEventListener("input", handleInput, true);
@@ -4778,13 +4682,10 @@ function OhhwellsBridge() {
4778
4682
  window.removeEventListener("message", handleCanvasHeight);
4779
4683
  window.removeEventListener("message", handleParentScroll);
4780
4684
  window.removeEventListener("message", handlePointerSync);
4781
- window.removeEventListener("message", handleClickAt);
4782
4685
  window.removeEventListener("message", handleHydrate);
4783
4686
  window.removeEventListener("message", handleDeactivate);
4784
4687
  autoSaveTimers.current.forEach(clearTimeout);
4785
4688
  autoSaveTimers.current.clear();
4786
- if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
4787
- if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
4788
4689
  };
4789
4690
  }, [isEditMode, refreshStateRules]);
4790
4691
  (0, import_react.useEffect)(() => {