@ohhwells/bridge 0.1.38-next.62 → 0.1.38-next.64
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 +1126 -292
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +1122 -288
- package/dist/index.js.map +1 -1
- package/dist/styles.css +14 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import
|
|
4
|
+
import React10, { useCallback as useCallback4, useEffect as useEffect8, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState7 } from "react";
|
|
5
5
|
import { createRoot } from "react-dom/client";
|
|
6
6
|
import { flushSync } from "react-dom";
|
|
7
7
|
|
|
@@ -511,7 +511,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
511
511
|
}
|
|
512
512
|
)
|
|
513
513
|
] }),
|
|
514
|
-
/* @__PURE__ */ jsx2("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ jsx2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
514
|
+
cls.showAvailability !== false && /* @__PURE__ */ jsx2("div", { className: "sm:hidden flex flex-col gap-px", children: isFull ? /* @__PURE__ */ jsx2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
515
515
|
/* @__PURE__ */ jsxs2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
516
516
|
available,
|
|
517
517
|
"/",
|
|
@@ -523,9 +523,10 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
523
523
|
/* @__PURE__ */ jsxs2("div", { className: "flex flex-1 flex-col gap-2 min-w-0 sm:contents", children: [
|
|
524
524
|
/* @__PURE__ */ jsxs2("div", { className: "flex-1 flex flex-col gap-2 min-w-0", children: [
|
|
525
525
|
/* @__PURE__ */ jsx2("span", { className: "font-body text-base font-bold text-(--color-dark,#200C02) block truncate", children: cls.name }),
|
|
526
|
-
cls.hostName && /* @__PURE__ */ jsx2("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName })
|
|
526
|
+
cls.hostName && /* @__PURE__ */ jsx2("span", { className: "font-body text-base font-normal text-(--color-dark,#200C02) opacity-80 block truncate", children: cls.hostName }),
|
|
527
|
+
cls.description && /* @__PURE__ */ jsx2("span", { className: "font-body text-sm font-normal text-(--color-dark,#200C02) opacity-70 block truncate", children: cls.description })
|
|
527
528
|
] }),
|
|
528
|
-
/* @__PURE__ */ jsx2("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ jsx2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
529
|
+
cls.showAvailability !== false && /* @__PURE__ */ jsx2("div", { className: "hidden sm:flex w-14 shrink-0 flex-col gap-px", children: isFull ? /* @__PURE__ */ jsx2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: "Full" }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
529
530
|
/* @__PURE__ */ jsxs2("span", { className: "font-body text-sm text-(--color-dark,#200C02) opacity-80", children: [
|
|
530
531
|
available,
|
|
531
532
|
"/",
|
|
@@ -4492,7 +4493,7 @@ function getChromeStyle(state) {
|
|
|
4492
4493
|
case "dragging":
|
|
4493
4494
|
return {
|
|
4494
4495
|
border: `2px solid ${PRIMARY}`,
|
|
4495
|
-
boxShadow: DRAG_SHADOW
|
|
4496
|
+
boxShadow: `${FOCUS_RING}, ${DRAG_SHADOW}`
|
|
4496
4497
|
};
|
|
4497
4498
|
default:
|
|
4498
4499
|
return {};
|
|
@@ -4508,6 +4509,8 @@ function ItemInteractionLayer({
|
|
|
4508
4509
|
dragHandleLabel = "Reorder item",
|
|
4509
4510
|
onDragHandleDragStart,
|
|
4510
4511
|
onDragHandleDragEnd,
|
|
4512
|
+
onItemPointerDown,
|
|
4513
|
+
onItemClick,
|
|
4511
4514
|
chromeGap = 6,
|
|
4512
4515
|
className
|
|
4513
4516
|
}) {
|
|
@@ -4515,7 +4518,8 @@ function ItemInteractionLayer({
|
|
|
4515
4518
|
const isActive = state === "active-top" || state === "active-bottom";
|
|
4516
4519
|
const isDragging = state === "dragging";
|
|
4517
4520
|
const showToolbar = isActive && toolbar;
|
|
4518
|
-
const showDragHandle = isActive
|
|
4521
|
+
const showDragHandle = (isActive || isDragging) && showHandle;
|
|
4522
|
+
const itemDragEnabled = isActive && showHandle && !isDragging && !dragDisabled;
|
|
4519
4523
|
return /* @__PURE__ */ jsxs4(
|
|
4520
4524
|
"div",
|
|
4521
4525
|
{
|
|
@@ -4540,11 +4544,28 @@ function ItemInteractionLayer({
|
|
|
4540
4544
|
style: getChromeStyle(state)
|
|
4541
4545
|
}
|
|
4542
4546
|
),
|
|
4547
|
+
itemDragEnabled && /* @__PURE__ */ jsx9(
|
|
4548
|
+
"div",
|
|
4549
|
+
{
|
|
4550
|
+
"data-ohw-item-drag-surface": "",
|
|
4551
|
+
className: "pointer-events-auto absolute inset-0 cursor-grab rounded-lg active:cursor-grabbing",
|
|
4552
|
+
onPointerDown: (e) => {
|
|
4553
|
+
if (e.button !== 0) return;
|
|
4554
|
+
onItemPointerDown?.(e);
|
|
4555
|
+
},
|
|
4556
|
+
onClick: (e) => {
|
|
4557
|
+
e.preventDefault();
|
|
4558
|
+
e.stopPropagation();
|
|
4559
|
+
onItemClick?.(e.clientX, e.clientY);
|
|
4560
|
+
}
|
|
4561
|
+
}
|
|
4562
|
+
),
|
|
4543
4563
|
showDragHandle && /* @__PURE__ */ jsx9(
|
|
4544
4564
|
"div",
|
|
4545
4565
|
{
|
|
4546
4566
|
"data-ohw-drag-handle-container": "",
|
|
4547
|
-
className: "pointer-events-auto absolute left-0 top-1/2 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4567
|
+
className: "pointer-events-auto absolute left-0 top-1/2 z-10 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4568
|
+
style: isDragging ? { visibility: "hidden" } : void 0,
|
|
4548
4569
|
children: /* @__PURE__ */ jsx9(
|
|
4549
4570
|
DragHandle,
|
|
4550
4571
|
{
|
|
@@ -6546,6 +6567,319 @@ function insertNavbarItem(href, label, afterAnchor = null) {
|
|
|
6546
6567
|
};
|
|
6547
6568
|
}
|
|
6548
6569
|
|
|
6570
|
+
// src/lib/footer-items.ts
|
|
6571
|
+
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
6572
|
+
var FOOTER_HREF_RE = /^footer-(\d+)-(\d+)-href$/;
|
|
6573
|
+
function parseFooterHrefKey(key) {
|
|
6574
|
+
if (!key) return null;
|
|
6575
|
+
const match = key.match(FOOTER_HREF_RE);
|
|
6576
|
+
if (!match) return null;
|
|
6577
|
+
return { col: parseInt(match[1], 10), item: parseInt(match[2], 10) };
|
|
6578
|
+
}
|
|
6579
|
+
function isFooterHrefKey(key) {
|
|
6580
|
+
return parseFooterHrefKey(key) !== null;
|
|
6581
|
+
}
|
|
6582
|
+
function getFooterRoot() {
|
|
6583
|
+
return document.querySelector('footer[data-ohw-section="footer"], footer');
|
|
6584
|
+
}
|
|
6585
|
+
function getFooterLinksContainer() {
|
|
6586
|
+
return document.querySelector("[data-ohw-footer-links]") ?? document.querySelector(".rb-footer-links");
|
|
6587
|
+
}
|
|
6588
|
+
function isFooterLinkAnchor(el) {
|
|
6589
|
+
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6590
|
+
if (!isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) return false;
|
|
6591
|
+
return Boolean(el.querySelector('[data-ohw-editable="text"]'));
|
|
6592
|
+
}
|
|
6593
|
+
function listFooterColumns() {
|
|
6594
|
+
const root = getFooterLinksContainer() ?? getFooterRoot()?.querySelector(".rb-footer-links") ?? null;
|
|
6595
|
+
if (!root) return [];
|
|
6596
|
+
const explicit = Array.from(root.querySelectorAll(":scope > [data-ohw-footer-col]"));
|
|
6597
|
+
if (explicit.length > 0) return explicit;
|
|
6598
|
+
return Array.from(root.children).filter((el) => {
|
|
6599
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
6600
|
+
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(
|
|
6601
|
+
isFooterLinkAnchor
|
|
6602
|
+
);
|
|
6603
|
+
});
|
|
6604
|
+
}
|
|
6605
|
+
function listFooterLinksInColumn(column) {
|
|
6606
|
+
return Array.from(column.querySelectorAll(":scope > [data-ohw-href-key]")).filter(
|
|
6607
|
+
isFooterLinkAnchor
|
|
6608
|
+
);
|
|
6609
|
+
}
|
|
6610
|
+
function findFooterColumnForLink(anchor) {
|
|
6611
|
+
const columns = listFooterColumns();
|
|
6612
|
+
return columns.find((col) => col.contains(anchor)) ?? null;
|
|
6613
|
+
}
|
|
6614
|
+
function getFooterOrderFromDom() {
|
|
6615
|
+
return listFooterColumns().map(
|
|
6616
|
+
(col) => listFooterLinksInColumn(col).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key))
|
|
6617
|
+
);
|
|
6618
|
+
}
|
|
6619
|
+
function findFooterLinkByKey(hrefKey) {
|
|
6620
|
+
return document.querySelector(
|
|
6621
|
+
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
6622
|
+
);
|
|
6623
|
+
}
|
|
6624
|
+
function syncFooterColumnIndices(columns) {
|
|
6625
|
+
columns.forEach((col, index) => {
|
|
6626
|
+
const next = String(index);
|
|
6627
|
+
if (col.getAttribute("data-ohw-footer-col") !== next) {
|
|
6628
|
+
col.setAttribute("data-ohw-footer-col", next);
|
|
6629
|
+
}
|
|
6630
|
+
});
|
|
6631
|
+
}
|
|
6632
|
+
function appendChildIfNeeded(parent, child) {
|
|
6633
|
+
if (parent.lastElementChild !== child) {
|
|
6634
|
+
parent.appendChild(child);
|
|
6635
|
+
}
|
|
6636
|
+
}
|
|
6637
|
+
function insertLinkBeforeNext(col, el, nextEl) {
|
|
6638
|
+
if (nextEl) {
|
|
6639
|
+
if (el.nextElementSibling !== nextEl) {
|
|
6640
|
+
col.insertBefore(el, nextEl);
|
|
6641
|
+
}
|
|
6642
|
+
return;
|
|
6643
|
+
}
|
|
6644
|
+
if (col.lastElementChild !== el) {
|
|
6645
|
+
col.appendChild(el);
|
|
6646
|
+
}
|
|
6647
|
+
}
|
|
6648
|
+
function applyFooterOrder(order) {
|
|
6649
|
+
const container = getFooterLinksContainer();
|
|
6650
|
+
if (!container) return;
|
|
6651
|
+
const columns = listFooterColumns();
|
|
6652
|
+
if (columns.length === 0) return;
|
|
6653
|
+
const currentOrder = getFooterOrderFromDom();
|
|
6654
|
+
if (ordersEqual(order, currentOrder)) {
|
|
6655
|
+
syncFooterColumnIndices(columns);
|
|
6656
|
+
return;
|
|
6657
|
+
}
|
|
6658
|
+
const colCount = Math.max(columns.length, order.length);
|
|
6659
|
+
const working = columns.slice(0, colCount);
|
|
6660
|
+
for (let i = 0; i < order.length && i < working.length; i++) {
|
|
6661
|
+
appendChildIfNeeded(container, working[i]);
|
|
6662
|
+
}
|
|
6663
|
+
for (let i = order.length; i < working.length; i++) {
|
|
6664
|
+
appendChildIfNeeded(container, working[i]);
|
|
6665
|
+
}
|
|
6666
|
+
const freshColumns = listFooterColumns();
|
|
6667
|
+
syncFooterColumnIndices(freshColumns);
|
|
6668
|
+
for (let c = 0; c < order.length; c++) {
|
|
6669
|
+
const col = freshColumns[c];
|
|
6670
|
+
if (!col) continue;
|
|
6671
|
+
const colOrder = order[c];
|
|
6672
|
+
for (let j = 0; j < colOrder.length; j++) {
|
|
6673
|
+
const hrefKey = colOrder[j];
|
|
6674
|
+
const el = findFooterLinkByKey(hrefKey);
|
|
6675
|
+
if (!el) continue;
|
|
6676
|
+
if (el.parentElement !== col) {
|
|
6677
|
+
col.appendChild(el);
|
|
6678
|
+
}
|
|
6679
|
+
const nextKey = colOrder[j + 1];
|
|
6680
|
+
const nextEl = nextKey ? findFooterLinkByKey(nextKey) : null;
|
|
6681
|
+
insertLinkBeforeNext(col, el, nextEl?.parentElement === col ? nextEl : null);
|
|
6682
|
+
}
|
|
6683
|
+
}
|
|
6684
|
+
}
|
|
6685
|
+
function ordersEqual(a, b) {
|
|
6686
|
+
if (a.length !== b.length) return false;
|
|
6687
|
+
for (let i = 0; i < a.length; i++) {
|
|
6688
|
+
const left = a[i];
|
|
6689
|
+
const right = b[i];
|
|
6690
|
+
if (left.length !== right.length) return false;
|
|
6691
|
+
for (let j = 0; j < left.length; j++) {
|
|
6692
|
+
if (left[j] !== right[j]) return false;
|
|
6693
|
+
}
|
|
6694
|
+
}
|
|
6695
|
+
return true;
|
|
6696
|
+
}
|
|
6697
|
+
function planFooterLinkMove(hrefKey, targetColIndex, insertIndex) {
|
|
6698
|
+
const order = getFooterOrderFromDom();
|
|
6699
|
+
if (targetColIndex < 0 || targetColIndex >= order.length) return null;
|
|
6700
|
+
let fromCol = -1;
|
|
6701
|
+
let fromIdx = -1;
|
|
6702
|
+
for (let c = 0; c < order.length; c++) {
|
|
6703
|
+
const idx = order[c].indexOf(hrefKey);
|
|
6704
|
+
if (idx >= 0) {
|
|
6705
|
+
fromCol = c;
|
|
6706
|
+
fromIdx = idx;
|
|
6707
|
+
break;
|
|
6708
|
+
}
|
|
6709
|
+
}
|
|
6710
|
+
if (fromCol < 0) return null;
|
|
6711
|
+
const next = order.map((col) => [...col]);
|
|
6712
|
+
next[fromCol].splice(fromIdx, 1);
|
|
6713
|
+
let adjusted = insertIndex;
|
|
6714
|
+
if (fromCol === targetColIndex && fromIdx < insertIndex) adjusted -= 1;
|
|
6715
|
+
adjusted = Math.max(0, Math.min(adjusted, next[targetColIndex].length));
|
|
6716
|
+
next[targetColIndex].splice(adjusted, 0, hrefKey);
|
|
6717
|
+
if (ordersEqual(next, order)) return null;
|
|
6718
|
+
return next;
|
|
6719
|
+
}
|
|
6720
|
+
function planFooterColumnMove(fromIndex, toIndex) {
|
|
6721
|
+
const order = getFooterOrderFromDom();
|
|
6722
|
+
const columns = listFooterColumns();
|
|
6723
|
+
if (fromIndex < 0 || fromIndex >= columns.length || toIndex < 0 || toIndex > columns.length) {
|
|
6724
|
+
return null;
|
|
6725
|
+
}
|
|
6726
|
+
if (toIndex === fromIndex || toIndex === fromIndex + 1) return null;
|
|
6727
|
+
const nextOrder = order.map((col) => [...col]);
|
|
6728
|
+
const [movedOrder] = nextOrder.splice(fromIndex, 1);
|
|
6729
|
+
if (!movedOrder) return null;
|
|
6730
|
+
let adjusted = toIndex;
|
|
6731
|
+
if (fromIndex < toIndex) adjusted -= 1;
|
|
6732
|
+
adjusted = Math.max(0, Math.min(adjusted, nextOrder.length));
|
|
6733
|
+
nextOrder.splice(adjusted, 0, movedOrder);
|
|
6734
|
+
if (ordersEqual(nextOrder, order)) return null;
|
|
6735
|
+
return nextOrder;
|
|
6736
|
+
}
|
|
6737
|
+
function parseFooterOrder(content) {
|
|
6738
|
+
const raw = content[FOOTER_ORDER_KEY];
|
|
6739
|
+
if (!raw) return null;
|
|
6740
|
+
try {
|
|
6741
|
+
const parsed = JSON.parse(raw);
|
|
6742
|
+
if (!Array.isArray(parsed)) return null;
|
|
6743
|
+
return parsed.filter((col) => Array.isArray(col)).map((col) => col.filter((key) => typeof key === "string" && key.length > 0));
|
|
6744
|
+
} catch {
|
|
6745
|
+
return null;
|
|
6746
|
+
}
|
|
6747
|
+
}
|
|
6748
|
+
function reconcileFooterOrderFromContent(content) {
|
|
6749
|
+
const order = parseFooterOrder(content);
|
|
6750
|
+
if (!order?.length) return;
|
|
6751
|
+
const current = getFooterOrderFromDom();
|
|
6752
|
+
if (ordersEqual(order, current)) {
|
|
6753
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
6754
|
+
return;
|
|
6755
|
+
}
|
|
6756
|
+
applyFooterOrder(order);
|
|
6757
|
+
}
|
|
6758
|
+
function buildLinkDropSlots(column, columnIndex) {
|
|
6759
|
+
const links = listFooterLinksInColumn(column);
|
|
6760
|
+
const colRect = column.getBoundingClientRect();
|
|
6761
|
+
const slots = [];
|
|
6762
|
+
const barThickness = 3;
|
|
6763
|
+
if (links.length === 0) {
|
|
6764
|
+
slots.push({
|
|
6765
|
+
insertIndex: 0,
|
|
6766
|
+
columnIndex,
|
|
6767
|
+
left: colRect.left,
|
|
6768
|
+
top: colRect.top + colRect.height / 2 - barThickness / 2,
|
|
6769
|
+
width: colRect.width,
|
|
6770
|
+
height: barThickness,
|
|
6771
|
+
direction: "horizontal"
|
|
6772
|
+
});
|
|
6773
|
+
return slots;
|
|
6774
|
+
}
|
|
6775
|
+
for (let i = 0; i <= links.length; i++) {
|
|
6776
|
+
let top;
|
|
6777
|
+
if (i === 0) {
|
|
6778
|
+
top = links[0].getBoundingClientRect().top - barThickness / 2;
|
|
6779
|
+
} else if (i === links.length) {
|
|
6780
|
+
const last = links[links.length - 1].getBoundingClientRect();
|
|
6781
|
+
top = last.bottom - barThickness / 2;
|
|
6782
|
+
} else {
|
|
6783
|
+
const prev = links[i - 1].getBoundingClientRect();
|
|
6784
|
+
const next = links[i].getBoundingClientRect();
|
|
6785
|
+
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
6786
|
+
}
|
|
6787
|
+
const widthRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
6788
|
+
slots.push({
|
|
6789
|
+
insertIndex: i,
|
|
6790
|
+
columnIndex,
|
|
6791
|
+
left: widthRef.left,
|
|
6792
|
+
top,
|
|
6793
|
+
width: Math.max(widthRef.width, colRect.width * 0.8),
|
|
6794
|
+
height: barThickness,
|
|
6795
|
+
direction: "horizontal"
|
|
6796
|
+
});
|
|
6797
|
+
}
|
|
6798
|
+
return slots;
|
|
6799
|
+
}
|
|
6800
|
+
function buildColumnDropSlots() {
|
|
6801
|
+
const columns = listFooterColumns();
|
|
6802
|
+
const slots = [];
|
|
6803
|
+
const barThickness = 3;
|
|
6804
|
+
if (columns.length === 0) return slots;
|
|
6805
|
+
for (let i = 0; i <= columns.length; i++) {
|
|
6806
|
+
let left;
|
|
6807
|
+
let height;
|
|
6808
|
+
let top;
|
|
6809
|
+
if (i === 0) {
|
|
6810
|
+
const first = columns[0].getBoundingClientRect();
|
|
6811
|
+
left = first.left - barThickness / 2;
|
|
6812
|
+
top = first.top;
|
|
6813
|
+
height = first.height;
|
|
6814
|
+
} else if (i === columns.length) {
|
|
6815
|
+
const last = columns[columns.length - 1].getBoundingClientRect();
|
|
6816
|
+
left = last.right - barThickness / 2;
|
|
6817
|
+
top = last.top;
|
|
6818
|
+
height = last.height;
|
|
6819
|
+
} else {
|
|
6820
|
+
const prev = columns[i - 1].getBoundingClientRect();
|
|
6821
|
+
const next = columns[i].getBoundingClientRect();
|
|
6822
|
+
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
6823
|
+
top = Math.min(prev.top, next.top);
|
|
6824
|
+
height = Math.max(prev.bottom, next.bottom) - top;
|
|
6825
|
+
}
|
|
6826
|
+
slots.push({
|
|
6827
|
+
insertIndex: i,
|
|
6828
|
+
columnIndex: i,
|
|
6829
|
+
left,
|
|
6830
|
+
top,
|
|
6831
|
+
width: barThickness,
|
|
6832
|
+
height: Math.max(height, 24),
|
|
6833
|
+
direction: "vertical"
|
|
6834
|
+
});
|
|
6835
|
+
}
|
|
6836
|
+
return slots;
|
|
6837
|
+
}
|
|
6838
|
+
function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
|
|
6839
|
+
const columns = listFooterColumns();
|
|
6840
|
+
let best = null;
|
|
6841
|
+
for (let c = 0; c < columns.length; c++) {
|
|
6842
|
+
const col = columns[c];
|
|
6843
|
+
const colRect = col.getBoundingClientRect();
|
|
6844
|
+
const inColX = clientX >= colRect.left - 24 && clientX <= colRect.right + 24;
|
|
6845
|
+
if (!inColX) continue;
|
|
6846
|
+
const slots = buildLinkDropSlots(col, c).filter((slot) => {
|
|
6847
|
+
const links = listFooterLinksInColumn(col);
|
|
6848
|
+
const fromIdx = links.findIndex(
|
|
6849
|
+
(el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey
|
|
6850
|
+
);
|
|
6851
|
+
if (fromIdx < 0) return true;
|
|
6852
|
+
if (c === findColumnIndexForKey(draggedHrefKey) && (slot.insertIndex === fromIdx || slot.insertIndex === fromIdx + 1)) {
|
|
6853
|
+
return true;
|
|
6854
|
+
}
|
|
6855
|
+
return true;
|
|
6856
|
+
});
|
|
6857
|
+
for (const slot of slots) {
|
|
6858
|
+
const cy = slot.top + slot.height / 2;
|
|
6859
|
+
const dist = Math.abs(clientY - cy) + (inColX ? 0 : 1e3);
|
|
6860
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
6861
|
+
}
|
|
6862
|
+
}
|
|
6863
|
+
return best?.slot ?? null;
|
|
6864
|
+
}
|
|
6865
|
+
function findColumnIndexForKey(hrefKey) {
|
|
6866
|
+
const order = getFooterOrderFromDom();
|
|
6867
|
+
for (let c = 0; c < order.length; c++) {
|
|
6868
|
+
if (order[c].includes(hrefKey)) return c;
|
|
6869
|
+
}
|
|
6870
|
+
return -1;
|
|
6871
|
+
}
|
|
6872
|
+
function hitTestColumnDropSlot(clientX, _clientY) {
|
|
6873
|
+
const slots = buildColumnDropSlots();
|
|
6874
|
+
let best = null;
|
|
6875
|
+
for (const slot of slots) {
|
|
6876
|
+
const cx2 = slot.left + slot.width / 2;
|
|
6877
|
+
const dist = Math.abs(clientX - cx2);
|
|
6878
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
6879
|
+
}
|
|
6880
|
+
return best?.slot ?? null;
|
|
6881
|
+
}
|
|
6882
|
+
|
|
6549
6883
|
// src/lib/carousel.ts
|
|
6550
6884
|
import { useEffect as useEffect7, useState as useState6 } from "react";
|
|
6551
6885
|
var CAROUSEL_ATTR = "data-ohw-carousel";
|
|
@@ -6674,8 +7008,50 @@ function NavbarContainerChrome({
|
|
|
6674
7008
|
);
|
|
6675
7009
|
}
|
|
6676
7010
|
|
|
6677
|
-
// src/ui/
|
|
7011
|
+
// src/ui/drop-indicator.tsx
|
|
7012
|
+
import * as React9 from "react";
|
|
6678
7013
|
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
7014
|
+
var dropIndicatorVariants = cva(
|
|
7015
|
+
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7016
|
+
{
|
|
7017
|
+
variants: {
|
|
7018
|
+
direction: {
|
|
7019
|
+
vertical: "h-6 w-[3px]",
|
|
7020
|
+
horizontal: "h-[3px] w-[200px]"
|
|
7021
|
+
},
|
|
7022
|
+
state: {
|
|
7023
|
+
default: "opacity-0",
|
|
7024
|
+
hover: "opacity-100",
|
|
7025
|
+
dragIdle: "opacity-40",
|
|
7026
|
+
dragActive: "opacity-100"
|
|
7027
|
+
}
|
|
7028
|
+
},
|
|
7029
|
+
defaultVariants: {
|
|
7030
|
+
direction: "vertical",
|
|
7031
|
+
state: "default"
|
|
7032
|
+
}
|
|
7033
|
+
}
|
|
7034
|
+
);
|
|
7035
|
+
var DropIndicator = React9.forwardRef(
|
|
7036
|
+
({ className, direction, state, ...props }, ref) => {
|
|
7037
|
+
return /* @__PURE__ */ jsx23(
|
|
7038
|
+
"div",
|
|
7039
|
+
{
|
|
7040
|
+
ref,
|
|
7041
|
+
"data-slot": "drop-indicator",
|
|
7042
|
+
"data-direction": direction ?? "vertical",
|
|
7043
|
+
"data-state": state ?? "default",
|
|
7044
|
+
"aria-hidden": "true",
|
|
7045
|
+
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
7046
|
+
...props
|
|
7047
|
+
}
|
|
7048
|
+
);
|
|
7049
|
+
}
|
|
7050
|
+
);
|
|
7051
|
+
DropIndicator.displayName = "DropIndicator";
|
|
7052
|
+
|
|
7053
|
+
// src/ui/badge.tsx
|
|
7054
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
6679
7055
|
var badgeVariants = cva(
|
|
6680
7056
|
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
6681
7057
|
{
|
|
@@ -6693,12 +7069,12 @@ var badgeVariants = cva(
|
|
|
6693
7069
|
}
|
|
6694
7070
|
);
|
|
6695
7071
|
function Badge({ className, variant, ...props }) {
|
|
6696
|
-
return /* @__PURE__ */
|
|
7072
|
+
return /* @__PURE__ */ jsx24("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
6697
7073
|
}
|
|
6698
7074
|
|
|
6699
7075
|
// src/OhhwellsBridge.tsx
|
|
6700
7076
|
import { Link as Link2 } from "lucide-react";
|
|
6701
|
-
import { Fragment as Fragment5, jsx as
|
|
7077
|
+
import { Fragment as Fragment5, jsx as jsx25, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
6702
7078
|
var PRIMARY2 = "#0885FE";
|
|
6703
7079
|
var IMAGE_FADE_MS = 300;
|
|
6704
7080
|
function runOpacityFade(el, onDone) {
|
|
@@ -6877,7 +7253,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
6877
7253
|
const root = createRoot(container);
|
|
6878
7254
|
flushSync(() => {
|
|
6879
7255
|
root.render(
|
|
6880
|
-
/* @__PURE__ */
|
|
7256
|
+
/* @__PURE__ */ jsx25(
|
|
6881
7257
|
SchedulingWidget,
|
|
6882
7258
|
{
|
|
6883
7259
|
notifyOnConnect,
|
|
@@ -6939,7 +7315,7 @@ function isDragHandleDisabled(el) {
|
|
|
6939
7315
|
return raw === "true" || raw === "";
|
|
6940
7316
|
});
|
|
6941
7317
|
}
|
|
6942
|
-
function collectEditableNodes() {
|
|
7318
|
+
function collectEditableNodes(extraContent) {
|
|
6943
7319
|
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
6944
7320
|
if (el.dataset.ohwEditable === "image") {
|
|
6945
7321
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -6967,6 +7343,14 @@ function collectEditableNodes() {
|
|
|
6967
7343
|
if (!key) return;
|
|
6968
7344
|
nodes.push({ key, type: "link", text: getLinkHref2(el) });
|
|
6969
7345
|
});
|
|
7346
|
+
if (extraContent) {
|
|
7347
|
+
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
7348
|
+
const text = extraContent[key];
|
|
7349
|
+
if (typeof text === "string" && text.length > 0) {
|
|
7350
|
+
nodes.push({ key, type: "meta", text });
|
|
7351
|
+
}
|
|
7352
|
+
}
|
|
7353
|
+
}
|
|
6970
7354
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
6971
7355
|
const key = el.dataset.ohwKey ?? "";
|
|
6972
7356
|
const video = getVideoEl(el);
|
|
@@ -7065,6 +7449,29 @@ function getHrefKeyFromElement(el) {
|
|
|
7065
7449
|
if (!key) return null;
|
|
7066
7450
|
return { anchor, key };
|
|
7067
7451
|
}
|
|
7452
|
+
function disableNativeHrefDrag(el) {
|
|
7453
|
+
if (el.draggable) el.draggable = false;
|
|
7454
|
+
if (el.getAttribute("draggable") !== "false") {
|
|
7455
|
+
el.setAttribute("draggable", "false");
|
|
7456
|
+
}
|
|
7457
|
+
}
|
|
7458
|
+
function clearTextSelection() {
|
|
7459
|
+
const sel = window.getSelection();
|
|
7460
|
+
if (sel && !sel.isCollapsed) sel.removeAllRanges();
|
|
7461
|
+
}
|
|
7462
|
+
function armFooterPressDrag() {
|
|
7463
|
+
document.documentElement.setAttribute("data-ohw-footer-press-drag", "");
|
|
7464
|
+
}
|
|
7465
|
+
function lockFooterDuringDrag() {
|
|
7466
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7467
|
+
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
7468
|
+
clearTextSelection();
|
|
7469
|
+
}
|
|
7470
|
+
function unlockFooterDragInteraction() {
|
|
7471
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7472
|
+
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7473
|
+
clearTextSelection();
|
|
7474
|
+
}
|
|
7068
7475
|
function isNavbarButton2(el) {
|
|
7069
7476
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
7070
7477
|
}
|
|
@@ -7378,7 +7785,7 @@ function EditGlowChrome({
|
|
|
7378
7785
|
zIndex: 2147483646
|
|
7379
7786
|
},
|
|
7380
7787
|
children: [
|
|
7381
|
-
/* @__PURE__ */
|
|
7788
|
+
/* @__PURE__ */ jsx25(
|
|
7382
7789
|
"div",
|
|
7383
7790
|
{
|
|
7384
7791
|
style: {
|
|
@@ -7391,7 +7798,7 @@ function EditGlowChrome({
|
|
|
7391
7798
|
}
|
|
7392
7799
|
}
|
|
7393
7800
|
),
|
|
7394
|
-
reorderHrefKey && /* @__PURE__ */
|
|
7801
|
+
reorderHrefKey && /* @__PURE__ */ jsx25(
|
|
7395
7802
|
"div",
|
|
7396
7803
|
{
|
|
7397
7804
|
"data-ohw-drag-handle-container": "",
|
|
@@ -7403,7 +7810,7 @@ function EditGlowChrome({
|
|
|
7403
7810
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
7404
7811
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
7405
7812
|
},
|
|
7406
|
-
children: /* @__PURE__ */
|
|
7813
|
+
children: /* @__PURE__ */ jsx25(
|
|
7407
7814
|
DragHandle,
|
|
7408
7815
|
{
|
|
7409
7816
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -7507,7 +7914,7 @@ function FloatingToolbar({
|
|
|
7507
7914
|
onEditLink
|
|
7508
7915
|
}) {
|
|
7509
7916
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
7510
|
-
return /* @__PURE__ */
|
|
7917
|
+
return /* @__PURE__ */ jsx25(
|
|
7511
7918
|
"div",
|
|
7512
7919
|
{
|
|
7513
7920
|
ref: elRef,
|
|
@@ -7529,11 +7936,11 @@ function FloatingToolbar({
|
|
|
7529
7936
|
pointerEvents: "auto"
|
|
7530
7937
|
},
|
|
7531
7938
|
children: /* @__PURE__ */ jsxs14(CustomToolbar, { children: [
|
|
7532
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs14(
|
|
7533
|
-
gi > 0 && /* @__PURE__ */
|
|
7939
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs14(React10.Fragment, { children: [
|
|
7940
|
+
gi > 0 && /* @__PURE__ */ jsx25(CustomToolbarDivider, {}),
|
|
7534
7941
|
btns.map((btn) => {
|
|
7535
7942
|
const isActive = activeCommands.has(btn.cmd);
|
|
7536
|
-
return /* @__PURE__ */
|
|
7943
|
+
return /* @__PURE__ */ jsx25(
|
|
7537
7944
|
CustomToolbarButton,
|
|
7538
7945
|
{
|
|
7539
7946
|
title: btn.title,
|
|
@@ -7542,7 +7949,7 @@ function FloatingToolbar({
|
|
|
7542
7949
|
e.preventDefault();
|
|
7543
7950
|
onCommand(btn.cmd);
|
|
7544
7951
|
},
|
|
7545
|
-
children: /* @__PURE__ */
|
|
7952
|
+
children: /* @__PURE__ */ jsx25(
|
|
7546
7953
|
"svg",
|
|
7547
7954
|
{
|
|
7548
7955
|
width: "16",
|
|
@@ -7563,7 +7970,7 @@ function FloatingToolbar({
|
|
|
7563
7970
|
);
|
|
7564
7971
|
})
|
|
7565
7972
|
] }, gi)),
|
|
7566
|
-
showEditLink ? /* @__PURE__ */
|
|
7973
|
+
showEditLink ? /* @__PURE__ */ jsx25(
|
|
7567
7974
|
CustomToolbarButton,
|
|
7568
7975
|
{
|
|
7569
7976
|
type: "button",
|
|
@@ -7577,7 +7984,7 @@ function FloatingToolbar({
|
|
|
7577
7984
|
e.preventDefault();
|
|
7578
7985
|
e.stopPropagation();
|
|
7579
7986
|
},
|
|
7580
|
-
children: /* @__PURE__ */
|
|
7987
|
+
children: /* @__PURE__ */ jsx25(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
7581
7988
|
}
|
|
7582
7989
|
) : null
|
|
7583
7990
|
] })
|
|
@@ -7594,7 +8001,7 @@ function StateToggle({
|
|
|
7594
8001
|
states,
|
|
7595
8002
|
onStateChange
|
|
7596
8003
|
}) {
|
|
7597
|
-
return /* @__PURE__ */
|
|
8004
|
+
return /* @__PURE__ */ jsx25(
|
|
7598
8005
|
ToggleGroup,
|
|
7599
8006
|
{
|
|
7600
8007
|
"data-ohw-state-toggle": "",
|
|
@@ -7608,7 +8015,7 @@ function StateToggle({
|
|
|
7608
8015
|
left: rect.right - 8,
|
|
7609
8016
|
transform: "translateX(-100%)"
|
|
7610
8017
|
},
|
|
7611
|
-
children: states.map((state) => /* @__PURE__ */
|
|
8018
|
+
children: states.map((state) => /* @__PURE__ */ jsx25(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
7612
8019
|
}
|
|
7613
8020
|
);
|
|
7614
8021
|
}
|
|
@@ -7732,7 +8139,15 @@ function OhhwellsBridge() {
|
|
|
7732
8139
|
const [hoveredItemRect, setHoveredItemRect] = useState7(null);
|
|
7733
8140
|
const siblingHintElRef = useRef5(null);
|
|
7734
8141
|
const [siblingHintRect, setSiblingHintRect] = useState7(null);
|
|
8142
|
+
const [siblingHintRects, setSiblingHintRects] = useState7([]);
|
|
7735
8143
|
const [isItemDragging, setIsItemDragging] = useState7(false);
|
|
8144
|
+
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState7(false);
|
|
8145
|
+
const footerDragRef = useRef5(null);
|
|
8146
|
+
const [footerDropSlots, setFooterDropSlots] = useState7([]);
|
|
8147
|
+
const [activeFooterDropIndex, setActiveFooterDropIndex] = useState7(null);
|
|
8148
|
+
const [draggedItemRect, setDraggedItemRect] = useState7(null);
|
|
8149
|
+
const footerPointerDragRef = useRef5(null);
|
|
8150
|
+
const suppressNextClickRef = useRef5(false);
|
|
7736
8151
|
const [linkPopover, setLinkPopover] = useState7(null);
|
|
7737
8152
|
const linkPopoverSessionRef = useRef5(null);
|
|
7738
8153
|
const addNavAfterAnchorRef = useRef5(null);
|
|
@@ -7896,8 +8311,10 @@ function OhhwellsBridge() {
|
|
|
7896
8311
|
selectedElRef.current = null;
|
|
7897
8312
|
setReorderHrefKey(null);
|
|
7898
8313
|
setReorderDragDisabled(false);
|
|
8314
|
+
setIsFooterFrameSelection(false);
|
|
7899
8315
|
siblingHintElRef.current = null;
|
|
7900
8316
|
setSiblingHintRect(null);
|
|
8317
|
+
setSiblingHintRects([]);
|
|
7901
8318
|
setIsItemDragging(false);
|
|
7902
8319
|
hoveredNavContainerRef.current = null;
|
|
7903
8320
|
setHoveredNavContainerRect(null);
|
|
@@ -7954,90 +8371,345 @@ function OhhwellsBridge() {
|
|
|
7954
8371
|
intent: "add-nav"
|
|
7955
8372
|
});
|
|
7956
8373
|
}, []);
|
|
7957
|
-
const
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
8374
|
+
const clearFooterDragVisuals = useCallback4(() => {
|
|
8375
|
+
footerDragRef.current = null;
|
|
8376
|
+
setSiblingHintRects([]);
|
|
8377
|
+
setFooterDropSlots([]);
|
|
8378
|
+
setActiveFooterDropIndex(null);
|
|
8379
|
+
setDraggedItemRect(null);
|
|
7963
8380
|
setIsItemDragging(false);
|
|
8381
|
+
unlockFooterDragInteraction();
|
|
7964
8382
|
}, []);
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
if (
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
clearHrefKeyHover(anchor);
|
|
7972
|
-
hoveredNavContainerRef.current = null;
|
|
7973
|
-
setHoveredNavContainerRect(null);
|
|
7974
|
-
setHoveredItemRect(null);
|
|
7975
|
-
hoveredItemElRef.current = null;
|
|
7976
|
-
siblingHintElRef.current = null;
|
|
7977
|
-
setSiblingHintRect(null);
|
|
7978
|
-
setIsItemDragging(false);
|
|
7979
|
-
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
7980
|
-
setReorderHrefKey(key);
|
|
7981
|
-
setReorderDragDisabled(disabled);
|
|
7982
|
-
setToolbarVariant("link-action");
|
|
7983
|
-
setToolbarRect(anchor.getBoundingClientRect());
|
|
7984
|
-
setToolbarShowEditLink(false);
|
|
7985
|
-
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7986
|
-
}, [deactivate]);
|
|
7987
|
-
const selectFrame = useCallback4((el) => {
|
|
7988
|
-
if (!isNavigationContainer(el)) return;
|
|
7989
|
-
if (activeElRef.current) deactivate();
|
|
7990
|
-
selectedElRef.current = el;
|
|
7991
|
-
clearHrefKeyHover(el);
|
|
7992
|
-
hoveredNavContainerRef.current = null;
|
|
7993
|
-
setHoveredNavContainerRect(null);
|
|
7994
|
-
setHoveredItemRect(null);
|
|
7995
|
-
hoveredItemElRef.current = null;
|
|
7996
|
-
siblingHintElRef.current = null;
|
|
7997
|
-
setSiblingHintRect(null);
|
|
7998
|
-
setIsItemDragging(false);
|
|
7999
|
-
setReorderHrefKey(null);
|
|
8000
|
-
setReorderDragDisabled(false);
|
|
8001
|
-
setToolbarVariant("select-frame");
|
|
8002
|
-
setToolbarRect(el.getBoundingClientRect());
|
|
8003
|
-
setToolbarShowEditLink(false);
|
|
8004
|
-
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8005
|
-
}, [deactivate]);
|
|
8006
|
-
const activate = useCallback4((el, options) => {
|
|
8007
|
-
if (activeElRef.current === el) return;
|
|
8008
|
-
selectedElRef.current = null;
|
|
8009
|
-
deactivate();
|
|
8010
|
-
if (hoveredImageRef.current) {
|
|
8011
|
-
hoveredImageRef.current = null;
|
|
8012
|
-
setMediaHover(null);
|
|
8383
|
+
const refreshFooterDragVisuals = useCallback4((session, activeSlot, clientX, clientY) => {
|
|
8384
|
+
const dragged = session.draggedEl;
|
|
8385
|
+
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
8386
|
+
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
8387
|
+
session.lastClientX = clientX;
|
|
8388
|
+
session.lastClientY = clientY;
|
|
8013
8389
|
}
|
|
8014
|
-
|
|
8015
|
-
|
|
8016
|
-
|
|
8017
|
-
|
|
8018
|
-
|
|
8019
|
-
|
|
8020
|
-
|
|
8021
|
-
|
|
8022
|
-
|
|
8023
|
-
|
|
8024
|
-
|
|
8025
|
-
|
|
8390
|
+
session.activeSlot = activeSlot;
|
|
8391
|
+
if (session.kind === "link") {
|
|
8392
|
+
const columns2 = listFooterColumns();
|
|
8393
|
+
const focusCols = /* @__PURE__ */ new Set([session.sourceColumnIndex]);
|
|
8394
|
+
if (activeSlot) focusCols.add(activeSlot.columnIndex);
|
|
8395
|
+
const siblingRects = [];
|
|
8396
|
+
columns2.forEach((col, i) => {
|
|
8397
|
+
if (!focusCols.has(i)) return;
|
|
8398
|
+
for (const link of listFooterLinksInColumn(col)) {
|
|
8399
|
+
if (link === dragged) continue;
|
|
8400
|
+
siblingRects.push(link.getBoundingClientRect());
|
|
8401
|
+
}
|
|
8402
|
+
});
|
|
8403
|
+
setSiblingHintRects(siblingRects);
|
|
8404
|
+
const slots2 = [];
|
|
8405
|
+
columns2.forEach((col, i) => {
|
|
8406
|
+
slots2.push(...buildLinkDropSlots(col, i));
|
|
8407
|
+
});
|
|
8408
|
+
setFooterDropSlots(slots2);
|
|
8409
|
+
const activeIdx2 = activeSlot ? slots2.findIndex((s) => s.columnIndex === activeSlot.columnIndex && s.insertIndex === activeSlot.insertIndex) : -1;
|
|
8410
|
+
setActiveFooterDropIndex(activeIdx2 >= 0 ? activeIdx2 : null);
|
|
8411
|
+
return;
|
|
8412
|
+
}
|
|
8413
|
+
const columns = listFooterColumns();
|
|
8414
|
+
setSiblingHintRects(columns.filter((col) => col !== dragged).map((col) => col.getBoundingClientRect()));
|
|
8415
|
+
const slots = buildColumnDropSlots();
|
|
8416
|
+
setFooterDropSlots(slots);
|
|
8417
|
+
const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
8418
|
+
setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
8419
|
+
}, []);
|
|
8420
|
+
const refreshFooterDragVisualsRef = useRef5(refreshFooterDragVisuals);
|
|
8421
|
+
refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
|
|
8422
|
+
const commitFooterDragRef = useRef5(() => {
|
|
8423
|
+
});
|
|
8424
|
+
const beginFooterDragRef = useRef5(() => {
|
|
8425
|
+
});
|
|
8426
|
+
const beginFooterDrag = useCallback4(
|
|
8427
|
+
(session) => {
|
|
8428
|
+
const rect = session.draggedEl.getBoundingClientRect();
|
|
8429
|
+
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
8430
|
+
session.lastClientY = session.lastClientY || rect.top + rect.height / 2;
|
|
8431
|
+
session.activeSlot = session.activeSlot ?? null;
|
|
8432
|
+
footerDragRef.current = session;
|
|
8433
|
+
setIsItemDragging(true);
|
|
8434
|
+
lockFooterDuringDrag();
|
|
8435
|
+
siblingHintElRef.current = null;
|
|
8436
|
+
setSiblingHintRect(null);
|
|
8437
|
+
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
8438
|
+
setToolbarRect(rect);
|
|
8439
|
+
}
|
|
8440
|
+
const initialSlot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
8441
|
+
refreshFooterDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
8442
|
+
},
|
|
8443
|
+
[refreshFooterDragVisuals]
|
|
8444
|
+
);
|
|
8445
|
+
beginFooterDragRef.current = beginFooterDrag;
|
|
8446
|
+
const commitFooterDrag = useCallback4(
|
|
8447
|
+
(clientX, clientY) => {
|
|
8448
|
+
const session = footerDragRef.current;
|
|
8449
|
+
if (!session) {
|
|
8450
|
+
clearFooterDragVisuals();
|
|
8451
|
+
return;
|
|
8452
|
+
}
|
|
8453
|
+
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
8454
|
+
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
8455
|
+
let nextOrder = null;
|
|
8456
|
+
const slot = session.activeSlot ?? (session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(x, y, session.hrefKey) : session.kind === "column" ? hitTestColumnDropSlot(x, y) : null);
|
|
8457
|
+
if (session.kind === "link" && session.hrefKey && slot) {
|
|
8458
|
+
nextOrder = planFooterLinkMove(session.hrefKey, slot.columnIndex, slot.insertIndex);
|
|
8459
|
+
} else if (session.kind === "column" && slot) {
|
|
8460
|
+
nextOrder = planFooterColumnMove(session.sourceColumnIndex, slot.insertIndex);
|
|
8461
|
+
}
|
|
8462
|
+
const wasSelected = session.wasSelected;
|
|
8463
|
+
const draggedEl = session.draggedEl;
|
|
8464
|
+
const hrefKey = session.hrefKey;
|
|
8465
|
+
let movedColumnIndex = null;
|
|
8466
|
+
if (session.kind === "column" && slot && nextOrder) {
|
|
8467
|
+
let adjusted = slot.insertIndex;
|
|
8468
|
+
if (session.sourceColumnIndex < slot.insertIndex) adjusted -= 1;
|
|
8469
|
+
movedColumnIndex = Math.max(0, Math.min(adjusted, nextOrder.length - 1));
|
|
8470
|
+
}
|
|
8471
|
+
clearFooterDragVisuals();
|
|
8472
|
+
if (nextOrder) {
|
|
8473
|
+
const orderJson = JSON.stringify(nextOrder);
|
|
8474
|
+
editContentRef.current = {
|
|
8475
|
+
...editContentRef.current,
|
|
8476
|
+
[FOOTER_ORDER_KEY]: orderJson
|
|
8477
|
+
};
|
|
8478
|
+
applyFooterOrder(nextOrder);
|
|
8479
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
8480
|
+
requestAnimationFrame(() => {
|
|
8481
|
+
if (editContentRef.current[FOOTER_ORDER_KEY] === orderJson) {
|
|
8482
|
+
applyFooterOrder(nextOrder);
|
|
8483
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
8484
|
+
}
|
|
8485
|
+
});
|
|
8486
|
+
postToParentRef.current({
|
|
8487
|
+
type: "ow:change",
|
|
8488
|
+
nodes: [{ key: FOOTER_ORDER_KEY, text: orderJson }]
|
|
8489
|
+
});
|
|
8490
|
+
}
|
|
8491
|
+
const still = (hrefKey ? document.querySelector(`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`) : null) ?? (movedColumnIndex !== null ? listFooterColumns()[movedColumnIndex] ?? null : null) ?? (document.body.contains(draggedEl) ? draggedEl : null);
|
|
8492
|
+
if (still && isNavigationItem(still)) {
|
|
8493
|
+
selectRef.current(still);
|
|
8494
|
+
} else if (still && isNavigationContainer(still)) {
|
|
8495
|
+
selectFrameRef.current(still);
|
|
8496
|
+
} else if (wasSelected) {
|
|
8497
|
+
deselectRef.current();
|
|
8498
|
+
}
|
|
8499
|
+
},
|
|
8500
|
+
[clearFooterDragVisuals]
|
|
8501
|
+
);
|
|
8502
|
+
commitFooterDragRef.current = commitFooterDrag;
|
|
8503
|
+
const startFooterLinkDrag = useCallback4(
|
|
8504
|
+
(anchor, clientX, clientY, wasSelected) => {
|
|
8505
|
+
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
8506
|
+
if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
|
|
8507
|
+
const column = findFooterColumnForLink(anchor);
|
|
8508
|
+
const columns = listFooterColumns();
|
|
8509
|
+
beginFooterDrag({
|
|
8510
|
+
kind: "link",
|
|
8511
|
+
hrefKey,
|
|
8512
|
+
columnEl: column,
|
|
8513
|
+
sourceColumnIndex: column ? columns.indexOf(column) : 0,
|
|
8514
|
+
wasSelected,
|
|
8515
|
+
draggedEl: anchor,
|
|
8516
|
+
lastClientX: clientX,
|
|
8517
|
+
lastClientY: clientY,
|
|
8518
|
+
activeSlot: null
|
|
8519
|
+
});
|
|
8520
|
+
return true;
|
|
8521
|
+
},
|
|
8522
|
+
[beginFooterDrag]
|
|
8523
|
+
);
|
|
8524
|
+
const startFooterColumnDrag = useCallback4(
|
|
8525
|
+
(columnEl, clientX, clientY, wasSelected) => {
|
|
8526
|
+
const columns = listFooterColumns();
|
|
8527
|
+
const idx = columns.indexOf(columnEl);
|
|
8528
|
+
if (idx < 0) return false;
|
|
8529
|
+
beginFooterDrag({
|
|
8530
|
+
kind: "column",
|
|
8531
|
+
hrefKey: null,
|
|
8532
|
+
columnEl,
|
|
8533
|
+
sourceColumnIndex: idx,
|
|
8534
|
+
wasSelected,
|
|
8535
|
+
draggedEl: columnEl,
|
|
8536
|
+
lastClientX: clientX,
|
|
8537
|
+
lastClientY: clientY,
|
|
8538
|
+
activeSlot: null
|
|
8539
|
+
});
|
|
8540
|
+
return true;
|
|
8541
|
+
},
|
|
8542
|
+
[beginFooterDrag]
|
|
8543
|
+
);
|
|
8544
|
+
const handleItemDragStart = useCallback4(
|
|
8545
|
+
(e) => {
|
|
8546
|
+
const selected = selectedElRef.current;
|
|
8547
|
+
if (!selected) {
|
|
8548
|
+
setIsItemDragging(true);
|
|
8549
|
+
return;
|
|
8550
|
+
}
|
|
8551
|
+
const clientX = e?.clientX ?? selected.getBoundingClientRect().left + 8;
|
|
8552
|
+
const clientY = e?.clientY ?? selected.getBoundingClientRect().top + 8;
|
|
8553
|
+
if (startFooterLinkDrag(selected, clientX, clientY, true)) return;
|
|
8554
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
8555
|
+
if (startFooterColumnDrag(selected, clientX, clientY, true)) return;
|
|
8556
|
+
}
|
|
8557
|
+
siblingHintElRef.current = null;
|
|
8558
|
+
setSiblingHintRect(null);
|
|
8559
|
+
setIsItemDragging(true);
|
|
8560
|
+
},
|
|
8561
|
+
[startFooterColumnDrag, startFooterLinkDrag]
|
|
8562
|
+
);
|
|
8563
|
+
const handleItemDragEnd = useCallback4(
|
|
8564
|
+
(e) => {
|
|
8565
|
+
if (footerDragRef.current) {
|
|
8566
|
+
const x = e?.clientX;
|
|
8567
|
+
const y = e?.clientY;
|
|
8568
|
+
if (typeof x === "number" && typeof y === "number" && (x !== 0 || y !== 0)) {
|
|
8569
|
+
commitFooterDrag(x, y);
|
|
8570
|
+
} else {
|
|
8571
|
+
commitFooterDrag();
|
|
8572
|
+
}
|
|
8573
|
+
return;
|
|
8574
|
+
}
|
|
8575
|
+
setIsItemDragging(false);
|
|
8576
|
+
},
|
|
8577
|
+
[commitFooterDrag]
|
|
8578
|
+
);
|
|
8579
|
+
const handleItemChromePointerDown = useCallback4((e) => {
|
|
8580
|
+
if (e.button !== 0) return;
|
|
8581
|
+
const selected = selectedElRef.current;
|
|
8582
|
+
if (!selected) return;
|
|
8583
|
+
armFooterPressDrag();
|
|
8584
|
+
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
8585
|
+
if (hrefKey && isFooterHrefKey(hrefKey)) {
|
|
8586
|
+
footerPointerDragRef.current = {
|
|
8587
|
+
el: selected,
|
|
8588
|
+
kind: "link",
|
|
8589
|
+
startX: e.clientX,
|
|
8590
|
+
startY: e.clientY,
|
|
8591
|
+
pointerId: e.pointerId,
|
|
8592
|
+
wasSelected: true,
|
|
8593
|
+
started: false
|
|
8594
|
+
};
|
|
8595
|
+
return;
|
|
8596
|
+
}
|
|
8597
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
8598
|
+
footerPointerDragRef.current = {
|
|
8599
|
+
el: selected,
|
|
8600
|
+
kind: "column",
|
|
8601
|
+
startX: e.clientX,
|
|
8602
|
+
startY: e.clientY,
|
|
8603
|
+
pointerId: e.pointerId,
|
|
8604
|
+
wasSelected: true,
|
|
8605
|
+
started: false
|
|
8606
|
+
};
|
|
8607
|
+
}
|
|
8608
|
+
}, []);
|
|
8609
|
+
const handleItemChromeClick = useCallback4((clientX, clientY) => {
|
|
8610
|
+
if (suppressNextClickRef.current) {
|
|
8611
|
+
suppressNextClickRef.current = false;
|
|
8612
|
+
return;
|
|
8026
8613
|
}
|
|
8027
|
-
|
|
8028
|
-
|
|
8029
|
-
|
|
8614
|
+
const selected = selectedElRef.current;
|
|
8615
|
+
if (!selected || !isNavigationItem(selected)) return;
|
|
8616
|
+
const editable = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
8617
|
+
if (!editable) return;
|
|
8618
|
+
activateRef.current(editable, { caretX: clientX, caretY: clientY });
|
|
8619
|
+
}, []);
|
|
8620
|
+
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
8621
|
+
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
8622
|
+
const select = useCallback4(
|
|
8623
|
+
(anchor) => {
|
|
8624
|
+
if (!isNavigationItem(anchor)) return;
|
|
8625
|
+
if (activeElRef.current) deactivate();
|
|
8626
|
+
selectedElRef.current = anchor;
|
|
8627
|
+
clearHrefKeyHover(anchor);
|
|
8628
|
+
hoveredNavContainerRef.current = null;
|
|
8629
|
+
setHoveredNavContainerRect(null);
|
|
8630
|
+
setHoveredItemRect(null);
|
|
8631
|
+
hoveredItemElRef.current = null;
|
|
8632
|
+
siblingHintElRef.current = null;
|
|
8633
|
+
setSiblingHintRect(null);
|
|
8634
|
+
setSiblingHintRects([]);
|
|
8635
|
+
setIsItemDragging(false);
|
|
8636
|
+
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
8637
|
+
setReorderHrefKey(key);
|
|
8638
|
+
setReorderDragDisabled(disabled);
|
|
8639
|
+
setIsFooterFrameSelection(false);
|
|
8640
|
+
setToolbarVariant("link-action");
|
|
8641
|
+
setToolbarRect(anchor.getBoundingClientRect());
|
|
8642
|
+
setToolbarShowEditLink(false);
|
|
8643
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8644
|
+
},
|
|
8645
|
+
[deactivate]
|
|
8646
|
+
);
|
|
8647
|
+
const selectFrame = useCallback4(
|
|
8648
|
+
(el) => {
|
|
8649
|
+
if (!isNavigationContainer(el)) return;
|
|
8650
|
+
if (activeElRef.current) deactivate();
|
|
8651
|
+
const isFooterColumn = el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el));
|
|
8652
|
+
selectedElRef.current = el;
|
|
8653
|
+
clearHrefKeyHover(el);
|
|
8654
|
+
hoveredNavContainerRef.current = null;
|
|
8655
|
+
setHoveredNavContainerRect(null);
|
|
8656
|
+
setHoveredItemRect(null);
|
|
8657
|
+
hoveredItemElRef.current = null;
|
|
8658
|
+
siblingHintElRef.current = null;
|
|
8659
|
+
setSiblingHintRect(null);
|
|
8660
|
+
setSiblingHintRects(
|
|
8661
|
+
isFooterColumn ? listFooterColumns().filter((column) => column !== el).map((column) => column.getBoundingClientRect()) : []
|
|
8662
|
+
);
|
|
8663
|
+
setIsItemDragging(false);
|
|
8030
8664
|
setReorderHrefKey(null);
|
|
8031
8665
|
setReorderDragDisabled(false);
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
|
|
8666
|
+
setIsFooterFrameSelection(isFooterColumn);
|
|
8667
|
+
setToolbarVariant("select-frame");
|
|
8668
|
+
setToolbarRect(el.getBoundingClientRect());
|
|
8669
|
+
setToolbarShowEditLink(false);
|
|
8670
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
8671
|
+
},
|
|
8672
|
+
[deactivate]
|
|
8673
|
+
);
|
|
8674
|
+
const activate = useCallback4(
|
|
8675
|
+
(el, options) => {
|
|
8676
|
+
if (activeElRef.current === el) return;
|
|
8677
|
+
selectedElRef.current = null;
|
|
8678
|
+
deactivate();
|
|
8679
|
+
if (hoveredImageRef.current) {
|
|
8680
|
+
hoveredImageRef.current = null;
|
|
8681
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8682
|
+
}
|
|
8683
|
+
setToolbarVariant("rich-text");
|
|
8684
|
+
siblingHintElRef.current = null;
|
|
8685
|
+
setSiblingHintRect(null);
|
|
8686
|
+
setSiblingHintRects([]);
|
|
8687
|
+
setIsItemDragging(false);
|
|
8688
|
+
el.setAttribute("contenteditable", "true");
|
|
8689
|
+
el.removeAttribute("data-ohw-hovered");
|
|
8690
|
+
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
8691
|
+
activeElRef.current = el;
|
|
8692
|
+
originalContentRef.current = el.innerHTML;
|
|
8693
|
+
el.focus();
|
|
8694
|
+
if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
8695
|
+
placeCaretAtPoint(el, options.caretX, options.caretY);
|
|
8696
|
+
}
|
|
8697
|
+
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
8698
|
+
const navAnchor = getNavigationItemAnchor(el);
|
|
8699
|
+
if (navAnchor) {
|
|
8700
|
+
setReorderHrefKey(null);
|
|
8701
|
+
setReorderDragDisabled(false);
|
|
8702
|
+
} else {
|
|
8703
|
+
const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
|
|
8704
|
+
setReorderHrefKey(reorderKey);
|
|
8705
|
+
setReorderDragDisabled(reorderDisabled);
|
|
8706
|
+
}
|
|
8707
|
+
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
8708
|
+
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
8709
|
+
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
8710
|
+
},
|
|
8711
|
+
[deactivate, postToParent2]
|
|
8712
|
+
);
|
|
8041
8713
|
activateRef.current = activate;
|
|
8042
8714
|
deactivateRef.current = deactivate;
|
|
8043
8715
|
selectRef.current = select;
|
|
@@ -8085,6 +8757,7 @@ function OhhwellsBridge() {
|
|
|
8085
8757
|
applyLinkByKey(key, val);
|
|
8086
8758
|
}
|
|
8087
8759
|
reconcileNavbarItemsFromContent(content);
|
|
8760
|
+
reconcileFooterOrderFromContent(content);
|
|
8088
8761
|
enforceLinkHrefs();
|
|
8089
8762
|
initSectionsFromContent(content, true);
|
|
8090
8763
|
sectionsLoadedRef.current = true;
|
|
@@ -8146,6 +8819,7 @@ function OhhwellsBridge() {
|
|
|
8146
8819
|
applyLinkByKey(key, val);
|
|
8147
8820
|
}
|
|
8148
8821
|
reconcileNavbarItemsFromContent(content);
|
|
8822
|
+
reconcileFooterOrderFromContent(content);
|
|
8149
8823
|
} finally {
|
|
8150
8824
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
8151
8825
|
}
|
|
@@ -8186,15 +8860,42 @@ function OhhwellsBridge() {
|
|
|
8186
8860
|
if (!subdomain) return {};
|
|
8187
8861
|
return contentCache.get(subdomain) ?? {};
|
|
8188
8862
|
};
|
|
8189
|
-
|
|
8863
|
+
let applying = false;
|
|
8864
|
+
let rafId = null;
|
|
8865
|
+
const run = () => {
|
|
8866
|
+
if (footerDragRef.current || applying) return;
|
|
8867
|
+
applying = true;
|
|
8868
|
+
try {
|
|
8869
|
+
const content = contentForNav();
|
|
8870
|
+
reconcileNavbarItemsFromContent(content);
|
|
8871
|
+
reconcileFooterOrderFromContent(content);
|
|
8872
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
8873
|
+
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
8874
|
+
disableNativeHrefDrag(el);
|
|
8875
|
+
}
|
|
8876
|
+
});
|
|
8877
|
+
} finally {
|
|
8878
|
+
applying = false;
|
|
8879
|
+
}
|
|
8880
|
+
};
|
|
8881
|
+
const scheduleRun = () => {
|
|
8882
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
8883
|
+
rafId = requestAnimationFrame(() => {
|
|
8884
|
+
rafId = null;
|
|
8885
|
+
run();
|
|
8886
|
+
});
|
|
8887
|
+
};
|
|
8190
8888
|
run();
|
|
8191
8889
|
const nav = document.querySelector("nav");
|
|
8192
|
-
|
|
8193
|
-
const observer = new MutationObserver(
|
|
8194
|
-
|
|
8195
|
-
});
|
|
8196
|
-
|
|
8197
|
-
return () =>
|
|
8890
|
+
const footer = document.querySelector("footer");
|
|
8891
|
+
const observer = new MutationObserver(scheduleRun);
|
|
8892
|
+
if (nav) observer.observe(nav, { childList: true, subtree: true });
|
|
8893
|
+
if (footer) observer.observe(footer, { childList: true, subtree: true });
|
|
8894
|
+
if (!nav && !footer) return;
|
|
8895
|
+
return () => {
|
|
8896
|
+
observer.disconnect();
|
|
8897
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
8898
|
+
};
|
|
8198
8899
|
}, [isEditMode, pathname, subdomain, fetchState]);
|
|
8199
8900
|
useEffect8(() => {
|
|
8200
8901
|
if (!isEditMode) return;
|
|
@@ -8259,6 +8960,29 @@ function OhhwellsBridge() {
|
|
|
8259
8960
|
[data-ohw-editable] {
|
|
8260
8961
|
display: block;
|
|
8261
8962
|
}
|
|
8963
|
+
/* Native <a> drag steals clicks \u2014 disable for edit links; reorder via press-to-drag / handle. */
|
|
8964
|
+
footer [data-ohw-href-key] {
|
|
8965
|
+
-webkit-user-drag: none !important;
|
|
8966
|
+
}
|
|
8967
|
+
footer [data-ohw-footer-col]:hover {
|
|
8968
|
+
outline: 1.5px dashed ${PRIMARY2} !important;
|
|
8969
|
+
outline-offset: 6px;
|
|
8970
|
+
border-radius: 8px;
|
|
8971
|
+
}
|
|
8972
|
+
html[data-ohw-footer-press-drag] footer,
|
|
8973
|
+
html[data-ohw-footer-press-drag] footer * {
|
|
8974
|
+
user-select: none !important;
|
|
8975
|
+
-webkit-user-select: none !important;
|
|
8976
|
+
}
|
|
8977
|
+
html[data-ohw-item-dragging] footer,
|
|
8978
|
+
html[data-ohw-item-dragging] footer * {
|
|
8979
|
+
user-select: none !important;
|
|
8980
|
+
-webkit-user-select: none !important;
|
|
8981
|
+
pointer-events: none !important;
|
|
8982
|
+
}
|
|
8983
|
+
html[data-ohw-item-dragging] {
|
|
8984
|
+
cursor: grabbing !important;
|
|
8985
|
+
}
|
|
8262
8986
|
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]) { cursor: text !important; }
|
|
8263
8987
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
8264
8988
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
@@ -8304,12 +9028,39 @@ function OhhwellsBridge() {
|
|
|
8304
9028
|
}
|
|
8305
9029
|
refreshStateRules();
|
|
8306
9030
|
const handleClick = (e) => {
|
|
9031
|
+
if (suppressNextClickRef.current) {
|
|
9032
|
+
suppressNextClickRef.current = false;
|
|
9033
|
+
e.preventDefault();
|
|
9034
|
+
e.stopPropagation();
|
|
9035
|
+
return;
|
|
9036
|
+
}
|
|
8307
9037
|
const target = e.target;
|
|
8308
9038
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
8309
9039
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
8310
9040
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
8311
9041
|
if (isInsideLinkEditor(target)) return;
|
|
8312
9042
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
9043
|
+
if (target.closest("[data-ohw-item-drag-surface]")) {
|
|
9044
|
+
e.preventDefault();
|
|
9045
|
+
e.stopPropagation();
|
|
9046
|
+
const selected = selectedElRef.current;
|
|
9047
|
+
if (selected && isNavigationItem(selected)) {
|
|
9048
|
+
const editable2 = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
9049
|
+
if (editable2) {
|
|
9050
|
+
activateRef.current(editable2, {
|
|
9051
|
+
caretX: e.clientX,
|
|
9052
|
+
caretY: e.clientY
|
|
9053
|
+
});
|
|
9054
|
+
}
|
|
9055
|
+
} else if (selected?.hasAttribute("data-ohw-footer-col")) {
|
|
9056
|
+
const link = listFooterLinksInColumn(selected).find((el) => {
|
|
9057
|
+
const r2 = el.getBoundingClientRect();
|
|
9058
|
+
return e.clientX >= r2.left && e.clientX <= r2.right && e.clientY >= r2.top && e.clientY <= r2.bottom;
|
|
9059
|
+
});
|
|
9060
|
+
if (link) selectRef.current(link);
|
|
9061
|
+
}
|
|
9062
|
+
return;
|
|
9063
|
+
}
|
|
8313
9064
|
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8314
9065
|
if (navFromChrome) {
|
|
8315
9066
|
e.preventDefault();
|
|
@@ -8364,10 +9115,26 @@ function OhhwellsBridge() {
|
|
|
8364
9115
|
if (hrefAnchor) {
|
|
8365
9116
|
e.preventDefault();
|
|
8366
9117
|
e.stopPropagation();
|
|
8367
|
-
if (selectedElRef.current === hrefAnchor)
|
|
9118
|
+
if (selectedElRef.current === hrefAnchor) {
|
|
9119
|
+
const textEditable = hrefAnchor.querySelector('[data-ohw-editable="text"]') ?? hrefAnchor.querySelector("[data-ohw-editable]");
|
|
9120
|
+
if (textEditable) {
|
|
9121
|
+
activateRef.current(textEditable, {
|
|
9122
|
+
caretX: e.clientX,
|
|
9123
|
+
caretY: e.clientY
|
|
9124
|
+
});
|
|
9125
|
+
}
|
|
9126
|
+
return;
|
|
9127
|
+
}
|
|
8368
9128
|
selectRef.current(hrefAnchor);
|
|
8369
9129
|
return;
|
|
8370
9130
|
}
|
|
9131
|
+
const footerColClick = target.closest("[data-ohw-footer-col]");
|
|
9132
|
+
if (footerColClick) {
|
|
9133
|
+
e.preventDefault();
|
|
9134
|
+
e.stopPropagation();
|
|
9135
|
+
selectFrameRef.current(footerColClick);
|
|
9136
|
+
return;
|
|
9137
|
+
}
|
|
8371
9138
|
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8372
9139
|
if (navContainerToSelect) {
|
|
8373
9140
|
e.preventDefault();
|
|
@@ -8448,6 +9215,15 @@ function OhhwellsBridge() {
|
|
|
8448
9215
|
setHoveredNavContainerRect(null);
|
|
8449
9216
|
}
|
|
8450
9217
|
}
|
|
9218
|
+
const footerCol = target.closest("[data-ohw-footer-col]");
|
|
9219
|
+
if (footerCol) {
|
|
9220
|
+
hoveredNavContainerRef.current = null;
|
|
9221
|
+
setHoveredNavContainerRect(null);
|
|
9222
|
+
if (selectedElRef.current === footerCol) return;
|
|
9223
|
+
hoveredItemElRef.current = footerCol;
|
|
9224
|
+
setHoveredItemRect(footerCol.getBoundingClientRect());
|
|
9225
|
+
return;
|
|
9226
|
+
}
|
|
8451
9227
|
const navAnchor = getNavigationItemAnchor(target);
|
|
8452
9228
|
if (navAnchor) {
|
|
8453
9229
|
hoveredNavContainerRef.current = null;
|
|
@@ -8484,6 +9260,15 @@ function OhhwellsBridge() {
|
|
|
8484
9260
|
hoveredNavContainerRef.current = null;
|
|
8485
9261
|
setHoveredNavContainerRect(null);
|
|
8486
9262
|
}
|
|
9263
|
+
const footerCol = target.closest("[data-ohw-footer-col]");
|
|
9264
|
+
if (footerCol && hoveredItemElRef.current === footerCol) {
|
|
9265
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
9266
|
+
if (related2?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
9267
|
+
if (related2?.closest("[data-ohw-footer-col]") === footerCol) return;
|
|
9268
|
+
hoveredItemElRef.current = null;
|
|
9269
|
+
setHoveredItemRect(null);
|
|
9270
|
+
return;
|
|
9271
|
+
}
|
|
8487
9272
|
const navAnchor = getNavigationItemAnchor(target);
|
|
8488
9273
|
if (navAnchor) {
|
|
8489
9274
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -8892,6 +9677,14 @@ function OhhwellsBridge() {
|
|
|
8892
9677
|
probeHoverCardsAt(clientX, clientY);
|
|
8893
9678
|
};
|
|
8894
9679
|
const handleDragOver = (e) => {
|
|
9680
|
+
const footerSession = footerDragRef.current;
|
|
9681
|
+
if (footerSession) {
|
|
9682
|
+
e.preventDefault();
|
|
9683
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
9684
|
+
const slot = footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
9685
|
+
refreshFooterDragVisualsRef.current(footerSession, slot, e.clientX, e.clientY);
|
|
9686
|
+
return;
|
|
9687
|
+
}
|
|
8895
9688
|
e.preventDefault();
|
|
8896
9689
|
const el = findImageAtPoint(e.clientX, e.clientY, false);
|
|
8897
9690
|
if (!el) {
|
|
@@ -9099,6 +9892,7 @@ function OhhwellsBridge() {
|
|
|
9099
9892
|
}
|
|
9100
9893
|
editContentRef.current = { ...editContentRef.current, ...content };
|
|
9101
9894
|
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
9895
|
+
reconcileFooterOrderFromContent(editContentRef.current);
|
|
9102
9896
|
enforceLinkHrefs();
|
|
9103
9897
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
9104
9898
|
};
|
|
@@ -9212,6 +10006,17 @@ function OhhwellsBridge() {
|
|
|
9212
10006
|
if (siblingHintElRef.current) {
|
|
9213
10007
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
9214
10008
|
}
|
|
10009
|
+
const selected = selectedElRef.current;
|
|
10010
|
+
if (selected && !footerDragRef.current && (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") && isInferredFooterGroup(selected)))) {
|
|
10011
|
+
setSiblingHintRects(
|
|
10012
|
+
listFooterColumns().filter((column) => column !== selected).map((column) => column.getBoundingClientRect())
|
|
10013
|
+
);
|
|
10014
|
+
}
|
|
10015
|
+
if (footerDragRef.current) {
|
|
10016
|
+
const session = footerDragRef.current;
|
|
10017
|
+
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
10018
|
+
refreshFooterDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
10019
|
+
}
|
|
9215
10020
|
if (hoveredImageRef.current) {
|
|
9216
10021
|
const el = hoveredImageRef.current;
|
|
9217
10022
|
const r2 = el.getBoundingClientRect();
|
|
@@ -9222,7 +10027,7 @@ function OhhwellsBridge() {
|
|
|
9222
10027
|
};
|
|
9223
10028
|
const handleSave = (e) => {
|
|
9224
10029
|
if (e.data?.type !== "ow:save") return;
|
|
9225
|
-
const nodes = collectEditableNodes();
|
|
10030
|
+
const nodes = collectEditableNodes(editContentRef.current);
|
|
9226
10031
|
const tracker = document.querySelector("[data-ohw-sections-tracker]");
|
|
9227
10032
|
if (tracker?.textContent) nodes.push({ key: "__ohw_sections", type: "sections", text: tracker.textContent });
|
|
9228
10033
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
@@ -9562,6 +10367,154 @@ function OhhwellsBridge() {
|
|
|
9562
10367
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
9563
10368
|
};
|
|
9564
10369
|
}, [isEditMode, refreshStateRules]);
|
|
10370
|
+
useEffect8(() => {
|
|
10371
|
+
if (!isEditMode) return;
|
|
10372
|
+
const THRESHOLD = 10;
|
|
10373
|
+
const resolveWasSelected = (el) => {
|
|
10374
|
+
if (selectedElRef.current === el) return true;
|
|
10375
|
+
const activeAnchor = activeElRef.current ? getNavigationItemAnchor(activeElRef.current) : null;
|
|
10376
|
+
return activeAnchor === el;
|
|
10377
|
+
};
|
|
10378
|
+
const onPointerDown = (e) => {
|
|
10379
|
+
if (e.button !== 0) return;
|
|
10380
|
+
if (footerDragRef.current) return;
|
|
10381
|
+
const target = e.target;
|
|
10382
|
+
if (!target) return;
|
|
10383
|
+
if (target.closest('[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root]')) {
|
|
10384
|
+
return;
|
|
10385
|
+
}
|
|
10386
|
+
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
10387
|
+
const anchor = getNavigationItemAnchor(target);
|
|
10388
|
+
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
10389
|
+
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
10390
|
+
armFooterPressDrag();
|
|
10391
|
+
footerPointerDragRef.current = {
|
|
10392
|
+
el: anchor,
|
|
10393
|
+
kind: "link",
|
|
10394
|
+
startX: e.clientX,
|
|
10395
|
+
startY: e.clientY,
|
|
10396
|
+
pointerId: e.pointerId,
|
|
10397
|
+
wasSelected: resolveWasSelected(anchor),
|
|
10398
|
+
started: false
|
|
10399
|
+
};
|
|
10400
|
+
return;
|
|
10401
|
+
}
|
|
10402
|
+
const col = target.closest("[data-ohw-footer-col]");
|
|
10403
|
+
if (col && !getNavigationItemAnchor(target)) {
|
|
10404
|
+
armFooterPressDrag();
|
|
10405
|
+
footerPointerDragRef.current = {
|
|
10406
|
+
el: col,
|
|
10407
|
+
kind: "column",
|
|
10408
|
+
startX: e.clientX,
|
|
10409
|
+
startY: e.clientY,
|
|
10410
|
+
pointerId: e.pointerId,
|
|
10411
|
+
wasSelected: resolveWasSelected(col),
|
|
10412
|
+
started: false
|
|
10413
|
+
};
|
|
10414
|
+
}
|
|
10415
|
+
};
|
|
10416
|
+
const onPointerMove = (e) => {
|
|
10417
|
+
const pending = footerPointerDragRef.current;
|
|
10418
|
+
if (!pending) return;
|
|
10419
|
+
if (pending.started) {
|
|
10420
|
+
e.preventDefault();
|
|
10421
|
+
clearTextSelection();
|
|
10422
|
+
const session = footerDragRef.current;
|
|
10423
|
+
if (!session) return;
|
|
10424
|
+
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
10425
|
+
refreshFooterDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
10426
|
+
return;
|
|
10427
|
+
}
|
|
10428
|
+
const dx = e.clientX - pending.startX;
|
|
10429
|
+
const dy = e.clientY - pending.startY;
|
|
10430
|
+
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
10431
|
+
e.preventDefault();
|
|
10432
|
+
pending.started = true;
|
|
10433
|
+
clearTextSelection();
|
|
10434
|
+
try {
|
|
10435
|
+
document.body.setPointerCapture(pending.pointerId);
|
|
10436
|
+
} catch {
|
|
10437
|
+
}
|
|
10438
|
+
if (linkPopoverOpenRef.current) {
|
|
10439
|
+
setLinkPopoverRef.current(null);
|
|
10440
|
+
}
|
|
10441
|
+
if (activeElRef.current) {
|
|
10442
|
+
deactivateRef.current();
|
|
10443
|
+
}
|
|
10444
|
+
if (pending.kind === "link") {
|
|
10445
|
+
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
10446
|
+
if (!key) return;
|
|
10447
|
+
const column = findFooterColumnForLink(pending.el);
|
|
10448
|
+
const columns2 = listFooterColumns();
|
|
10449
|
+
beginFooterDragRef.current({
|
|
10450
|
+
kind: "link",
|
|
10451
|
+
hrefKey: key,
|
|
10452
|
+
columnEl: column,
|
|
10453
|
+
sourceColumnIndex: column ? columns2.indexOf(column) : 0,
|
|
10454
|
+
wasSelected: pending.wasSelected,
|
|
10455
|
+
draggedEl: pending.el,
|
|
10456
|
+
lastClientX: e.clientX,
|
|
10457
|
+
lastClientY: e.clientY,
|
|
10458
|
+
activeSlot: null
|
|
10459
|
+
});
|
|
10460
|
+
return;
|
|
10461
|
+
}
|
|
10462
|
+
const columns = listFooterColumns();
|
|
10463
|
+
const idx = columns.indexOf(pending.el);
|
|
10464
|
+
if (idx < 0) return;
|
|
10465
|
+
beginFooterDragRef.current({
|
|
10466
|
+
kind: "column",
|
|
10467
|
+
hrefKey: null,
|
|
10468
|
+
columnEl: pending.el,
|
|
10469
|
+
sourceColumnIndex: idx,
|
|
10470
|
+
wasSelected: pending.wasSelected,
|
|
10471
|
+
draggedEl: pending.el,
|
|
10472
|
+
lastClientX: e.clientX,
|
|
10473
|
+
lastClientY: e.clientY,
|
|
10474
|
+
activeSlot: null
|
|
10475
|
+
});
|
|
10476
|
+
};
|
|
10477
|
+
const endPointerDrag = (e) => {
|
|
10478
|
+
const pending = footerPointerDragRef.current;
|
|
10479
|
+
footerPointerDragRef.current = null;
|
|
10480
|
+
try {
|
|
10481
|
+
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
10482
|
+
document.body.releasePointerCapture(e.pointerId);
|
|
10483
|
+
}
|
|
10484
|
+
} catch {
|
|
10485
|
+
}
|
|
10486
|
+
if (!pending?.started) {
|
|
10487
|
+
unlockFooterDragInteraction();
|
|
10488
|
+
return;
|
|
10489
|
+
}
|
|
10490
|
+
suppressNextClickRef.current = true;
|
|
10491
|
+
commitFooterDragRef.current(e.clientX, e.clientY);
|
|
10492
|
+
};
|
|
10493
|
+
const blockSelectStart = (e) => {
|
|
10494
|
+
if (footerDragRef.current || footerPointerDragRef.current?.started || document.documentElement.hasAttribute("data-ohw-footer-press-drag")) {
|
|
10495
|
+
e.preventDefault();
|
|
10496
|
+
}
|
|
10497
|
+
};
|
|
10498
|
+
const onDragEnd = (_e) => {
|
|
10499
|
+
if (!footerDragRef.current) return;
|
|
10500
|
+
commitFooterDragRef.current();
|
|
10501
|
+
};
|
|
10502
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
10503
|
+
document.addEventListener("pointermove", onPointerMove, true);
|
|
10504
|
+
document.addEventListener("pointerup", endPointerDrag, true);
|
|
10505
|
+
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
10506
|
+
document.addEventListener("selectstart", blockSelectStart, true);
|
|
10507
|
+
document.addEventListener("dragend", onDragEnd, true);
|
|
10508
|
+
return () => {
|
|
10509
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
10510
|
+
document.removeEventListener("pointermove", onPointerMove, true);
|
|
10511
|
+
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
10512
|
+
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
10513
|
+
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
10514
|
+
document.removeEventListener("dragend", onDragEnd, true);
|
|
10515
|
+
unlockFooterDragInteraction();
|
|
10516
|
+
};
|
|
10517
|
+
}, [isEditMode]);
|
|
9565
10518
|
useEffect8(() => {
|
|
9566
10519
|
const handler = (e) => {
|
|
9567
10520
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
@@ -9599,7 +10552,13 @@ function OhhwellsBridge() {
|
|
|
9599
10552
|
const next = { ...prev, [pathKey]: sections };
|
|
9600
10553
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
9601
10554
|
});
|
|
9602
|
-
postToParent2({
|
|
10555
|
+
postToParent2({
|
|
10556
|
+
type: "ow:ready",
|
|
10557
|
+
version: "1",
|
|
10558
|
+
path: pathname,
|
|
10559
|
+
nodes: collectEditableNodes(editContentRef.current),
|
|
10560
|
+
sections
|
|
10561
|
+
});
|
|
9603
10562
|
postToParent2({ type: "ow:request-site-pages" });
|
|
9604
10563
|
}, 150);
|
|
9605
10564
|
return () => {
|
|
@@ -9716,9 +10675,6 @@ function OhhwellsBridge() {
|
|
|
9716
10675
|
},
|
|
9717
10676
|
[postToParent2, sitePages, sectionsByPath]
|
|
9718
10677
|
);
|
|
9719
|
-
const showEditLink = toolbarShowEditLink;
|
|
9720
|
-
const currentSections = sectionsByPath[pathname] ?? [];
|
|
9721
|
-
linkPopoverOpenRef.current = linkPopover !== null;
|
|
9722
10678
|
const handleMediaReplace = useCallback4(
|
|
9723
10679
|
(key) => {
|
|
9724
10680
|
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
@@ -9761,10 +10717,13 @@ function OhhwellsBridge() {
|
|
|
9761
10717
|
},
|
|
9762
10718
|
[postToParent2]
|
|
9763
10719
|
);
|
|
10720
|
+
const showEditLink = toolbarShowEditLink;
|
|
10721
|
+
const currentSections = sectionsByPath[pathname] ?? [];
|
|
10722
|
+
linkPopoverOpenRef.current = linkPopover !== null;
|
|
9764
10723
|
return bridgeRoot ? createPortal2(
|
|
9765
10724
|
/* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
9766
|
-
/* @__PURE__ */
|
|
9767
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */
|
|
10725
|
+
/* @__PURE__ */ jsx25("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
10726
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx25(
|
|
9768
10727
|
MediaOverlay,
|
|
9769
10728
|
{
|
|
9770
10729
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -9775,7 +10734,7 @@ function OhhwellsBridge() {
|
|
|
9775
10734
|
},
|
|
9776
10735
|
`uploading-${key}`
|
|
9777
10736
|
)),
|
|
9778
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */
|
|
10737
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx25(
|
|
9779
10738
|
MediaOverlay,
|
|
9780
10739
|
{
|
|
9781
10740
|
hover: mediaHover,
|
|
@@ -9784,61 +10743,31 @@ function OhhwellsBridge() {
|
|
|
9784
10743
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
9785
10744
|
}
|
|
9786
10745
|
),
|
|
9787
|
-
carouselHover && /* @__PURE__ */
|
|
9788
|
-
siblingHintRect && !isItemDragging && /* @__PURE__ */
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
rect: toolbarRect,
|
|
9794
|
-
onAdd: handleAddTopLevelNavItem
|
|
9795
|
-
}
|
|
9796
|
-
),
|
|
9797
|
-
hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx24(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
9798
|
-
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ jsx24(
|
|
9799
|
-
ItemInteractionLayer,
|
|
10746
|
+
carouselHover && /* @__PURE__ */ jsx25(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
|
|
10747
|
+
siblingHintRect && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx25(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
10748
|
+
siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx25(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
10749
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && /* @__PURE__ */ jsx25(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
10750
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx25(
|
|
10751
|
+
"div",
|
|
9800
10752
|
{
|
|
9801
|
-
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
|
|
9808
|
-
|
|
9809
|
-
|
|
9810
|
-
|
|
9811
|
-
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
}
|
|
9817
|
-
) : void 0
|
|
9818
|
-
}
|
|
9819
|
-
),
|
|
10753
|
+
className: "pointer-events-none fixed z-2147483646",
|
|
10754
|
+
style: {
|
|
10755
|
+
left: slot.left,
|
|
10756
|
+
top: slot.top,
|
|
10757
|
+
width: slot.width,
|
|
10758
|
+
height: slot.height
|
|
10759
|
+
},
|
|
10760
|
+
children: /* @__PURE__ */ jsx25(DropIndicator, { direction: slot.direction, state: activeFooterDropIndex === i ? "dragActive" : "dragIdle", className: slot.direction === "horizontal" ? "!h-full !w-full" : "!h-full !w-full" })
|
|
10761
|
+
},
|
|
10762
|
+
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
10763
|
+
)),
|
|
10764
|
+
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && !siblingHintRect && siblingHintRects.length === 0 && /* @__PURE__ */ jsx25(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
10765
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && /* @__PURE__ */ jsx25(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
10766
|
+
hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && siblingHintRects.length === 0 && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx25(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
10767
|
+
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ jsx25(ItemInteractionLayer, { rect: isItemDragging && draggedItemRect && footerDragRef.current?.wasSelected ? draggedItemRect : toolbarRect, elRef: glowElRef, state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current), showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection, dragDisabled: reorderDragDisabled, dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item", onDragHandleDragStart: handleItemDragStart, onDragHandleDragEnd: handleItemDragEnd, onItemPointerDown: handleItemChromePointerDown, onItemClick: handleItemChromeClick, toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ jsx25(ItemActionToolbar, { onEditLink: openLinkPopoverForSelected, addItemDisabled: true, editLinkDisabled: false, moreDisabled: true }) : void 0 }),
|
|
9820
10768
|
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
9821
|
-
/* @__PURE__ */
|
|
9822
|
-
|
|
9823
|
-
{
|
|
9824
|
-
rect: toolbarRect,
|
|
9825
|
-
elRef: glowElRef,
|
|
9826
|
-
reorderHrefKey,
|
|
9827
|
-
dragDisabled: reorderDragDisabled
|
|
9828
|
-
}
|
|
9829
|
-
),
|
|
9830
|
-
/* @__PURE__ */ jsx24(
|
|
9831
|
-
FloatingToolbar,
|
|
9832
|
-
{
|
|
9833
|
-
rect: toolbarRect,
|
|
9834
|
-
parentScroll: parentScrollRef.current,
|
|
9835
|
-
elRef: toolbarElRef,
|
|
9836
|
-
onCommand: handleCommand,
|
|
9837
|
-
activeCommands,
|
|
9838
|
-
showEditLink,
|
|
9839
|
-
onEditLink: openLinkPopoverForActive
|
|
9840
|
-
}
|
|
9841
|
-
)
|
|
10769
|
+
/* @__PURE__ */ jsx25(EditGlowChrome, { rect: toolbarRect, elRef: glowElRef, reorderHrefKey, dragDisabled: reorderDragDisabled }),
|
|
10770
|
+
/* @__PURE__ */ jsx25(FloatingToolbar, { rect: toolbarRect, parentScroll: parentScrollRef.current, elRef: toolbarElRef, onCommand: handleCommand, activeCommands, showEditLink, onEditLink: openLinkPopoverForActive })
|
|
9842
10771
|
] }),
|
|
9843
10772
|
maxBadge && /* @__PURE__ */ jsxs14(
|
|
9844
10773
|
"div",
|
|
@@ -9866,128 +10795,33 @@ function OhhwellsBridge() {
|
|
|
9866
10795
|
]
|
|
9867
10796
|
}
|
|
9868
10797
|
),
|
|
9869
|
-
toggleState && !linkPopover && /* @__PURE__ */
|
|
9870
|
-
|
|
9871
|
-
{
|
|
9872
|
-
|
|
9873
|
-
|
|
9874
|
-
|
|
9875
|
-
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
9883
|
-
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
9884
|
-
children: [
|
|
9885
|
-
/* @__PURE__ */ jsx24("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9886
|
-
/* @__PURE__ */ jsx24(
|
|
9887
|
-
Badge,
|
|
9888
|
-
{
|
|
9889
|
-
className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
|
|
9890
|
-
onClick: () => {
|
|
9891
|
-
window.parent.postMessage(
|
|
9892
|
-
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
9893
|
-
"*"
|
|
9894
|
-
);
|
|
9895
|
-
},
|
|
9896
|
-
children: "Add Section"
|
|
9897
|
-
}
|
|
9898
|
-
),
|
|
9899
|
-
/* @__PURE__ */ jsx24("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
9900
|
-
]
|
|
9901
|
-
}
|
|
9902
|
-
),
|
|
9903
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx24(
|
|
9904
|
-
LinkPopover,
|
|
9905
|
-
{
|
|
9906
|
-
panelRef: linkPopoverPanelRef,
|
|
9907
|
-
portalContainer: dialogPortalContainer,
|
|
9908
|
-
open: true,
|
|
9909
|
-
mode: linkPopover.mode ?? "edit",
|
|
9910
|
-
pages: sitePages,
|
|
9911
|
-
sections: currentSections,
|
|
9912
|
-
sectionsByPath,
|
|
9913
|
-
initialTarget: linkPopover.target,
|
|
9914
|
-
existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
|
|
9915
|
-
onClose: closeLinkPopover,
|
|
9916
|
-
onSubmit: handleLinkPopoverSubmit
|
|
9917
|
-
},
|
|
9918
|
-
linkPopover.key
|
|
9919
|
-
) : null,
|
|
9920
|
-
sectionGap && /* @__PURE__ */ jsxs14(
|
|
9921
|
-
"div",
|
|
9922
|
-
{
|
|
9923
|
-
"data-ohw-section-insert-line": "",
|
|
9924
|
-
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
9925
|
-
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
9926
|
-
children: [
|
|
9927
|
-
/* @__PURE__ */ jsx24("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9928
|
-
/* @__PURE__ */ jsx24(
|
|
9929
|
-
Badge,
|
|
9930
|
-
{
|
|
9931
|
-
className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
|
|
9932
|
-
onClick: () => {
|
|
9933
|
-
window.parent.postMessage(
|
|
9934
|
-
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
9935
|
-
"*"
|
|
9936
|
-
);
|
|
10798
|
+
toggleState && !linkPopover && /* @__PURE__ */ jsx25(StateToggle, { rect: toggleState.rect, activeState: toggleState.activeState, states: toggleState.states, onStateChange: handleStateChange }),
|
|
10799
|
+
sectionGap && !linkPopover && /* @__PURE__ */ jsxs14("div", { "data-ohw-section-insert-line": "", className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none", style: { top: sectionGap.y, transform: "translateY(-50%)" }, children: [
|
|
10800
|
+
/* @__PURE__ */ jsx25("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
10801
|
+
/* @__PURE__ */ jsx25(
|
|
10802
|
+
Badge,
|
|
10803
|
+
{
|
|
10804
|
+
className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
|
|
10805
|
+
onClick: () => {
|
|
10806
|
+
window.parent.postMessage(
|
|
10807
|
+
{
|
|
10808
|
+
type: "ow:add-section",
|
|
10809
|
+
insertAfter: sectionGap.insertAfter,
|
|
10810
|
+
insertBefore: sectionGap.insertBefore
|
|
9937
10811
|
},
|
|
9938
|
-
|
|
9939
|
-
|
|
9940
|
-
|
|
9941
|
-
|
|
9942
|
-
|
|
9943
|
-
|
|
9944
|
-
|
|
10812
|
+
"*"
|
|
10813
|
+
);
|
|
10814
|
+
},
|
|
10815
|
+
children: "Add Section"
|
|
10816
|
+
}
|
|
10817
|
+
),
|
|
10818
|
+
/* @__PURE__ */ jsx25("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
10819
|
+
] }),
|
|
10820
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx25(LinkPopover, { panelRef: linkPopoverPanelRef, portalContainer: dialogPortalContainer, open: true, mode: linkPopover.mode ?? "edit", pages: sitePages, sections: currentSections, sectionsByPath, initialTarget: linkPopover.target, existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [], onClose: closeLinkPopover, onSubmit: handleLinkPopoverSubmit }, linkPopover.key) : null
|
|
9945
10821
|
] }),
|
|
9946
10822
|
bridgeRoot
|
|
9947
10823
|
) : null;
|
|
9948
10824
|
}
|
|
9949
|
-
|
|
9950
|
-
// src/ui/drop-indicator.tsx
|
|
9951
|
-
import * as React10 from "react";
|
|
9952
|
-
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
9953
|
-
var dropIndicatorVariants = cva(
|
|
9954
|
-
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
9955
|
-
{
|
|
9956
|
-
variants: {
|
|
9957
|
-
direction: {
|
|
9958
|
-
vertical: "h-6 w-[3px]",
|
|
9959
|
-
horizontal: "h-[3px] w-[200px]"
|
|
9960
|
-
},
|
|
9961
|
-
state: {
|
|
9962
|
-
default: "opacity-0",
|
|
9963
|
-
hover: "opacity-100",
|
|
9964
|
-
dragIdle: "opacity-40",
|
|
9965
|
-
dragActive: "opacity-100"
|
|
9966
|
-
}
|
|
9967
|
-
},
|
|
9968
|
-
defaultVariants: {
|
|
9969
|
-
direction: "vertical",
|
|
9970
|
-
state: "default"
|
|
9971
|
-
}
|
|
9972
|
-
}
|
|
9973
|
-
);
|
|
9974
|
-
var DropIndicator = React10.forwardRef(
|
|
9975
|
-
({ className, direction, state, ...props }, ref) => {
|
|
9976
|
-
return /* @__PURE__ */ jsx25(
|
|
9977
|
-
"div",
|
|
9978
|
-
{
|
|
9979
|
-
ref,
|
|
9980
|
-
"data-slot": "drop-indicator",
|
|
9981
|
-
"data-direction": direction ?? "vertical",
|
|
9982
|
-
"data-state": state ?? "default",
|
|
9983
|
-
"aria-hidden": "true",
|
|
9984
|
-
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
9985
|
-
...props
|
|
9986
|
-
}
|
|
9987
|
-
);
|
|
9988
|
-
}
|
|
9989
|
-
);
|
|
9990
|
-
DropIndicator.displayName = "DropIndicator";
|
|
9991
10825
|
export {
|
|
9992
10826
|
CustomToolbar,
|
|
9993
10827
|
CustomToolbarButton,
|