@ohhwells/bridge 0.1.43 → 0.1.45
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 +2742 -480
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -4
- package/dist/index.d.ts +30 -4
- package/dist/index.js +2746 -484
- package/dist/index.js.map +1 -1
- package/dist/styles.css +56 -49
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -62,7 +62,7 @@ __export(index_exports, {
|
|
|
62
62
|
module.exports = __toCommonJS(index_exports);
|
|
63
63
|
|
|
64
64
|
// src/OhhwellsBridge.tsx
|
|
65
|
-
var
|
|
65
|
+
var import_react9 = __toESM(require("react"), 1);
|
|
66
66
|
var import_client = require("react-dom/client");
|
|
67
67
|
var import_react_dom2 = require("react-dom");
|
|
68
68
|
|
|
@@ -4303,7 +4303,8 @@ var CustomToolbar = React4.forwardRef(({ className, onMouseDown, ...props }, ref
|
|
|
4303
4303
|
ref,
|
|
4304
4304
|
"data-ohw-toolbar": "",
|
|
4305
4305
|
className: cn(
|
|
4306
|
-
|
|
4306
|
+
// Figma: bg background, radius 8, gap-1, p-0.5, shadow-md — no border
|
|
4307
|
+
"inline-flex h-8 items-center gap-1 rounded-[var(--radius,0.5rem)] bg-background p-0.5 font-sans whitespace-nowrap shadow-md",
|
|
4307
4308
|
className
|
|
4308
4309
|
),
|
|
4309
4310
|
onMouseDown: (e) => {
|
|
@@ -4331,8 +4332,8 @@ var CustomToolbarButton = React4.forwardRef(
|
|
|
4331
4332
|
ref,
|
|
4332
4333
|
type,
|
|
4333
4334
|
className: cn(
|
|
4334
|
-
"inline-flex shrink-0 items-center justify-center rounded
|
|
4335
|
-
active ? "bg-primary text-primary-foreground" : "bg-transparent
|
|
4335
|
+
"inline-flex size-7 shrink-0 items-center justify-center rounded-[calc(var(--radius,0.5rem)-2px)] text-foreground transition-colors",
|
|
4336
|
+
active ? "bg-primary text-primary-foreground" : "bg-transparent hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
4336
4337
|
className
|
|
4337
4338
|
),
|
|
4338
4339
|
...props
|
|
@@ -4367,9 +4368,10 @@ var arrowClassBySide = {
|
|
|
4367
4368
|
};
|
|
4368
4369
|
function TooltipContent({
|
|
4369
4370
|
className,
|
|
4370
|
-
sideOffset =
|
|
4371
|
+
sideOffset = 9,
|
|
4371
4372
|
side = "bottom",
|
|
4372
4373
|
children,
|
|
4374
|
+
hideArrow,
|
|
4373
4375
|
...props
|
|
4374
4376
|
}) {
|
|
4375
4377
|
const resolvedSide = side ?? "bottom";
|
|
@@ -4380,12 +4382,13 @@ function TooltipContent({
|
|
|
4380
4382
|
side,
|
|
4381
4383
|
sideOffset,
|
|
4382
4384
|
className: cn(
|
|
4383
|
-
"relative z-[2147483647] w-fit max-w-xs rounded-md bg-foreground px-3 py-1.5 text-xs text-background
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
"animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
4385
|
+
"relative z-[2147483647] inline-flex w-fit max-w-xs items-center rounded-md bg-foreground px-3 py-1.5 text-xs text-background",
|
|
4386
|
+
"origin-[var(--radix-tooltip-content-transform-origin)] animate-in fade-in-0 zoom-in-95",
|
|
4387
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
4387
4388
|
"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
|
|
4388
4389
|
"data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2",
|
|
4390
|
+
!hideArrow && 'before:pointer-events-none before:absolute before:size-2 before:rotate-45 before:bg-foreground before:content-[""]',
|
|
4391
|
+
!hideArrow && arrowClassBySide[resolvedSide],
|
|
4389
4392
|
className
|
|
4390
4393
|
),
|
|
4391
4394
|
...props,
|
|
@@ -4406,7 +4409,7 @@ function ToolbarActionTooltip({
|
|
|
4406
4409
|
const button = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, ...buttonProps, children });
|
|
4407
4410
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Tooltip, { children: [
|
|
4408
4411
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "inline-flex", children: button }) : button }),
|
|
4409
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipContent, { side, children: label })
|
|
4412
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipContent, { side, sideOffset: 9, children: label })
|
|
4410
4413
|
] });
|
|
4411
4414
|
}
|
|
4412
4415
|
function ItemActionToolbar({
|
|
@@ -4416,6 +4419,8 @@ function ItemActionToolbar({
|
|
|
4416
4419
|
editLinkDisabled = false,
|
|
4417
4420
|
addItemDisabled = true,
|
|
4418
4421
|
moreDisabled = true,
|
|
4422
|
+
showAddItem = true,
|
|
4423
|
+
showMore = true,
|
|
4419
4424
|
tooltipSide = "bottom"
|
|
4420
4425
|
}) {
|
|
4421
4426
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CustomToolbar, { children: [
|
|
@@ -4440,8 +4445,7 @@ function ItemActionToolbar({
|
|
|
4440
4445
|
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4441
4446
|
}
|
|
4442
4447
|
),
|
|
4443
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4444
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4448
|
+
showAddItem ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4445
4449
|
ToolbarActionTooltip,
|
|
4446
4450
|
{
|
|
4447
4451
|
label: "Add item",
|
|
@@ -4457,9 +4461,8 @@ function ItemActionToolbar({
|
|
|
4457
4461
|
},
|
|
4458
4462
|
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Plus, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4459
4463
|
}
|
|
4460
|
-
),
|
|
4461
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4462
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4464
|
+
) : null,
|
|
4465
|
+
showMore ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4463
4466
|
ToolbarActionTooltip,
|
|
4464
4467
|
{
|
|
4465
4468
|
label: "More",
|
|
@@ -4475,15 +4478,32 @@ function ItemActionToolbar({
|
|
|
4475
4478
|
},
|
|
4476
4479
|
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.MoreHorizontal, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4477
4480
|
}
|
|
4478
|
-
)
|
|
4481
|
+
) : null
|
|
4479
4482
|
] }) });
|
|
4480
4483
|
}
|
|
4481
4484
|
|
|
4482
4485
|
// src/ui/item-interaction-layer.tsx
|
|
4486
|
+
var React5 = __toESM(require("react"), 1);
|
|
4483
4487
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
4484
4488
|
var PRIMARY = "var(--ohw-primary, #0885FE)";
|
|
4485
|
-
var FOCUS_RING =
|
|
4489
|
+
var FOCUS_RING = `0 0 0 4px color-mix(in srgb, ${PRIMARY} 12%, transparent)`;
|
|
4486
4490
|
var DRAG_SHADOW = "0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.1)";
|
|
4491
|
+
var TOOLBAR_EDGE_MARGIN = 4;
|
|
4492
|
+
var SELECTION_CHROME_GAP = 4;
|
|
4493
|
+
var TOOLBAR_STROKE_GAP = 4;
|
|
4494
|
+
function getChromeZIndex(state) {
|
|
4495
|
+
switch (state) {
|
|
4496
|
+
case "active-top":
|
|
4497
|
+
case "active-bottom":
|
|
4498
|
+
case "dragging":
|
|
4499
|
+
return 2147483644;
|
|
4500
|
+
case "hover":
|
|
4501
|
+
case "sibling-hint":
|
|
4502
|
+
return 2147483643;
|
|
4503
|
+
default:
|
|
4504
|
+
return 2147483642;
|
|
4505
|
+
}
|
|
4506
|
+
}
|
|
4487
4507
|
function getChromeStyle(state) {
|
|
4488
4508
|
switch (state) {
|
|
4489
4509
|
case "hover":
|
|
@@ -4505,12 +4525,65 @@ function getChromeStyle(state) {
|
|
|
4505
4525
|
case "dragging":
|
|
4506
4526
|
return {
|
|
4507
4527
|
border: `2px solid ${PRIMARY}`,
|
|
4508
|
-
boxShadow: DRAG_SHADOW
|
|
4528
|
+
boxShadow: `${FOCUS_RING}, ${DRAG_SHADOW}`
|
|
4509
4529
|
};
|
|
4510
4530
|
default:
|
|
4511
4531
|
return {};
|
|
4512
4532
|
}
|
|
4513
4533
|
}
|
|
4534
|
+
function ClampedToolbarSlot({
|
|
4535
|
+
placement,
|
|
4536
|
+
children
|
|
4537
|
+
}) {
|
|
4538
|
+
const slotRef = React5.useRef(null);
|
|
4539
|
+
React5.useLayoutEffect(() => {
|
|
4540
|
+
const slot = slotRef.current;
|
|
4541
|
+
if (!slot) return;
|
|
4542
|
+
const clamp = () => {
|
|
4543
|
+
const toolbar = slot.firstElementChild;
|
|
4544
|
+
if (!toolbar) return;
|
|
4545
|
+
const w = toolbar.offsetWidth;
|
|
4546
|
+
if (w <= 0) return;
|
|
4547
|
+
const parent = slot.offsetParent;
|
|
4548
|
+
if (!parent) return;
|
|
4549
|
+
const parentRect = parent.getBoundingClientRect();
|
|
4550
|
+
const centerX = parentRect.left + parentRect.width / 2;
|
|
4551
|
+
const half = w / 2;
|
|
4552
|
+
const clampedCenter = Math.max(
|
|
4553
|
+
TOOLBAR_EDGE_MARGIN + half,
|
|
4554
|
+
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN - half)
|
|
4555
|
+
);
|
|
4556
|
+
const offsetX = clampedCenter - centerX;
|
|
4557
|
+
slot.style.transform = `translateX(calc(-50% + ${offsetX}px))`;
|
|
4558
|
+
};
|
|
4559
|
+
clamp();
|
|
4560
|
+
const ro = new ResizeObserver(clamp);
|
|
4561
|
+
ro.observe(slot);
|
|
4562
|
+
if (slot.firstElementChild) ro.observe(slot.firstElementChild);
|
|
4563
|
+
window.addEventListener("resize", clamp);
|
|
4564
|
+
return () => {
|
|
4565
|
+
ro.disconnect();
|
|
4566
|
+
window.removeEventListener("resize", clamp);
|
|
4567
|
+
};
|
|
4568
|
+
}, [placement, children]);
|
|
4569
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4570
|
+
"div",
|
|
4571
|
+
{
|
|
4572
|
+
ref: slotRef,
|
|
4573
|
+
className: cn(
|
|
4574
|
+
"pointer-events-auto absolute left-1/2",
|
|
4575
|
+
placement === "top" ? "bottom-full" : "top-full"
|
|
4576
|
+
),
|
|
4577
|
+
style: {
|
|
4578
|
+
marginBottom: placement === "top" ? TOOLBAR_STROKE_GAP : void 0,
|
|
4579
|
+
marginTop: placement === "bottom" ? TOOLBAR_STROKE_GAP : void 0,
|
|
4580
|
+
transform: "translateX(-50%)"
|
|
4581
|
+
},
|
|
4582
|
+
"data-ohw-item-toolbar-anchor": placement,
|
|
4583
|
+
children
|
|
4584
|
+
}
|
|
4585
|
+
);
|
|
4586
|
+
}
|
|
4514
4587
|
function ItemInteractionLayer({
|
|
4515
4588
|
rect,
|
|
4516
4589
|
state,
|
|
@@ -4521,14 +4594,18 @@ function ItemInteractionLayer({
|
|
|
4521
4594
|
dragHandleLabel = "Reorder item",
|
|
4522
4595
|
onDragHandleDragStart,
|
|
4523
4596
|
onDragHandleDragEnd,
|
|
4524
|
-
|
|
4597
|
+
onItemPointerDown,
|
|
4598
|
+
onItemClick,
|
|
4599
|
+
itemDragSurface = true,
|
|
4600
|
+
chromeGap = SELECTION_CHROME_GAP,
|
|
4525
4601
|
className
|
|
4526
4602
|
}) {
|
|
4527
4603
|
if (state === "default") return null;
|
|
4528
4604
|
const isActive = state === "active-top" || state === "active-bottom";
|
|
4529
4605
|
const isDragging = state === "dragging";
|
|
4530
4606
|
const showToolbar = isActive && toolbar;
|
|
4531
|
-
const showDragHandle = isActive
|
|
4607
|
+
const showDragHandle = (isActive || isDragging) && showHandle;
|
|
4608
|
+
const itemDragEnabled = itemDragSurface && isActive && showHandle && !isDragging && !dragDisabled;
|
|
4532
4609
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4533
4610
|
"div",
|
|
4534
4611
|
{
|
|
@@ -4542,7 +4619,7 @@ function ItemInteractionLayer({
|
|
|
4542
4619
|
left: rect.left - chromeGap,
|
|
4543
4620
|
width: rect.width + chromeGap * 2,
|
|
4544
4621
|
height: rect.height + chromeGap * 2,
|
|
4545
|
-
zIndex:
|
|
4622
|
+
zIndex: getChromeZIndex(state)
|
|
4546
4623
|
},
|
|
4547
4624
|
children: [
|
|
4548
4625
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
@@ -4553,11 +4630,29 @@ function ItemInteractionLayer({
|
|
|
4553
4630
|
style: getChromeStyle(state)
|
|
4554
4631
|
}
|
|
4555
4632
|
),
|
|
4633
|
+
itemDragEnabled && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4634
|
+
"div",
|
|
4635
|
+
{
|
|
4636
|
+
"data-ohw-item-drag-surface": "",
|
|
4637
|
+
className: "pointer-events-auto absolute inset-0 cursor-text rounded-lg",
|
|
4638
|
+
onPointerDown: (e) => {
|
|
4639
|
+
if (e.button !== 0) return;
|
|
4640
|
+
onItemPointerDown?.(e);
|
|
4641
|
+
},
|
|
4642
|
+
onClick: (e) => {
|
|
4643
|
+
e.preventDefault();
|
|
4644
|
+
e.stopPropagation();
|
|
4645
|
+
onItemClick?.(e.clientX, e.clientY);
|
|
4646
|
+
}
|
|
4647
|
+
}
|
|
4648
|
+
),
|
|
4556
4649
|
showDragHandle && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4557
4650
|
"div",
|
|
4558
4651
|
{
|
|
4559
4652
|
"data-ohw-drag-handle-container": "",
|
|
4560
|
-
className: "pointer-events-auto absolute left-0 top-1/2 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4653
|
+
className: "pointer-events-auto absolute left-0 top-1/2 z-10 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4654
|
+
style: isDragging ? { opacity: 0 } : void 0,
|
|
4655
|
+
"aria-hidden": isDragging || void 0,
|
|
4561
4656
|
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4562
4657
|
DragHandle,
|
|
4563
4658
|
{
|
|
@@ -4569,7 +4664,17 @@ function ItemInteractionLayer({
|
|
|
4569
4664
|
e.preventDefault();
|
|
4570
4665
|
return;
|
|
4571
4666
|
}
|
|
4572
|
-
|
|
4667
|
+
const blank = document.createElement("canvas");
|
|
4668
|
+
blank.width = 1;
|
|
4669
|
+
blank.height = 1;
|
|
4670
|
+
blank.style.cssText = "position:fixed;left:-9999px;top:-9999px;width:1px;height:1px;pointer-events:none";
|
|
4671
|
+
document.body.appendChild(blank);
|
|
4672
|
+
try {
|
|
4673
|
+
e.dataTransfer.setDragImage(blank, 0, 0);
|
|
4674
|
+
} finally {
|
|
4675
|
+
requestAnimationFrame(() => blank.remove());
|
|
4676
|
+
}
|
|
4677
|
+
e.dataTransfer.setData("text/plain", dragHandleLabel);
|
|
4573
4678
|
e.dataTransfer.effectAllowed = "move";
|
|
4574
4679
|
onDragHandleDragStart?.(e);
|
|
4575
4680
|
},
|
|
@@ -4578,33 +4683,19 @@ function ItemInteractionLayer({
|
|
|
4578
4683
|
)
|
|
4579
4684
|
}
|
|
4580
4685
|
),
|
|
4581
|
-
showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4582
|
-
|
|
4583
|
-
{
|
|
4584
|
-
className: "pointer-events-auto absolute bottom-full left-1/2 mb-2 -translate-x-1/2",
|
|
4585
|
-
"data-ohw-item-toolbar-anchor": "top",
|
|
4586
|
-
children: toolbar
|
|
4587
|
-
}
|
|
4588
|
-
),
|
|
4589
|
-
showToolbar && state === "active-bottom" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4590
|
-
"div",
|
|
4591
|
-
{
|
|
4592
|
-
className: "pointer-events-auto absolute left-1/2 top-full mt-2 -translate-x-1/2",
|
|
4593
|
-
"data-ohw-item-toolbar-anchor": "bottom",
|
|
4594
|
-
children: toolbar
|
|
4595
|
-
}
|
|
4596
|
-
)
|
|
4686
|
+
showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ClampedToolbarSlot, { placement: "top", children: toolbar }),
|
|
4687
|
+
showToolbar && state === "active-bottom" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ClampedToolbarSlot, { placement: "bottom", children: toolbar })
|
|
4597
4688
|
]
|
|
4598
4689
|
}
|
|
4599
4690
|
);
|
|
4600
4691
|
}
|
|
4601
4692
|
|
|
4602
4693
|
// src/ui/MediaOverlay.tsx
|
|
4603
|
-
var
|
|
4694
|
+
var React7 = __toESM(require("react"), 1);
|
|
4604
4695
|
var import_lucide_react3 = require("lucide-react");
|
|
4605
4696
|
|
|
4606
4697
|
// src/ui/button.tsx
|
|
4607
|
-
var
|
|
4698
|
+
var React6 = __toESM(require("react"), 1);
|
|
4608
4699
|
var import_radix_ui4 = require("radix-ui");
|
|
4609
4700
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4610
4701
|
var buttonVariants = cva(
|
|
@@ -4627,7 +4718,7 @@ var buttonVariants = cva(
|
|
|
4627
4718
|
}
|
|
4628
4719
|
}
|
|
4629
4720
|
);
|
|
4630
|
-
var Button =
|
|
4721
|
+
var Button = React6.forwardRef(
|
|
4631
4722
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
4632
4723
|
const Comp = asChild ? import_radix_ui4.Slot.Root : "button";
|
|
4633
4724
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
@@ -4679,7 +4770,7 @@ function MediaOverlay({
|
|
|
4679
4770
|
onVideoSettingsChange
|
|
4680
4771
|
}) {
|
|
4681
4772
|
const { rect } = hover;
|
|
4682
|
-
const skeletonRef =
|
|
4773
|
+
const skeletonRef = React7.useRef(null);
|
|
4683
4774
|
const isVideo = hover.elementType === "video";
|
|
4684
4775
|
const autoplay = hover.videoAutoplay ?? true;
|
|
4685
4776
|
const muted = hover.videoMuted ?? true;
|
|
@@ -4691,7 +4782,7 @@ function MediaOverlay({
|
|
|
4691
4782
|
height: rect.height,
|
|
4692
4783
|
zIndex: 2147483646
|
|
4693
4784
|
};
|
|
4694
|
-
|
|
4785
|
+
React7.useEffect(() => {
|
|
4695
4786
|
if (!isUploading || !fadingOut || !skeletonRef.current) return;
|
|
4696
4787
|
const anim = skeletonRef.current.animate([{ opacity: 1 }, { opacity: 0 }], {
|
|
4697
4788
|
duration: MEDIA_UPLOAD_FADE_MS,
|
|
@@ -5096,7 +5187,7 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
5096
5187
|
var import_react7 = require("react");
|
|
5097
5188
|
|
|
5098
5189
|
// src/ui/dialog.tsx
|
|
5099
|
-
var
|
|
5190
|
+
var React8 = __toESM(require("react"), 1);
|
|
5100
5191
|
var import_radix_ui5 = require("radix-ui");
|
|
5101
5192
|
var import_lucide_react4 = require("lucide-react");
|
|
5102
5193
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
@@ -5124,7 +5215,7 @@ function DialogOverlay({
|
|
|
5124
5215
|
}
|
|
5125
5216
|
);
|
|
5126
5217
|
}
|
|
5127
|
-
var DialogContent =
|
|
5218
|
+
var DialogContent = React8.forwardRef(
|
|
5128
5219
|
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5129
5220
|
const positionMode = container ? "absolute" : "fixed";
|
|
5130
5221
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
@@ -5179,7 +5270,7 @@ function DialogFooter({
|
|
|
5179
5270
|
}
|
|
5180
5271
|
);
|
|
5181
5272
|
}
|
|
5182
|
-
var DialogTitle =
|
|
5273
|
+
var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5183
5274
|
import_radix_ui5.Dialog.Title,
|
|
5184
5275
|
{
|
|
5185
5276
|
ref,
|
|
@@ -5191,7 +5282,7 @@ var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
5191
5282
|
}
|
|
5192
5283
|
));
|
|
5193
5284
|
DialogTitle.displayName = import_radix_ui5.Dialog.Title.displayName;
|
|
5194
|
-
var DialogDescription =
|
|
5285
|
+
var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5195
5286
|
import_radix_ui5.Dialog.Description,
|
|
5196
5287
|
{
|
|
5197
5288
|
ref,
|
|
@@ -5296,9 +5387,9 @@ function SectionTreeItem({
|
|
|
5296
5387
|
var import_react4 = require("react");
|
|
5297
5388
|
|
|
5298
5389
|
// src/ui/input.tsx
|
|
5299
|
-
var
|
|
5390
|
+
var React9 = __toESM(require("react"), 1);
|
|
5300
5391
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
5301
|
-
var Input =
|
|
5392
|
+
var Input = React9.forwardRef(
|
|
5302
5393
|
({ className, type, ...props }, ref) => {
|
|
5303
5394
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5304
5395
|
"input",
|
|
@@ -6279,9 +6370,155 @@ function shouldUseDevFixtures() {
|
|
|
6279
6370
|
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
6280
6371
|
}
|
|
6281
6372
|
|
|
6373
|
+
// src/lib/nav-tree.ts
|
|
6374
|
+
var MAX_LEVEL = { nav: 1 };
|
|
6375
|
+
var ROOT = null;
|
|
6376
|
+
function cloneForest(nodes) {
|
|
6377
|
+
return nodes.map((n) => ({ id: n.id, children: cloneForest(n.children) }));
|
|
6378
|
+
}
|
|
6379
|
+
function findNode(nodes, id, parentId = ROOT) {
|
|
6380
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
6381
|
+
const node = nodes[i];
|
|
6382
|
+
if (node.id === id) return { node, parentId, index: i, siblings: nodes };
|
|
6383
|
+
const nested = findNode(node.children, id, node.id);
|
|
6384
|
+
if (nested) return nested;
|
|
6385
|
+
}
|
|
6386
|
+
return null;
|
|
6387
|
+
}
|
|
6388
|
+
function getChildrenOf(nodes, parentId) {
|
|
6389
|
+
if (parentId === ROOT) return nodes;
|
|
6390
|
+
const found = findNode(nodes, parentId);
|
|
6391
|
+
return found ? found.node.children : null;
|
|
6392
|
+
}
|
|
6393
|
+
function isDescendant(nodes, ancestorId, maybeDescendantId) {
|
|
6394
|
+
const found = findNode(nodes, ancestorId);
|
|
6395
|
+
if (!found) return false;
|
|
6396
|
+
return findNode(found.node.children, maybeDescendantId) !== null;
|
|
6397
|
+
}
|
|
6398
|
+
function levelOf(nodes, id) {
|
|
6399
|
+
const loc = findNode(nodes, id);
|
|
6400
|
+
if (!loc) return -1;
|
|
6401
|
+
if (loc.parentId === ROOT) return 0;
|
|
6402
|
+
return 1 + Math.max(0, levelOf(nodes, loc.parentId));
|
|
6403
|
+
}
|
|
6404
|
+
function insertedLevel(nodes, parentId) {
|
|
6405
|
+
if (parentId === ROOT) return 0;
|
|
6406
|
+
const parentLevel = levelOf(nodes, parentId);
|
|
6407
|
+
if (parentLevel < 0) return -1;
|
|
6408
|
+
return parentLevel + 1;
|
|
6409
|
+
}
|
|
6410
|
+
function takeNode(nodes, id) {
|
|
6411
|
+
const forest = cloneForest(nodes);
|
|
6412
|
+
const loc = findNode(forest, id);
|
|
6413
|
+
if (!loc) return null;
|
|
6414
|
+
const [taken] = loc.siblings.splice(loc.index, 1);
|
|
6415
|
+
if (!taken) return null;
|
|
6416
|
+
return { forest, taken };
|
|
6417
|
+
}
|
|
6418
|
+
function insertInto(forest, node, parentId, index) {
|
|
6419
|
+
const siblings = getChildrenOf(forest, parentId);
|
|
6420
|
+
if (!siblings) return false;
|
|
6421
|
+
const clamped = Math.max(0, Math.min(index, siblings.length));
|
|
6422
|
+
siblings.splice(clamped, 0, node);
|
|
6423
|
+
return true;
|
|
6424
|
+
}
|
|
6425
|
+
function normalize(nodes) {
|
|
6426
|
+
const walk = (list) => list.map((n) => {
|
|
6427
|
+
const children = walk(n.children);
|
|
6428
|
+
return { id: n.id, children };
|
|
6429
|
+
});
|
|
6430
|
+
return walk(nodes);
|
|
6431
|
+
}
|
|
6432
|
+
function moveNode(model, draggedId, target) {
|
|
6433
|
+
const { parentId, index: targetIndex } = target;
|
|
6434
|
+
if (parentId === draggedId) return null;
|
|
6435
|
+
if (parentId !== ROOT && isDescendant(model, draggedId, parentId)) return null;
|
|
6436
|
+
const nextLevel = insertedLevel(model, parentId);
|
|
6437
|
+
if (nextLevel < 0 || nextLevel > MAX_LEVEL.nav) return null;
|
|
6438
|
+
const draggedLoc = findNode(model, draggedId);
|
|
6439
|
+
if (!draggedLoc) return null;
|
|
6440
|
+
if (parentId !== ROOT && draggedLoc.node.children.length > 0) return null;
|
|
6441
|
+
const taken = takeNode(model, draggedId);
|
|
6442
|
+
if (!taken) return null;
|
|
6443
|
+
let insertIndex = targetIndex;
|
|
6444
|
+
if (draggedLoc.parentId === parentId && draggedLoc.index < targetIndex) {
|
|
6445
|
+
insertIndex -= 1;
|
|
6446
|
+
}
|
|
6447
|
+
if (!insertInto(taken.forest, taken.taken, parentId, insertIndex)) return null;
|
|
6448
|
+
const next = normalize(taken.forest);
|
|
6449
|
+
if (forestsEqual(model, next)) return null;
|
|
6450
|
+
return next;
|
|
6451
|
+
}
|
|
6452
|
+
function forestsEqual(a, b) {
|
|
6453
|
+
if (a.length !== b.length) return false;
|
|
6454
|
+
for (let i = 0; i < a.length; i++) {
|
|
6455
|
+
const left = a[i];
|
|
6456
|
+
const right = b[i];
|
|
6457
|
+
if (left.id !== right.id) return false;
|
|
6458
|
+
if (!forestsEqual(left.children, right.children)) return false;
|
|
6459
|
+
}
|
|
6460
|
+
return true;
|
|
6461
|
+
}
|
|
6462
|
+
function forestFromFlatOrder(order) {
|
|
6463
|
+
return order.map((id) => ({ id, children: [] }));
|
|
6464
|
+
}
|
|
6465
|
+
function serializeNavOrder(nodes) {
|
|
6466
|
+
const hasNesting = nodes.some((n) => n.children.length > 0);
|
|
6467
|
+
if (!hasNesting) {
|
|
6468
|
+
return JSON.stringify(nodes.map((n) => n.id));
|
|
6469
|
+
}
|
|
6470
|
+
return JSON.stringify(nodes);
|
|
6471
|
+
}
|
|
6472
|
+
function parseNavOrderJson(raw) {
|
|
6473
|
+
if (!raw) return null;
|
|
6474
|
+
try {
|
|
6475
|
+
const parsed = JSON.parse(raw);
|
|
6476
|
+
if (!Array.isArray(parsed)) return null;
|
|
6477
|
+
if (parsed.every((x) => typeof x === "string")) {
|
|
6478
|
+
return forestFromFlatOrder(parsed.filter((x) => typeof x === "string" && x.length > 0));
|
|
6479
|
+
}
|
|
6480
|
+
return parseNavNodeList(parsed);
|
|
6481
|
+
} catch {
|
|
6482
|
+
return null;
|
|
6483
|
+
}
|
|
6484
|
+
}
|
|
6485
|
+
function parseNavNodeList(raw) {
|
|
6486
|
+
const out = [];
|
|
6487
|
+
for (const item of raw) {
|
|
6488
|
+
if (typeof item === "string" && item.length > 0) {
|
|
6489
|
+
out.push({ id: item, children: [] });
|
|
6490
|
+
continue;
|
|
6491
|
+
}
|
|
6492
|
+
if (!item || typeof item !== "object") return null;
|
|
6493
|
+
const rec = item;
|
|
6494
|
+
if (typeof rec.id !== "string" || !rec.id) return null;
|
|
6495
|
+
const children = Array.isArray(rec.children) ? parseNavNodeList(rec.children) : [];
|
|
6496
|
+
if (!children) return null;
|
|
6497
|
+
out.push({ id: rec.id, children });
|
|
6498
|
+
}
|
|
6499
|
+
return out;
|
|
6500
|
+
}
|
|
6501
|
+
function flattenNavOrder(nodes) {
|
|
6502
|
+
const out = [];
|
|
6503
|
+
const walk = (list) => {
|
|
6504
|
+
for (const n of list) {
|
|
6505
|
+
out.push(n.id);
|
|
6506
|
+
walk(n.children);
|
|
6507
|
+
}
|
|
6508
|
+
};
|
|
6509
|
+
walk(nodes);
|
|
6510
|
+
return out;
|
|
6511
|
+
}
|
|
6512
|
+
|
|
6282
6513
|
// src/lib/nav-items.ts
|
|
6283
6514
|
var NAV_COUNT_KEY = "__ohw_nav_count";
|
|
6284
6515
|
var NAV_ORDER_KEY = "__ohw_nav_order";
|
|
6516
|
+
var NAV_HREF_RE = /^nav-(\d+)-href$/;
|
|
6517
|
+
function isNavbarHrefKey(key) {
|
|
6518
|
+
if (!key) return false;
|
|
6519
|
+
if (key === "nav-book-href") return false;
|
|
6520
|
+
return NAV_HREF_RE.test(key);
|
|
6521
|
+
}
|
|
6285
6522
|
function getLinkHref(el) {
|
|
6286
6523
|
const key = el.getAttribute("data-ohw-href-key");
|
|
6287
6524
|
if (key) {
|
|
@@ -6318,7 +6555,7 @@ function listNavbarItems() {
|
|
|
6318
6555
|
}
|
|
6319
6556
|
function parseNavIndexFromKey(key) {
|
|
6320
6557
|
if (!key) return null;
|
|
6321
|
-
const match = key.match(
|
|
6558
|
+
const match = key.match(NAV_HREF_RE);
|
|
6322
6559
|
if (!match) return null;
|
|
6323
6560
|
return parseInt(match[1], 10);
|
|
6324
6561
|
}
|
|
@@ -6341,17 +6578,6 @@ function getNavbarExistingTargets() {
|
|
|
6341
6578
|
function getNavOrderFromDom() {
|
|
6342
6579
|
return listNavbarItems().map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6343
6580
|
}
|
|
6344
|
-
function parseNavOrder(content) {
|
|
6345
|
-
const raw = content[NAV_ORDER_KEY];
|
|
6346
|
-
if (!raw) return null;
|
|
6347
|
-
try {
|
|
6348
|
-
const parsed = JSON.parse(raw);
|
|
6349
|
-
if (!Array.isArray(parsed)) return null;
|
|
6350
|
-
return parsed.filter((key) => typeof key === "string" && key.length > 0);
|
|
6351
|
-
} catch {
|
|
6352
|
-
return null;
|
|
6353
|
-
}
|
|
6354
|
-
}
|
|
6355
6581
|
function findCounterpartByHrefKey(hrefKey, root) {
|
|
6356
6582
|
return root.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
6357
6583
|
}
|
|
@@ -6415,19 +6641,43 @@ function insertNavbarItemDom(index, href, label, afterAnchor) {
|
|
|
6415
6641
|
}
|
|
6416
6642
|
return primary;
|
|
6417
6643
|
}
|
|
6644
|
+
function navOrderKeysEqual(a, b) {
|
|
6645
|
+
if (a.length !== b.length) return false;
|
|
6646
|
+
for (let i = 0; i < a.length; i++) {
|
|
6647
|
+
if (a[i] !== b[i]) return false;
|
|
6648
|
+
}
|
|
6649
|
+
return true;
|
|
6650
|
+
}
|
|
6651
|
+
function getNavbarLinkKeysInContainer(container) {
|
|
6652
|
+
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6653
|
+
}
|
|
6418
6654
|
function applyNavOrderToContainer(container, order) {
|
|
6655
|
+
const desired = order.filter((key, i) => order.indexOf(key) === i);
|
|
6656
|
+
const current = getNavbarLinkKeysInContainer(container);
|
|
6657
|
+
const extras = current.filter((key) => !desired.includes(key));
|
|
6658
|
+
const expected = [...desired.filter((key) => current.includes(key)), ...extras];
|
|
6659
|
+
const orderedEls = [];
|
|
6660
|
+
if (navOrderKeysEqual(current, expected)) return;
|
|
6661
|
+
if (current.length === expected.length && current.every((key, i) => key === expected[i])) {
|
|
6662
|
+
return;
|
|
6663
|
+
}
|
|
6419
6664
|
const seen = /* @__PURE__ */ new Set();
|
|
6420
|
-
for (const hrefKey of
|
|
6665
|
+
for (const hrefKey of desired) {
|
|
6421
6666
|
if (seen.has(hrefKey)) continue;
|
|
6422
6667
|
seen.add(hrefKey);
|
|
6423
6668
|
const el = findCounterpartByHrefKey(hrefKey, container);
|
|
6424
|
-
if (el)
|
|
6669
|
+
if (el && isNavbarLinkItem(el)) orderedEls.push(el);
|
|
6425
6670
|
}
|
|
6426
6671
|
for (const el of container.querySelectorAll("[data-ohw-href-key]")) {
|
|
6427
6672
|
if (!isNavbarLinkItem(el)) continue;
|
|
6428
6673
|
const key = el.getAttribute("data-ohw-href-key");
|
|
6429
6674
|
if (!key || seen.has(key)) continue;
|
|
6430
|
-
|
|
6675
|
+
orderedEls.push(el);
|
|
6676
|
+
}
|
|
6677
|
+
for (const el of orderedEls) {
|
|
6678
|
+
if (container.lastElementChild !== el) {
|
|
6679
|
+
container.appendChild(el);
|
|
6680
|
+
}
|
|
6431
6681
|
}
|
|
6432
6682
|
}
|
|
6433
6683
|
function applyNavOrder(order) {
|
|
@@ -6436,6 +6686,75 @@ function applyNavOrder(order) {
|
|
|
6436
6686
|
const drawer = getNavbarDrawerContainer();
|
|
6437
6687
|
if (drawer) applyNavOrderToContainer(drawer, order);
|
|
6438
6688
|
}
|
|
6689
|
+
function applyChildrenOrder(parentHrefKey, childKeys, root) {
|
|
6690
|
+
const parent = findCounterpartByHrefKey(parentHrefKey, root);
|
|
6691
|
+
if (!parent) return;
|
|
6692
|
+
const group = parent.closest("[data-ohw-nav-group]");
|
|
6693
|
+
const childrenRoot = group?.querySelector(":scope > [data-ohw-nav-children]");
|
|
6694
|
+
if (!childrenRoot) return;
|
|
6695
|
+
const current = Array.from(childrenRoot.querySelectorAll(":scope > [data-ohw-href-key]")).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6696
|
+
if (navOrderKeysEqual(current, childKeys)) return;
|
|
6697
|
+
for (const key of childKeys) {
|
|
6698
|
+
const el = findCounterpartByHrefKey(key, root);
|
|
6699
|
+
if (!el) continue;
|
|
6700
|
+
if (childrenRoot.lastElementChild !== el) {
|
|
6701
|
+
childrenRoot.appendChild(el);
|
|
6702
|
+
}
|
|
6703
|
+
}
|
|
6704
|
+
}
|
|
6705
|
+
function applyNavForest(forest) {
|
|
6706
|
+
if (forestsEqual(forest, getNavForestFromDom())) return;
|
|
6707
|
+
const rootKeys = forest.map((n) => n.id);
|
|
6708
|
+
applyNavOrder(rootKeys);
|
|
6709
|
+
const desktop = getNavbarDesktopContainer();
|
|
6710
|
+
const drawer = getNavbarDrawerContainer();
|
|
6711
|
+
for (const node of forest) {
|
|
6712
|
+
if (node.children.length === 0) continue;
|
|
6713
|
+
const childKeys = node.children.map((c) => c.id);
|
|
6714
|
+
if (desktop) applyChildrenOrder(node.id, childKeys, desktop);
|
|
6715
|
+
if (drawer) applyChildrenOrder(node.id, childKeys, drawer);
|
|
6716
|
+
}
|
|
6717
|
+
}
|
|
6718
|
+
function getNavForestFromDom() {
|
|
6719
|
+
const items = listNavbarItems();
|
|
6720
|
+
const nestedChildKeys = /* @__PURE__ */ new Set();
|
|
6721
|
+
const roots = [];
|
|
6722
|
+
for (const item of items) {
|
|
6723
|
+
const key = item.getAttribute("data-ohw-href-key");
|
|
6724
|
+
if (!key || !isNavbarHrefKey(key)) continue;
|
|
6725
|
+
if (item.closest("[data-ohw-nav-children]")) continue;
|
|
6726
|
+
const group = item.closest("[data-ohw-nav-group]");
|
|
6727
|
+
const childrenRoot = group?.querySelector(":scope > [data-ohw-nav-children]");
|
|
6728
|
+
const children = [];
|
|
6729
|
+
if (childrenRoot) {
|
|
6730
|
+
for (const child of childrenRoot.querySelectorAll(":scope > [data-ohw-href-key]")) {
|
|
6731
|
+
if (!isNavbarLinkItem(child)) continue;
|
|
6732
|
+
const childKey = child.getAttribute("data-ohw-href-key");
|
|
6733
|
+
if (!childKey || !isNavbarHrefKey(childKey)) continue;
|
|
6734
|
+
nestedChildKeys.add(childKey);
|
|
6735
|
+
children.push({ id: childKey, children: [] });
|
|
6736
|
+
}
|
|
6737
|
+
}
|
|
6738
|
+
roots.push({ id: key, children });
|
|
6739
|
+
}
|
|
6740
|
+
if (roots.length === 0) {
|
|
6741
|
+
return forestFromFlatOrder(
|
|
6742
|
+
getNavOrderFromDom().filter((k) => isNavbarHrefKey(k) && !nestedChildKeys.has(k))
|
|
6743
|
+
);
|
|
6744
|
+
}
|
|
6745
|
+
return roots;
|
|
6746
|
+
}
|
|
6747
|
+
function planNavItemMove(hrefKey, parentId, insertIndex) {
|
|
6748
|
+
const model = getNavForestFromDom();
|
|
6749
|
+
const next = moveNode(model, hrefKey, { parentId, index: insertIndex });
|
|
6750
|
+
if (!next) return null;
|
|
6751
|
+
if (forestsEqual(model, next)) return null;
|
|
6752
|
+
return {
|
|
6753
|
+
forest: next,
|
|
6754
|
+
orderJson: serializeNavOrder(next),
|
|
6755
|
+
flatOrder: flattenNavOrder(next)
|
|
6756
|
+
};
|
|
6757
|
+
}
|
|
6439
6758
|
function collectNavbarIndicesFromContent(content) {
|
|
6440
6759
|
const indices = /* @__PURE__ */ new Set();
|
|
6441
6760
|
for (const key of Object.keys(content)) {
|
|
@@ -6463,8 +6782,10 @@ function reconcileNavbarItemsFromContent(content) {
|
|
|
6463
6782
|
if (!href && !label) continue;
|
|
6464
6783
|
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
6465
6784
|
}
|
|
6466
|
-
const
|
|
6467
|
-
if (
|
|
6785
|
+
const orderForest = parseNavOrderJson(content[NAV_ORDER_KEY]);
|
|
6786
|
+
if (orderForest?.length) {
|
|
6787
|
+
applyNavForest(orderForest);
|
|
6788
|
+
}
|
|
6468
6789
|
}
|
|
6469
6790
|
function buildNavOrderAfterInsert(afterAnchor, newHrefKey) {
|
|
6470
6791
|
const order = getNavOrderFromDom();
|
|
@@ -6504,133 +6825,1023 @@ function insertNavbarItem(href, label, afterAnchor = null) {
|
|
|
6504
6825
|
};
|
|
6505
6826
|
}
|
|
6506
6827
|
|
|
6507
|
-
// src/
|
|
6508
|
-
var
|
|
6509
|
-
var
|
|
6510
|
-
function
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6516
|
-
"div",
|
|
6517
|
-
{
|
|
6518
|
-
"data-ohw-navbar-container-chrome": "",
|
|
6519
|
-
"data-ohw-bridge": "",
|
|
6520
|
-
className: "pointer-events-none fixed z-[2147483647]",
|
|
6521
|
-
style: {
|
|
6522
|
-
top: rect.top - chromeGap,
|
|
6523
|
-
left: rect.left - chromeGap,
|
|
6524
|
-
width: rect.width + chromeGap * 2,
|
|
6525
|
-
height: rect.height + chromeGap * 2
|
|
6526
|
-
},
|
|
6527
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6528
|
-
"button",
|
|
6529
|
-
{
|
|
6530
|
-
type: "button",
|
|
6531
|
-
"data-ohw-navbar-add-button": "",
|
|
6532
|
-
className: "pointer-events-auto absolute left-1/2 flex p-0.5 rounded-[10px] size-7 -translate-x-1/2 translate-y-1/2 items-center justify-center border border-border bg-background shadow-sm transition-colors hover:bg-muted/80",
|
|
6533
|
-
style: { top: "70%" },
|
|
6534
|
-
"aria-label": "Add item",
|
|
6535
|
-
onMouseDown: (e) => {
|
|
6536
|
-
e.preventDefault();
|
|
6537
|
-
e.stopPropagation();
|
|
6538
|
-
},
|
|
6539
|
-
onClick: (e) => {
|
|
6540
|
-
e.preventDefault();
|
|
6541
|
-
e.stopPropagation();
|
|
6542
|
-
onAdd();
|
|
6543
|
-
},
|
|
6544
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
6545
|
-
}
|
|
6546
|
-
)
|
|
6547
|
-
}
|
|
6548
|
-
);
|
|
6828
|
+
// src/lib/footer-items.ts
|
|
6829
|
+
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
6830
|
+
var FOOTER_HREF_RE = /^footer-(\d+)-(\d+)-href$/;
|
|
6831
|
+
function parseFooterHrefKey(key) {
|
|
6832
|
+
if (!key) return null;
|
|
6833
|
+
const match = key.match(FOOTER_HREF_RE);
|
|
6834
|
+
if (!match) return null;
|
|
6835
|
+
return { col: parseInt(match[1], 10), item: parseInt(match[2], 10) };
|
|
6549
6836
|
}
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
6553
|
-
var badgeVariants = cva(
|
|
6554
|
-
"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",
|
|
6555
|
-
{
|
|
6556
|
-
variants: {
|
|
6557
|
-
variant: {
|
|
6558
|
-
default: "border-transparent bg-primary text-primary-foreground",
|
|
6559
|
-
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
6560
|
-
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
6561
|
-
outline: "text-foreground"
|
|
6562
|
-
}
|
|
6563
|
-
},
|
|
6564
|
-
defaultVariants: {
|
|
6565
|
-
variant: "default"
|
|
6566
|
-
}
|
|
6567
|
-
}
|
|
6568
|
-
);
|
|
6569
|
-
function Badge({ className, variant, ...props }) {
|
|
6570
|
-
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
6837
|
+
function isFooterHrefKey(key) {
|
|
6838
|
+
return parseFooterHrefKey(key) !== null;
|
|
6571
6839
|
}
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
var import_lucide_react11 = require("lucide-react");
|
|
6575
|
-
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
6576
|
-
var PRIMARY2 = "#0885FE";
|
|
6577
|
-
var IMAGE_FADE_MS = 300;
|
|
6578
|
-
function runOpacityFade(el, onDone) {
|
|
6579
|
-
const anim = el.animate([{ opacity: 0 }, { opacity: 1 }], {
|
|
6580
|
-
duration: IMAGE_FADE_MS,
|
|
6581
|
-
easing: "ease",
|
|
6582
|
-
fill: "forwards"
|
|
6583
|
-
});
|
|
6584
|
-
let finished = false;
|
|
6585
|
-
const finish = () => {
|
|
6586
|
-
if (finished) return;
|
|
6587
|
-
finished = true;
|
|
6588
|
-
anim.cancel();
|
|
6589
|
-
el.style.opacity = "";
|
|
6590
|
-
onDone();
|
|
6591
|
-
};
|
|
6592
|
-
anim.finished.then(finish).catch(finish);
|
|
6593
|
-
window.setTimeout(finish, IMAGE_FADE_MS + 100);
|
|
6840
|
+
function getFooterRoot() {
|
|
6841
|
+
return document.querySelector('footer[data-ohw-section="footer"], footer');
|
|
6594
6842
|
}
|
|
6595
|
-
function
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6843
|
+
function getFooterLinksContainer() {
|
|
6844
|
+
return document.querySelector("[data-ohw-footer-links]") ?? document.querySelector(".rb-footer-links");
|
|
6845
|
+
}
|
|
6846
|
+
function isFooterLinkAnchor(el) {
|
|
6847
|
+
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6848
|
+
if (!isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) return false;
|
|
6849
|
+
return Boolean(el.querySelector('[data-ohw-editable="text"]'));
|
|
6850
|
+
}
|
|
6851
|
+
function listFooterColumns() {
|
|
6852
|
+
const root = getFooterLinksContainer() ?? getFooterRoot()?.querySelector(".rb-footer-links") ?? null;
|
|
6853
|
+
if (!root) return [];
|
|
6854
|
+
const explicit = Array.from(root.querySelectorAll(":scope > [data-ohw-footer-col]"));
|
|
6855
|
+
if (explicit.length > 0) return explicit;
|
|
6856
|
+
return Array.from(root.children).filter((el) => {
|
|
6857
|
+
if (!(el instanceof HTMLElement)) return false;
|
|
6858
|
+
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(
|
|
6859
|
+
isFooterLinkAnchor
|
|
6860
|
+
);
|
|
6600
6861
|
});
|
|
6601
6862
|
}
|
|
6602
|
-
function
|
|
6603
|
-
|
|
6604
|
-
|
|
6605
|
-
|
|
6863
|
+
function listFooterLinksInColumn(column) {
|
|
6864
|
+
return Array.from(column.querySelectorAll(":scope > [data-ohw-href-key]")).filter(
|
|
6865
|
+
isFooterLinkAnchor
|
|
6866
|
+
);
|
|
6606
6867
|
}
|
|
6607
|
-
function
|
|
6608
|
-
const
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
layer.remove();
|
|
6628
|
-
if (!prevPos || prevPos === "static") el.style.position = prevPos;
|
|
6868
|
+
function findFooterColumnForLink(anchor) {
|
|
6869
|
+
const columns = listFooterColumns();
|
|
6870
|
+
return columns.find((col) => col.contains(anchor)) ?? null;
|
|
6871
|
+
}
|
|
6872
|
+
function getFooterOrderFromDom() {
|
|
6873
|
+
return listFooterColumns().map(
|
|
6874
|
+
(col) => listFooterLinksInColumn(col).map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key))
|
|
6875
|
+
);
|
|
6876
|
+
}
|
|
6877
|
+
function findFooterLinkByKey(hrefKey) {
|
|
6878
|
+
return document.querySelector(
|
|
6879
|
+
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
6880
|
+
);
|
|
6881
|
+
}
|
|
6882
|
+
function syncFooterColumnIndices(columns) {
|
|
6883
|
+
columns.forEach((col, index) => {
|
|
6884
|
+
const next = String(index);
|
|
6885
|
+
if (col.getAttribute("data-ohw-footer-col") !== next) {
|
|
6886
|
+
col.setAttribute("data-ohw-footer-col", next);
|
|
6887
|
+
}
|
|
6629
6888
|
});
|
|
6630
6889
|
}
|
|
6631
|
-
function
|
|
6632
|
-
|
|
6633
|
-
|
|
6890
|
+
function appendChildIfNeeded(parent, child) {
|
|
6891
|
+
if (parent.lastElementChild !== child) {
|
|
6892
|
+
parent.appendChild(child);
|
|
6893
|
+
}
|
|
6894
|
+
}
|
|
6895
|
+
function applyFooterOrder(order) {
|
|
6896
|
+
const container = getFooterLinksContainer();
|
|
6897
|
+
if (!container) return;
|
|
6898
|
+
const columns = listFooterColumns();
|
|
6899
|
+
if (columns.length === 0) return;
|
|
6900
|
+
const currentOrder = getFooterOrderFromDom();
|
|
6901
|
+
if (ordersEqual(order, currentOrder)) {
|
|
6902
|
+
syncFooterColumnIndices(columns);
|
|
6903
|
+
return;
|
|
6904
|
+
}
|
|
6905
|
+
const used = /* @__PURE__ */ new Set();
|
|
6906
|
+
const orderedCols = [];
|
|
6907
|
+
for (const colOrder of order) {
|
|
6908
|
+
let matched = null;
|
|
6909
|
+
for (const hrefKey of colOrder) {
|
|
6910
|
+
const link = findFooterLinkByKey(hrefKey);
|
|
6911
|
+
if (!link) continue;
|
|
6912
|
+
const owner = findFooterColumnForLink(link);
|
|
6913
|
+
if (owner && !used.has(owner)) {
|
|
6914
|
+
matched = owner;
|
|
6915
|
+
break;
|
|
6916
|
+
}
|
|
6917
|
+
}
|
|
6918
|
+
if (!matched) {
|
|
6919
|
+
matched = columns.find((col) => !used.has(col)) ?? null;
|
|
6920
|
+
}
|
|
6921
|
+
if (matched) {
|
|
6922
|
+
used.add(matched);
|
|
6923
|
+
orderedCols.push(matched);
|
|
6924
|
+
}
|
|
6925
|
+
}
|
|
6926
|
+
for (const col of columns) {
|
|
6927
|
+
if (!used.has(col)) orderedCols.push(col);
|
|
6928
|
+
}
|
|
6929
|
+
for (const col of orderedCols) {
|
|
6930
|
+
appendChildIfNeeded(container, col);
|
|
6931
|
+
}
|
|
6932
|
+
const freshColumns = listFooterColumns();
|
|
6933
|
+
syncFooterColumnIndices(freshColumns);
|
|
6934
|
+
for (let c = 0; c < order.length; c++) {
|
|
6935
|
+
const col = freshColumns[c];
|
|
6936
|
+
if (!col) continue;
|
|
6937
|
+
const colOrder = order[c];
|
|
6938
|
+
for (const hrefKey of colOrder) {
|
|
6939
|
+
const el = findFooterLinkByKey(hrefKey);
|
|
6940
|
+
if (!el) continue;
|
|
6941
|
+
if (el.parentElement !== col || col.lastElementChild !== el) {
|
|
6942
|
+
col.appendChild(el);
|
|
6943
|
+
}
|
|
6944
|
+
}
|
|
6945
|
+
}
|
|
6946
|
+
}
|
|
6947
|
+
function ordersEqual(a, b) {
|
|
6948
|
+
if (a.length !== b.length) return false;
|
|
6949
|
+
for (let i = 0; i < a.length; i++) {
|
|
6950
|
+
const left = a[i];
|
|
6951
|
+
const right = b[i];
|
|
6952
|
+
if (left.length !== right.length) return false;
|
|
6953
|
+
for (let j = 0; j < left.length; j++) {
|
|
6954
|
+
if (left[j] !== right[j]) return false;
|
|
6955
|
+
}
|
|
6956
|
+
}
|
|
6957
|
+
return true;
|
|
6958
|
+
}
|
|
6959
|
+
function planFooterLinkMove(hrefKey, targetColIndex, insertIndex) {
|
|
6960
|
+
const order = getFooterOrderFromDom();
|
|
6961
|
+
if (targetColIndex < 0 || targetColIndex >= order.length) return null;
|
|
6962
|
+
let fromCol = -1;
|
|
6963
|
+
let fromIdx = -1;
|
|
6964
|
+
for (let c = 0; c < order.length; c++) {
|
|
6965
|
+
const idx = order[c].indexOf(hrefKey);
|
|
6966
|
+
if (idx >= 0) {
|
|
6967
|
+
fromCol = c;
|
|
6968
|
+
fromIdx = idx;
|
|
6969
|
+
break;
|
|
6970
|
+
}
|
|
6971
|
+
}
|
|
6972
|
+
if (fromCol < 0) return null;
|
|
6973
|
+
const next = order.map((col) => [...col]);
|
|
6974
|
+
next[fromCol].splice(fromIdx, 1);
|
|
6975
|
+
let adjusted = insertIndex;
|
|
6976
|
+
if (fromCol === targetColIndex && fromIdx < insertIndex) adjusted -= 1;
|
|
6977
|
+
adjusted = Math.max(0, Math.min(adjusted, next[targetColIndex].length));
|
|
6978
|
+
next[targetColIndex].splice(adjusted, 0, hrefKey);
|
|
6979
|
+
if (ordersEqual(next, order)) return null;
|
|
6980
|
+
return next;
|
|
6981
|
+
}
|
|
6982
|
+
function planFooterColumnMove(fromIndex, toIndex) {
|
|
6983
|
+
const order = getFooterOrderFromDom();
|
|
6984
|
+
const columns = listFooterColumns();
|
|
6985
|
+
if (fromIndex < 0 || fromIndex >= columns.length || toIndex < 0 || toIndex > columns.length) {
|
|
6986
|
+
return null;
|
|
6987
|
+
}
|
|
6988
|
+
if (toIndex === fromIndex || toIndex === fromIndex + 1) return null;
|
|
6989
|
+
const nextOrder = order.map((col) => [...col]);
|
|
6990
|
+
const [movedOrder] = nextOrder.splice(fromIndex, 1);
|
|
6991
|
+
if (!movedOrder) return null;
|
|
6992
|
+
let adjusted = toIndex;
|
|
6993
|
+
if (fromIndex < toIndex) adjusted -= 1;
|
|
6994
|
+
adjusted = Math.max(0, Math.min(adjusted, nextOrder.length));
|
|
6995
|
+
nextOrder.splice(adjusted, 0, movedOrder);
|
|
6996
|
+
if (ordersEqual(nextOrder, order)) return null;
|
|
6997
|
+
return nextOrder;
|
|
6998
|
+
}
|
|
6999
|
+
function parseFooterOrder(content) {
|
|
7000
|
+
const raw = content[FOOTER_ORDER_KEY];
|
|
7001
|
+
if (!raw) return null;
|
|
7002
|
+
try {
|
|
7003
|
+
const parsed = JSON.parse(raw);
|
|
7004
|
+
if (!Array.isArray(parsed)) return null;
|
|
7005
|
+
return parsed.filter((col) => Array.isArray(col)).map((col) => col.filter((key) => typeof key === "string" && key.length > 0));
|
|
7006
|
+
} catch {
|
|
7007
|
+
return null;
|
|
7008
|
+
}
|
|
7009
|
+
}
|
|
7010
|
+
function reconcileFooterOrderFromContent(content) {
|
|
7011
|
+
const order = parseFooterOrder(content);
|
|
7012
|
+
if (!order?.length) return;
|
|
7013
|
+
const current = getFooterOrderFromDom();
|
|
7014
|
+
if (ordersEqual(order, current)) {
|
|
7015
|
+
syncFooterColumnIndices(listFooterColumns());
|
|
7016
|
+
return;
|
|
7017
|
+
}
|
|
7018
|
+
applyFooterOrder(order);
|
|
7019
|
+
}
|
|
7020
|
+
function buildLinkDropSlots(column, columnIndex) {
|
|
7021
|
+
const links = listFooterLinksInColumn(column);
|
|
7022
|
+
const colRect = column.getBoundingClientRect();
|
|
7023
|
+
const slots = [];
|
|
7024
|
+
const barThickness = 3;
|
|
7025
|
+
if (links.length === 0) {
|
|
7026
|
+
slots.push({
|
|
7027
|
+
insertIndex: 0,
|
|
7028
|
+
columnIndex,
|
|
7029
|
+
left: colRect.left,
|
|
7030
|
+
top: colRect.top + colRect.height / 2 - barThickness / 2,
|
|
7031
|
+
width: colRect.width,
|
|
7032
|
+
height: barThickness,
|
|
7033
|
+
direction: "horizontal"
|
|
7034
|
+
});
|
|
7035
|
+
return slots;
|
|
7036
|
+
}
|
|
7037
|
+
for (let i = 0; i <= links.length; i++) {
|
|
7038
|
+
let top;
|
|
7039
|
+
if (i === 0) {
|
|
7040
|
+
top = links[0].getBoundingClientRect().top - barThickness / 2;
|
|
7041
|
+
} else if (i === links.length) {
|
|
7042
|
+
const last = links[links.length - 1].getBoundingClientRect();
|
|
7043
|
+
top = last.bottom - barThickness / 2;
|
|
7044
|
+
} else {
|
|
7045
|
+
const prev = links[i - 1].getBoundingClientRect();
|
|
7046
|
+
const next = links[i].getBoundingClientRect();
|
|
7047
|
+
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
7048
|
+
}
|
|
7049
|
+
const widthRef = i === 0 ? links[0].getBoundingClientRect() : i === links.length ? links[links.length - 1].getBoundingClientRect() : links[i].getBoundingClientRect();
|
|
7050
|
+
slots.push({
|
|
7051
|
+
insertIndex: i,
|
|
7052
|
+
columnIndex,
|
|
7053
|
+
left: widthRef.left,
|
|
7054
|
+
top,
|
|
7055
|
+
width: Math.max(widthRef.width, colRect.width * 0.8),
|
|
7056
|
+
height: barThickness,
|
|
7057
|
+
direction: "horizontal"
|
|
7058
|
+
});
|
|
7059
|
+
}
|
|
7060
|
+
return slots;
|
|
7061
|
+
}
|
|
7062
|
+
function buildColumnDropSlots() {
|
|
7063
|
+
const columns = listFooterColumns();
|
|
7064
|
+
const slots = [];
|
|
7065
|
+
const barThickness = 3;
|
|
7066
|
+
if (columns.length === 0) return slots;
|
|
7067
|
+
for (let i = 0; i <= columns.length; i++) {
|
|
7068
|
+
let left;
|
|
7069
|
+
let height;
|
|
7070
|
+
let top;
|
|
7071
|
+
if (i === 0) {
|
|
7072
|
+
const first = columns[0].getBoundingClientRect();
|
|
7073
|
+
left = first.left - barThickness / 2;
|
|
7074
|
+
top = first.top;
|
|
7075
|
+
height = first.height;
|
|
7076
|
+
} else if (i === columns.length) {
|
|
7077
|
+
const last = columns[columns.length - 1].getBoundingClientRect();
|
|
7078
|
+
left = last.right - barThickness / 2;
|
|
7079
|
+
top = last.top;
|
|
7080
|
+
height = last.height;
|
|
7081
|
+
} else {
|
|
7082
|
+
const prev = columns[i - 1].getBoundingClientRect();
|
|
7083
|
+
const next = columns[i].getBoundingClientRect();
|
|
7084
|
+
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
7085
|
+
top = Math.min(prev.top, next.top);
|
|
7086
|
+
height = Math.max(prev.bottom, next.bottom) - top;
|
|
7087
|
+
}
|
|
7088
|
+
slots.push({
|
|
7089
|
+
insertIndex: i,
|
|
7090
|
+
columnIndex: i,
|
|
7091
|
+
left,
|
|
7092
|
+
top,
|
|
7093
|
+
width: barThickness,
|
|
7094
|
+
height: Math.max(height, 24),
|
|
7095
|
+
direction: "vertical"
|
|
7096
|
+
});
|
|
7097
|
+
}
|
|
7098
|
+
return slots;
|
|
7099
|
+
}
|
|
7100
|
+
function hitTestLinkDropSlot(clientX, clientY, draggedHrefKey) {
|
|
7101
|
+
const columns = listFooterColumns();
|
|
7102
|
+
let best = null;
|
|
7103
|
+
for (let c = 0; c < columns.length; c++) {
|
|
7104
|
+
const col = columns[c];
|
|
7105
|
+
const colRect = col.getBoundingClientRect();
|
|
7106
|
+
const inColX = clientX >= colRect.left - 24 && clientX <= colRect.right + 24;
|
|
7107
|
+
if (!inColX) continue;
|
|
7108
|
+
const slots = buildLinkDropSlots(col, c).filter((slot) => {
|
|
7109
|
+
const links = listFooterLinksInColumn(col);
|
|
7110
|
+
const fromIdx = links.findIndex(
|
|
7111
|
+
(el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey
|
|
7112
|
+
);
|
|
7113
|
+
if (fromIdx < 0) return true;
|
|
7114
|
+
if (c === findColumnIndexForKey(draggedHrefKey) && (slot.insertIndex === fromIdx || slot.insertIndex === fromIdx + 1)) {
|
|
7115
|
+
return true;
|
|
7116
|
+
}
|
|
7117
|
+
return true;
|
|
7118
|
+
});
|
|
7119
|
+
for (const slot of slots) {
|
|
7120
|
+
const cy = slot.top + slot.height / 2;
|
|
7121
|
+
const dist = Math.abs(clientY - cy) + (inColX ? 0 : 1e3);
|
|
7122
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
7123
|
+
}
|
|
7124
|
+
}
|
|
7125
|
+
return best?.slot ?? null;
|
|
7126
|
+
}
|
|
7127
|
+
function findColumnIndexForKey(hrefKey) {
|
|
7128
|
+
const order = getFooterOrderFromDom();
|
|
7129
|
+
for (let c = 0; c < order.length; c++) {
|
|
7130
|
+
if (order[c].includes(hrefKey)) return c;
|
|
7131
|
+
}
|
|
7132
|
+
return -1;
|
|
7133
|
+
}
|
|
7134
|
+
function hitTestColumnDropSlot(clientX, _clientY) {
|
|
7135
|
+
const slots = buildColumnDropSlots();
|
|
7136
|
+
let best = null;
|
|
7137
|
+
for (const slot of slots) {
|
|
7138
|
+
const cx2 = slot.left + slot.width / 2;
|
|
7139
|
+
const dist = Math.abs(clientX - cx2);
|
|
7140
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
7141
|
+
}
|
|
7142
|
+
return best?.slot ?? null;
|
|
7143
|
+
}
|
|
7144
|
+
|
|
7145
|
+
// src/lib/item-drag-interaction.ts
|
|
7146
|
+
function disableNativeHrefDrag(el) {
|
|
7147
|
+
if (el.draggable) el.draggable = false;
|
|
7148
|
+
if (el.getAttribute("draggable") !== "false") {
|
|
7149
|
+
el.setAttribute("draggable", "false");
|
|
7150
|
+
}
|
|
7151
|
+
}
|
|
7152
|
+
function clearTextSelection() {
|
|
7153
|
+
const sel = window.getSelection();
|
|
7154
|
+
if (sel && !sel.isCollapsed) sel.removeAllRanges();
|
|
7155
|
+
}
|
|
7156
|
+
function armItemPressDrag() {
|
|
7157
|
+
document.documentElement.setAttribute("data-ohw-footer-press-drag", "");
|
|
7158
|
+
}
|
|
7159
|
+
function lockItemDuringDrag() {
|
|
7160
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7161
|
+
document.documentElement.setAttribute("data-ohw-item-dragging", "");
|
|
7162
|
+
clearTextSelection();
|
|
7163
|
+
}
|
|
7164
|
+
function unlockItemDragInteraction() {
|
|
7165
|
+
document.documentElement.removeAttribute("data-ohw-footer-press-drag");
|
|
7166
|
+
document.documentElement.removeAttribute("data-ohw-item-dragging");
|
|
7167
|
+
clearTextSelection();
|
|
7168
|
+
}
|
|
7169
|
+
var armFooterPressDrag = armItemPressDrag;
|
|
7170
|
+
var lockFooterDuringDrag = lockItemDuringDrag;
|
|
7171
|
+
var unlockFooterDragInteraction = unlockItemDragInteraction;
|
|
7172
|
+
|
|
7173
|
+
// src/lib/nav-dnd.ts
|
|
7174
|
+
function listReorderableNavItems() {
|
|
7175
|
+
return listNavbarItems().filter((el) => {
|
|
7176
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
7177
|
+
return isNavbarHrefKey(key) && !el.closest("[data-ohw-nav-children]");
|
|
7178
|
+
});
|
|
7179
|
+
}
|
|
7180
|
+
function listNavChildren(parentHrefKey) {
|
|
7181
|
+
const items = listNavbarItems();
|
|
7182
|
+
const parent = items.find((el) => el.getAttribute("data-ohw-href-key") === parentHrefKey);
|
|
7183
|
+
if (!parent) return [];
|
|
7184
|
+
const group = parent.closest("[data-ohw-nav-group]");
|
|
7185
|
+
const childrenRoot = group?.querySelector(":scope > [data-ohw-nav-children]");
|
|
7186
|
+
if (!childrenRoot) return [];
|
|
7187
|
+
return Array.from(childrenRoot.querySelectorAll(":scope > [data-ohw-href-key]")).filter(
|
|
7188
|
+
(el) => isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))
|
|
7189
|
+
);
|
|
7190
|
+
}
|
|
7191
|
+
function activeNavListContainer() {
|
|
7192
|
+
const desktop = getNavbarDesktopContainer();
|
|
7193
|
+
if (desktop && desktop.getClientRects().length > 0) {
|
|
7194
|
+
const style = window.getComputedStyle(desktop);
|
|
7195
|
+
if (style.display !== "none" && style.visibility !== "hidden") return desktop;
|
|
7196
|
+
}
|
|
7197
|
+
return getNavbarDrawerContainer();
|
|
7198
|
+
}
|
|
7199
|
+
function buildRootNavDropSlots() {
|
|
7200
|
+
const items = listReorderableNavItems();
|
|
7201
|
+
const slots = [];
|
|
7202
|
+
const barThickness = 3;
|
|
7203
|
+
if (items.length === 0) {
|
|
7204
|
+
const container = activeNavListContainer();
|
|
7205
|
+
if (!container) return slots;
|
|
7206
|
+
const rect = container.getBoundingClientRect();
|
|
7207
|
+
slots.push({
|
|
7208
|
+
insertIndex: 0,
|
|
7209
|
+
parentId: null,
|
|
7210
|
+
left: rect.left + rect.width / 2 - barThickness / 2,
|
|
7211
|
+
top: rect.top,
|
|
7212
|
+
width: barThickness,
|
|
7213
|
+
height: Math.max(rect.height, 24),
|
|
7214
|
+
direction: "vertical"
|
|
7215
|
+
});
|
|
7216
|
+
return slots;
|
|
7217
|
+
}
|
|
7218
|
+
const edgeGap = (() => {
|
|
7219
|
+
if (items.length < 2) return 32;
|
|
7220
|
+
const a = items[0].getBoundingClientRect();
|
|
7221
|
+
const b = items[1].getBoundingClientRect();
|
|
7222
|
+
return Math.max(0, b.left - a.right);
|
|
7223
|
+
})();
|
|
7224
|
+
for (let i = 0; i <= items.length; i++) {
|
|
7225
|
+
let left;
|
|
7226
|
+
let top;
|
|
7227
|
+
let height;
|
|
7228
|
+
if (i === 0) {
|
|
7229
|
+
const first = items[0].getBoundingClientRect();
|
|
7230
|
+
left = first.left - edgeGap / 2 - barThickness / 2;
|
|
7231
|
+
top = first.top;
|
|
7232
|
+
height = first.height;
|
|
7233
|
+
} else if (i === items.length) {
|
|
7234
|
+
const last = items[items.length - 1].getBoundingClientRect();
|
|
7235
|
+
const lastGap = items.length >= 2 ? Math.max(
|
|
7236
|
+
0,
|
|
7237
|
+
last.left - items[items.length - 2].getBoundingClientRect().right
|
|
7238
|
+
) : edgeGap;
|
|
7239
|
+
left = last.right + lastGap / 2 - barThickness / 2;
|
|
7240
|
+
top = last.top;
|
|
7241
|
+
height = last.height;
|
|
7242
|
+
} else {
|
|
7243
|
+
const prev = items[i - 1].getBoundingClientRect();
|
|
7244
|
+
const next = items[i].getBoundingClientRect();
|
|
7245
|
+
left = (prev.right + next.left) / 2 - barThickness / 2;
|
|
7246
|
+
top = Math.min(prev.top, next.top);
|
|
7247
|
+
height = Math.max(prev.bottom, next.bottom) - top;
|
|
7248
|
+
}
|
|
7249
|
+
slots.push({
|
|
7250
|
+
insertIndex: i,
|
|
7251
|
+
parentId: null,
|
|
7252
|
+
left,
|
|
7253
|
+
top,
|
|
7254
|
+
width: barThickness,
|
|
7255
|
+
height: Math.max(height, 24),
|
|
7256
|
+
direction: "vertical"
|
|
7257
|
+
});
|
|
7258
|
+
}
|
|
7259
|
+
return slots;
|
|
7260
|
+
}
|
|
7261
|
+
function buildChildNavDropSlots(parentHrefKey) {
|
|
7262
|
+
const children = listNavChildren(parentHrefKey);
|
|
7263
|
+
const slots = [];
|
|
7264
|
+
const barThickness = 3;
|
|
7265
|
+
if (children.length === 0) return slots;
|
|
7266
|
+
const edgeGap = (() => {
|
|
7267
|
+
if (children.length < 2) return 16;
|
|
7268
|
+
const a = children[0].getBoundingClientRect();
|
|
7269
|
+
const b = children[1].getBoundingClientRect();
|
|
7270
|
+
return Math.max(0, b.top - a.bottom);
|
|
7271
|
+
})();
|
|
7272
|
+
for (let i = 0; i <= children.length; i++) {
|
|
7273
|
+
let top;
|
|
7274
|
+
let width;
|
|
7275
|
+
let left;
|
|
7276
|
+
if (i === 0) {
|
|
7277
|
+
const first = children[0].getBoundingClientRect();
|
|
7278
|
+
top = first.top - edgeGap / 2 - barThickness / 2;
|
|
7279
|
+
left = first.left;
|
|
7280
|
+
width = first.width;
|
|
7281
|
+
} else if (i === children.length) {
|
|
7282
|
+
const last = children[children.length - 1].getBoundingClientRect();
|
|
7283
|
+
const lastGap = children.length >= 2 ? Math.max(
|
|
7284
|
+
0,
|
|
7285
|
+
last.top - children[children.length - 2].getBoundingClientRect().bottom
|
|
7286
|
+
) : edgeGap;
|
|
7287
|
+
top = last.bottom + lastGap / 2 - barThickness / 2;
|
|
7288
|
+
left = last.left;
|
|
7289
|
+
width = last.width;
|
|
7290
|
+
} else {
|
|
7291
|
+
const prev = children[i - 1].getBoundingClientRect();
|
|
7292
|
+
const next = children[i].getBoundingClientRect();
|
|
7293
|
+
top = (prev.bottom + next.top) / 2 - barThickness / 2;
|
|
7294
|
+
left = Math.min(prev.left, next.left);
|
|
7295
|
+
width = Math.max(prev.right, next.right) - left;
|
|
7296
|
+
}
|
|
7297
|
+
slots.push({
|
|
7298
|
+
insertIndex: i,
|
|
7299
|
+
parentId: parentHrefKey,
|
|
7300
|
+
left,
|
|
7301
|
+
top,
|
|
7302
|
+
width: Math.max(width, 40),
|
|
7303
|
+
height: barThickness,
|
|
7304
|
+
direction: "horizontal"
|
|
7305
|
+
});
|
|
7306
|
+
}
|
|
7307
|
+
return slots;
|
|
7308
|
+
}
|
|
7309
|
+
function buildAllNavDropSlots(draggedHrefKey) {
|
|
7310
|
+
const slots = [...buildRootNavDropSlots()];
|
|
7311
|
+
for (const item of listReorderableNavItems()) {
|
|
7312
|
+
const key = item.getAttribute("data-ohw-href-key");
|
|
7313
|
+
if (!key || key === draggedHrefKey) continue;
|
|
7314
|
+
const group = item.closest("[data-ohw-nav-group]");
|
|
7315
|
+
if (!group?.querySelector(":scope > [data-ohw-nav-children]")) continue;
|
|
7316
|
+
slots.push(...buildChildNavDropSlots(key));
|
|
7317
|
+
}
|
|
7318
|
+
const dragged = listNavbarItems().find((el) => el.getAttribute("data-ohw-href-key") === draggedHrefKey);
|
|
7319
|
+
const parentGroup = dragged?.closest("[data-ohw-nav-children]")?.closest("[data-ohw-nav-group]");
|
|
7320
|
+
const parentTrigger = parentGroup?.querySelector(":scope > [data-ohw-href-key]");
|
|
7321
|
+
const parentKey = parentTrigger?.getAttribute("data-ohw-href-key");
|
|
7322
|
+
if (parentKey && isNavbarHrefKey(parentKey)) {
|
|
7323
|
+
const existing = slots.some((s) => s.parentId === parentKey);
|
|
7324
|
+
if (!existing) slots.push(...buildChildNavDropSlots(parentKey));
|
|
7325
|
+
}
|
|
7326
|
+
return slots;
|
|
7327
|
+
}
|
|
7328
|
+
function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
|
|
7329
|
+
const slots = buildAllNavDropSlots(draggedHrefKey);
|
|
7330
|
+
let best = null;
|
|
7331
|
+
for (const slot of slots) {
|
|
7332
|
+
const cx2 = slot.left + slot.width / 2;
|
|
7333
|
+
const cy = slot.top + slot.height / 2;
|
|
7334
|
+
const dist = slot.direction === "vertical" ? Math.abs(clientX - cx2) + Math.abs(clientY - cy) * 0.25 : Math.abs(clientY - cy) + Math.abs(clientX - cx2) * 0.25;
|
|
7335
|
+
if (!best || dist < best.dist) best = { slot, dist };
|
|
7336
|
+
}
|
|
7337
|
+
return best?.slot ?? null;
|
|
7338
|
+
}
|
|
7339
|
+
|
|
7340
|
+
// src/useNavItemDrag.ts
|
|
7341
|
+
var import_react8 = require("react");
|
|
7342
|
+
function useNavItemDrag({
|
|
7343
|
+
isEditMode,
|
|
7344
|
+
editContentRef,
|
|
7345
|
+
selectedElRef,
|
|
7346
|
+
activeElRef,
|
|
7347
|
+
footerDragRef,
|
|
7348
|
+
suppressNextClickRef,
|
|
7349
|
+
suppressClickUntilRef,
|
|
7350
|
+
siblingHintElRef,
|
|
7351
|
+
postToParentRef,
|
|
7352
|
+
deselectRef,
|
|
7353
|
+
selectRef,
|
|
7354
|
+
deactivateRef,
|
|
7355
|
+
setLinkPopover,
|
|
7356
|
+
linkPopoverOpenRef,
|
|
7357
|
+
setIsItemDragging,
|
|
7358
|
+
setDraggedItemRect,
|
|
7359
|
+
setSiblingHintRect,
|
|
7360
|
+
setSiblingHintRects,
|
|
7361
|
+
setToolbarRect,
|
|
7362
|
+
getNavigationItemAnchor: getNavigationItemAnchor2,
|
|
7363
|
+
isDragHandleDisabled: isDragHandleDisabled2,
|
|
7364
|
+
isNavbarButton: isNavbarButton3
|
|
7365
|
+
}) {
|
|
7366
|
+
const navDragRef = (0, import_react8.useRef)(null);
|
|
7367
|
+
const [navDropSlots, setNavDropSlots] = (0, import_react8.useState)([]);
|
|
7368
|
+
const [activeNavDropIndex, setActiveNavDropIndex] = (0, import_react8.useState)(null);
|
|
7369
|
+
const navPointerDragRef = (0, import_react8.useRef)(null);
|
|
7370
|
+
const clearNavDragVisuals = (0, import_react8.useCallback)(() => {
|
|
7371
|
+
navDragRef.current = null;
|
|
7372
|
+
setNavDropSlots([]);
|
|
7373
|
+
setActiveNavDropIndex(null);
|
|
7374
|
+
setDraggedItemRect(null);
|
|
7375
|
+
setSiblingHintRects([]);
|
|
7376
|
+
setIsItemDragging(false);
|
|
7377
|
+
unlockItemDragInteraction();
|
|
7378
|
+
}, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
|
|
7379
|
+
const refreshNavDragVisuals = (0, import_react8.useCallback)(
|
|
7380
|
+
(session, activeSlot, clientX, clientY) => {
|
|
7381
|
+
setDraggedItemRect(session.draggedEl.getBoundingClientRect());
|
|
7382
|
+
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
7383
|
+
session.lastClientX = clientX;
|
|
7384
|
+
session.lastClientY = clientY;
|
|
7385
|
+
}
|
|
7386
|
+
session.activeSlot = activeSlot;
|
|
7387
|
+
setSiblingHintRects([]);
|
|
7388
|
+
const slots = buildAllNavDropSlots(session.hrefKey);
|
|
7389
|
+
setNavDropSlots(slots);
|
|
7390
|
+
const activeIdx = activeSlot ? slots.findIndex(
|
|
7391
|
+
(s) => s.parentId === activeSlot.parentId && s.insertIndex === activeSlot.insertIndex
|
|
7392
|
+
) : -1;
|
|
7393
|
+
setActiveNavDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
7394
|
+
},
|
|
7395
|
+
[setDraggedItemRect, setSiblingHintRects]
|
|
7396
|
+
);
|
|
7397
|
+
const refreshNavDragVisualsRef = (0, import_react8.useRef)(refreshNavDragVisuals);
|
|
7398
|
+
refreshNavDragVisualsRef.current = refreshNavDragVisuals;
|
|
7399
|
+
const commitNavDragRef = (0, import_react8.useRef)(() => {
|
|
7400
|
+
});
|
|
7401
|
+
const beginNavDragRef = (0, import_react8.useRef)(() => {
|
|
7402
|
+
});
|
|
7403
|
+
const beginNavDrag = (0, import_react8.useCallback)(
|
|
7404
|
+
(session) => {
|
|
7405
|
+
const rect = session.draggedEl.getBoundingClientRect();
|
|
7406
|
+
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
7407
|
+
session.lastClientY = session.lastClientY || rect.top + rect.height / 2;
|
|
7408
|
+
session.activeSlot = session.activeSlot ?? null;
|
|
7409
|
+
navDragRef.current = session;
|
|
7410
|
+
setIsItemDragging(true);
|
|
7411
|
+
lockItemDuringDrag();
|
|
7412
|
+
siblingHintElRef.current = null;
|
|
7413
|
+
setSiblingHintRect(null);
|
|
7414
|
+
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
7415
|
+
setToolbarRect(rect);
|
|
7416
|
+
}
|
|
7417
|
+
const initialSlot = hitTestNavDropSlot(session.lastClientX, session.lastClientY, session.hrefKey);
|
|
7418
|
+
refreshNavDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
7419
|
+
},
|
|
7420
|
+
[
|
|
7421
|
+
refreshNavDragVisuals,
|
|
7422
|
+
selectedElRef,
|
|
7423
|
+
setIsItemDragging,
|
|
7424
|
+
setSiblingHintRect,
|
|
7425
|
+
setToolbarRect,
|
|
7426
|
+
siblingHintElRef
|
|
7427
|
+
]
|
|
7428
|
+
);
|
|
7429
|
+
beginNavDragRef.current = beginNavDrag;
|
|
7430
|
+
const commitNavDrag = (0, import_react8.useCallback)(
|
|
7431
|
+
(clientX, clientY) => {
|
|
7432
|
+
const session = navDragRef.current;
|
|
7433
|
+
if (!session) {
|
|
7434
|
+
clearNavDragVisuals();
|
|
7435
|
+
return;
|
|
7436
|
+
}
|
|
7437
|
+
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
7438
|
+
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
7439
|
+
const slot = session.activeSlot ?? hitTestNavDropSlot(x, y, session.hrefKey);
|
|
7440
|
+
const planned = slot != null ? planNavItemMove(session.hrefKey, slot.parentId, slot.insertIndex) : null;
|
|
7441
|
+
const wasSelected = session.wasSelected;
|
|
7442
|
+
const hrefKey = session.hrefKey;
|
|
7443
|
+
const applySelectionAfterDrop = () => {
|
|
7444
|
+
if (!wasSelected) {
|
|
7445
|
+
deselectRef.current();
|
|
7446
|
+
return;
|
|
7447
|
+
}
|
|
7448
|
+
const desktop = document.querySelector("[data-ohw-nav-container]");
|
|
7449
|
+
const drawer = document.querySelector("[data-ohw-nav-drawer]");
|
|
7450
|
+
const link = desktop?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? drawer?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
7451
|
+
if (link) {
|
|
7452
|
+
selectRef.current(link);
|
|
7453
|
+
return;
|
|
7454
|
+
}
|
|
7455
|
+
deselectRef.current();
|
|
7456
|
+
};
|
|
7457
|
+
if (planned) {
|
|
7458
|
+
editContentRef.current = {
|
|
7459
|
+
...editContentRef.current,
|
|
7460
|
+
[NAV_ORDER_KEY]: planned.orderJson
|
|
7461
|
+
};
|
|
7462
|
+
applyNavForest(planned.forest);
|
|
7463
|
+
document.querySelectorAll(
|
|
7464
|
+
"nav [data-ohw-href-key], [data-ohw-nav-container] [data-ohw-href-key], [data-ohw-nav-drawer] [data-ohw-href-key]"
|
|
7465
|
+
).forEach((el) => {
|
|
7466
|
+
if (isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
7467
|
+
disableNativeHrefDrag(el);
|
|
7468
|
+
}
|
|
7469
|
+
});
|
|
7470
|
+
postToParentRef.current({
|
|
7471
|
+
type: "ow:change",
|
|
7472
|
+
nodes: [{ key: NAV_ORDER_KEY, text: planned.orderJson }]
|
|
7473
|
+
});
|
|
7474
|
+
applySelectionAfterDrop();
|
|
7475
|
+
clearNavDragVisuals();
|
|
7476
|
+
requestAnimationFrame(() => {
|
|
7477
|
+
if (editContentRef.current[NAV_ORDER_KEY] === planned.orderJson) {
|
|
7478
|
+
applyNavForest(planned.forest);
|
|
7479
|
+
}
|
|
7480
|
+
applySelectionAfterDrop();
|
|
7481
|
+
requestAnimationFrame(applySelectionAfterDrop);
|
|
7482
|
+
});
|
|
7483
|
+
return;
|
|
7484
|
+
}
|
|
7485
|
+
applySelectionAfterDrop();
|
|
7486
|
+
clearNavDragVisuals();
|
|
7487
|
+
},
|
|
7488
|
+
[clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
|
|
7489
|
+
);
|
|
7490
|
+
commitNavDragRef.current = commitNavDrag;
|
|
7491
|
+
const startNavLinkDrag = (0, import_react8.useCallback)(
|
|
7492
|
+
(anchor, clientX, clientY, wasSelected) => {
|
|
7493
|
+
if (footerDragRef.current) return false;
|
|
7494
|
+
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
7495
|
+
if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
|
|
7496
|
+
if (isNavbarButton3(anchor) || isDragHandleDisabled2(anchor)) return false;
|
|
7497
|
+
beginNavDrag({
|
|
7498
|
+
hrefKey,
|
|
7499
|
+
wasSelected,
|
|
7500
|
+
draggedEl: anchor,
|
|
7501
|
+
lastClientX: clientX,
|
|
7502
|
+
lastClientY: clientY,
|
|
7503
|
+
activeSlot: null
|
|
7504
|
+
});
|
|
7505
|
+
return true;
|
|
7506
|
+
},
|
|
7507
|
+
[beginNavDrag, footerDragRef, isDragHandleDisabled2, isNavbarButton3]
|
|
7508
|
+
);
|
|
7509
|
+
const onNavDragOver = (0, import_react8.useCallback)(
|
|
7510
|
+
(e) => {
|
|
7511
|
+
const session = navDragRef.current;
|
|
7512
|
+
if (!session) return false;
|
|
7513
|
+
e.preventDefault();
|
|
7514
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
7515
|
+
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey);
|
|
7516
|
+
refreshNavDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
7517
|
+
return true;
|
|
7518
|
+
},
|
|
7519
|
+
[]
|
|
7520
|
+
);
|
|
7521
|
+
(0, import_react8.useEffect)(() => {
|
|
7522
|
+
if (!isEditMode) return;
|
|
7523
|
+
const THRESHOLD = 10;
|
|
7524
|
+
const resolveWasSelected = (el) => {
|
|
7525
|
+
if (selectedElRef.current === el) return true;
|
|
7526
|
+
const activeAnchor = activeElRef.current ? getNavigationItemAnchor2(activeElRef.current) : null;
|
|
7527
|
+
return activeAnchor === el;
|
|
7528
|
+
};
|
|
7529
|
+
const onPointerDown = (e) => {
|
|
7530
|
+
if (e.button !== 0) return;
|
|
7531
|
+
if (navDragRef.current || footerDragRef.current) return;
|
|
7532
|
+
const target = e.target;
|
|
7533
|
+
if (!target) return;
|
|
7534
|
+
if (target.closest(
|
|
7535
|
+
'[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root]'
|
|
7536
|
+
)) {
|
|
7537
|
+
return;
|
|
7538
|
+
}
|
|
7539
|
+
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
7540
|
+
const anchor = getNavigationItemAnchor2(target);
|
|
7541
|
+
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
7542
|
+
if (!anchor || !isNavbarHrefKey(hrefKey)) return;
|
|
7543
|
+
if (isNavbarButton3(anchor) || isDragHandleDisabled2(anchor)) return;
|
|
7544
|
+
armItemPressDrag();
|
|
7545
|
+
navPointerDragRef.current = {
|
|
7546
|
+
el: anchor,
|
|
7547
|
+
startX: e.clientX,
|
|
7548
|
+
startY: e.clientY,
|
|
7549
|
+
pointerId: e.pointerId,
|
|
7550
|
+
wasSelected: resolveWasSelected(anchor),
|
|
7551
|
+
started: false
|
|
7552
|
+
};
|
|
7553
|
+
};
|
|
7554
|
+
const onPointerMove = (e) => {
|
|
7555
|
+
const pending = navPointerDragRef.current;
|
|
7556
|
+
if (!pending) return;
|
|
7557
|
+
if (pending.started) {
|
|
7558
|
+
e.preventDefault();
|
|
7559
|
+
clearTextSelection();
|
|
7560
|
+
const session = navDragRef.current;
|
|
7561
|
+
if (!session) return;
|
|
7562
|
+
const slot = hitTestNavDropSlot(e.clientX, e.clientY, session.hrefKey);
|
|
7563
|
+
refreshNavDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
7564
|
+
return;
|
|
7565
|
+
}
|
|
7566
|
+
const dx = e.clientX - pending.startX;
|
|
7567
|
+
const dy = e.clientY - pending.startY;
|
|
7568
|
+
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
7569
|
+
e.preventDefault();
|
|
7570
|
+
pending.started = true;
|
|
7571
|
+
clearTextSelection();
|
|
7572
|
+
try {
|
|
7573
|
+
document.body.setPointerCapture(pending.pointerId);
|
|
7574
|
+
} catch {
|
|
7575
|
+
}
|
|
7576
|
+
if (linkPopoverOpenRef.current) setLinkPopover(null);
|
|
7577
|
+
if (activeElRef.current) deactivateRef.current();
|
|
7578
|
+
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
7579
|
+
if (!key) return;
|
|
7580
|
+
beginNavDragRef.current({
|
|
7581
|
+
hrefKey: key,
|
|
7582
|
+
wasSelected: pending.wasSelected,
|
|
7583
|
+
draggedEl: pending.el,
|
|
7584
|
+
lastClientX: e.clientX,
|
|
7585
|
+
lastClientY: e.clientY,
|
|
7586
|
+
activeSlot: null
|
|
7587
|
+
});
|
|
7588
|
+
};
|
|
7589
|
+
const endPointerDrag = (e) => {
|
|
7590
|
+
const pending = navPointerDragRef.current;
|
|
7591
|
+
navPointerDragRef.current = null;
|
|
7592
|
+
try {
|
|
7593
|
+
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
7594
|
+
document.body.releasePointerCapture(e.pointerId);
|
|
7595
|
+
}
|
|
7596
|
+
} catch {
|
|
7597
|
+
}
|
|
7598
|
+
if (!pending?.started) {
|
|
7599
|
+
unlockItemDragInteraction();
|
|
7600
|
+
return;
|
|
7601
|
+
}
|
|
7602
|
+
suppressNextClickRef.current = true;
|
|
7603
|
+
suppressClickUntilRef.current = Date.now() + 500;
|
|
7604
|
+
commitNavDragRef.current(e.clientX, e.clientY);
|
|
7605
|
+
};
|
|
7606
|
+
const blockSelectStart = (e) => {
|
|
7607
|
+
if (navDragRef.current || navPointerDragRef.current?.started || document.documentElement.hasAttribute("data-ohw-footer-press-drag")) {
|
|
7608
|
+
e.preventDefault();
|
|
7609
|
+
}
|
|
7610
|
+
};
|
|
7611
|
+
const onDragEnd = () => {
|
|
7612
|
+
if (!navDragRef.current) return;
|
|
7613
|
+
suppressNextClickRef.current = true;
|
|
7614
|
+
suppressClickUntilRef.current = Date.now() + 500;
|
|
7615
|
+
commitNavDragRef.current();
|
|
7616
|
+
};
|
|
7617
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
7618
|
+
document.addEventListener("pointermove", onPointerMove, true);
|
|
7619
|
+
document.addEventListener("pointerup", endPointerDrag, true);
|
|
7620
|
+
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
7621
|
+
document.addEventListener("selectstart", blockSelectStart, true);
|
|
7622
|
+
document.addEventListener("dragend", onDragEnd, true);
|
|
7623
|
+
return () => {
|
|
7624
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
7625
|
+
document.removeEventListener("pointermove", onPointerMove, true);
|
|
7626
|
+
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
7627
|
+
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
7628
|
+
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
7629
|
+
document.removeEventListener("dragend", onDragEnd, true);
|
|
7630
|
+
unlockItemDragInteraction();
|
|
7631
|
+
};
|
|
7632
|
+
}, [
|
|
7633
|
+
activeElRef,
|
|
7634
|
+
deactivateRef,
|
|
7635
|
+
footerDragRef,
|
|
7636
|
+
getNavigationItemAnchor2,
|
|
7637
|
+
isDragHandleDisabled2,
|
|
7638
|
+
isEditMode,
|
|
7639
|
+
isNavbarButton3,
|
|
7640
|
+
linkPopoverOpenRef,
|
|
7641
|
+
selectedElRef,
|
|
7642
|
+
setLinkPopover,
|
|
7643
|
+
suppressNextClickRef
|
|
7644
|
+
]);
|
|
7645
|
+
const armNavPressFromChrome = (0, import_react8.useCallback)(
|
|
7646
|
+
(selected, clientX, clientY, pointerId) => {
|
|
7647
|
+
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
7648
|
+
if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
|
|
7649
|
+
if (isNavbarButton3(selected) || isDragHandleDisabled2(selected)) return false;
|
|
7650
|
+
armItemPressDrag();
|
|
7651
|
+
navPointerDragRef.current = {
|
|
7652
|
+
el: selected,
|
|
7653
|
+
startX: clientX,
|
|
7654
|
+
startY: clientY,
|
|
7655
|
+
pointerId,
|
|
7656
|
+
wasSelected: true,
|
|
7657
|
+
started: false
|
|
7658
|
+
};
|
|
7659
|
+
return true;
|
|
7660
|
+
},
|
|
7661
|
+
[isDragHandleDisabled2, isNavbarButton3]
|
|
7662
|
+
);
|
|
7663
|
+
return {
|
|
7664
|
+
navDragRef,
|
|
7665
|
+
navDropSlots,
|
|
7666
|
+
activeNavDropIndex,
|
|
7667
|
+
startNavLinkDrag,
|
|
7668
|
+
commitNavDrag,
|
|
7669
|
+
onNavDragOver,
|
|
7670
|
+
armNavPressFromChrome,
|
|
7671
|
+
clearNavDragVisuals,
|
|
7672
|
+
refreshNavDragVisualsRef
|
|
7673
|
+
};
|
|
7674
|
+
}
|
|
7675
|
+
|
|
7676
|
+
// src/ui/navbar-container-chrome.tsx
|
|
7677
|
+
var import_lucide_react10 = require("lucide-react");
|
|
7678
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
7679
|
+
function NavbarContainerChrome({
|
|
7680
|
+
rect,
|
|
7681
|
+
onAdd
|
|
7682
|
+
}) {
|
|
7683
|
+
const chromeGap = 6;
|
|
7684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7685
|
+
"div",
|
|
7686
|
+
{
|
|
7687
|
+
"data-ohw-navbar-container-chrome": "",
|
|
7688
|
+
"data-ohw-bridge": "",
|
|
7689
|
+
className: "pointer-events-none fixed z-[2147483647]",
|
|
7690
|
+
style: {
|
|
7691
|
+
top: rect.top - chromeGap,
|
|
7692
|
+
left: rect.left - chromeGap,
|
|
7693
|
+
width: rect.width + chromeGap * 2,
|
|
7694
|
+
height: rect.height + chromeGap * 2
|
|
7695
|
+
},
|
|
7696
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7697
|
+
"button",
|
|
7698
|
+
{
|
|
7699
|
+
type: "button",
|
|
7700
|
+
"data-ohw-navbar-add-button": "",
|
|
7701
|
+
className: "pointer-events-auto absolute left-1/2 flex p-0.5 rounded-[10px] size-7 -translate-x-1/2 translate-y-1/2 items-center justify-center border border-border bg-background shadow-sm transition-colors hover:bg-muted/80",
|
|
7702
|
+
style: { top: "70%" },
|
|
7703
|
+
"aria-label": "Add item",
|
|
7704
|
+
onMouseDown: (e) => {
|
|
7705
|
+
e.preventDefault();
|
|
7706
|
+
e.stopPropagation();
|
|
7707
|
+
},
|
|
7708
|
+
onClick: (e) => {
|
|
7709
|
+
e.preventDefault();
|
|
7710
|
+
e.stopPropagation();
|
|
7711
|
+
onAdd();
|
|
7712
|
+
},
|
|
7713
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
7714
|
+
}
|
|
7715
|
+
)
|
|
7716
|
+
}
|
|
7717
|
+
);
|
|
7718
|
+
}
|
|
7719
|
+
|
|
7720
|
+
// src/ui/drop-indicator.tsx
|
|
7721
|
+
var React10 = __toESM(require("react"), 1);
|
|
7722
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
7723
|
+
var dropIndicatorVariants = cva(
|
|
7724
|
+
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
7725
|
+
{
|
|
7726
|
+
variants: {
|
|
7727
|
+
direction: {
|
|
7728
|
+
vertical: "h-6 w-[3px]",
|
|
7729
|
+
horizontal: "h-[3px] w-[200px]"
|
|
7730
|
+
},
|
|
7731
|
+
state: {
|
|
7732
|
+
default: "opacity-0",
|
|
7733
|
+
hover: "opacity-100",
|
|
7734
|
+
dragIdle: "opacity-40",
|
|
7735
|
+
dragActive: "opacity-100"
|
|
7736
|
+
}
|
|
7737
|
+
},
|
|
7738
|
+
defaultVariants: {
|
|
7739
|
+
direction: "vertical",
|
|
7740
|
+
state: "default"
|
|
7741
|
+
}
|
|
7742
|
+
}
|
|
7743
|
+
);
|
|
7744
|
+
var DropIndicator = React10.forwardRef(
|
|
7745
|
+
({ className, direction, state, ...props }, ref) => {
|
|
7746
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
7747
|
+
"div",
|
|
7748
|
+
{
|
|
7749
|
+
ref,
|
|
7750
|
+
"data-slot": "drop-indicator",
|
|
7751
|
+
"data-direction": direction ?? "vertical",
|
|
7752
|
+
"data-state": state ?? "default",
|
|
7753
|
+
"aria-hidden": "true",
|
|
7754
|
+
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
7755
|
+
...props
|
|
7756
|
+
}
|
|
7757
|
+
);
|
|
7758
|
+
}
|
|
7759
|
+
);
|
|
7760
|
+
DropIndicator.displayName = "DropIndicator";
|
|
7761
|
+
|
|
7762
|
+
// src/ui/badge.tsx
|
|
7763
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
7764
|
+
var badgeVariants = cva(
|
|
7765
|
+
"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",
|
|
7766
|
+
{
|
|
7767
|
+
variants: {
|
|
7768
|
+
variant: {
|
|
7769
|
+
default: "border-transparent bg-primary text-primary-foreground",
|
|
7770
|
+
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
7771
|
+
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
7772
|
+
outline: "text-foreground"
|
|
7773
|
+
}
|
|
7774
|
+
},
|
|
7775
|
+
defaultVariants: {
|
|
7776
|
+
variant: "default"
|
|
7777
|
+
}
|
|
7778
|
+
}
|
|
7779
|
+
);
|
|
7780
|
+
function Badge({ className, variant, ...props }) {
|
|
7781
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
7782
|
+
}
|
|
7783
|
+
|
|
7784
|
+
// src/OhhwellsBridge.tsx
|
|
7785
|
+
var import_lucide_react11 = require("lucide-react");
|
|
7786
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
7787
|
+
var PRIMARY2 = "#0885FE";
|
|
7788
|
+
var IMAGE_FADE_MS = 300;
|
|
7789
|
+
function runOpacityFade(el, onDone) {
|
|
7790
|
+
const anim = el.animate([{ opacity: 0 }, { opacity: 1 }], {
|
|
7791
|
+
duration: IMAGE_FADE_MS,
|
|
7792
|
+
easing: "ease",
|
|
7793
|
+
fill: "forwards"
|
|
7794
|
+
});
|
|
7795
|
+
let finished = false;
|
|
7796
|
+
const finish = () => {
|
|
7797
|
+
if (finished) return;
|
|
7798
|
+
finished = true;
|
|
7799
|
+
anim.cancel();
|
|
7800
|
+
el.style.opacity = "";
|
|
7801
|
+
onDone();
|
|
7802
|
+
};
|
|
7803
|
+
anim.finished.then(finish).catch(finish);
|
|
7804
|
+
window.setTimeout(finish, IMAGE_FADE_MS + 100);
|
|
7805
|
+
}
|
|
7806
|
+
function fadeInImageElement(img, onReady) {
|
|
7807
|
+
onReady();
|
|
7808
|
+
img.style.opacity = "0";
|
|
7809
|
+
runOpacityFade(img, () => {
|
|
7810
|
+
img.style.opacity = "";
|
|
7811
|
+
});
|
|
7812
|
+
}
|
|
7813
|
+
function applyEditableImageSrc(img, url) {
|
|
7814
|
+
img.removeAttribute("srcset");
|
|
7815
|
+
img.removeAttribute("sizes");
|
|
7816
|
+
img.src = url;
|
|
7817
|
+
}
|
|
7818
|
+
function fadeInBgImage(el, url, onReady) {
|
|
7819
|
+
const prevPos = el.style.position;
|
|
7820
|
+
if (!prevPos || prevPos === "static") el.style.position = "relative";
|
|
7821
|
+
const layer = document.createElement("div");
|
|
7822
|
+
layer.setAttribute("data-ohw-bg-fade-layer", "");
|
|
7823
|
+
Object.assign(layer.style, {
|
|
7824
|
+
position: "absolute",
|
|
7825
|
+
inset: "0",
|
|
7826
|
+
zIndex: "0",
|
|
7827
|
+
backgroundImage: `url('${url}')`,
|
|
7828
|
+
backgroundSize: "cover",
|
|
7829
|
+
backgroundPosition: "center",
|
|
7830
|
+
backgroundRepeat: "no-repeat",
|
|
7831
|
+
opacity: "0",
|
|
7832
|
+
pointerEvents: "none"
|
|
7833
|
+
});
|
|
7834
|
+
el.prepend(layer);
|
|
7835
|
+
onReady();
|
|
7836
|
+
runOpacityFade(layer, () => {
|
|
7837
|
+
el.style.backgroundImage = `url('${url}')`;
|
|
7838
|
+
layer.remove();
|
|
7839
|
+
if (!prevPos || prevPos === "static") el.style.position = prevPos;
|
|
7840
|
+
});
|
|
7841
|
+
}
|
|
7842
|
+
function getSectionsTracker() {
|
|
7843
|
+
let el = document.querySelector("[data-ohw-sections-tracker]");
|
|
7844
|
+
if (!el) {
|
|
6634
7845
|
el = document.createElement("div");
|
|
6635
7846
|
el.setAttribute("data-ohw-sections-tracker", "");
|
|
6636
7847
|
el.style.display = "none";
|
|
@@ -6751,7 +7962,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
6751
7962
|
const root = (0, import_client.createRoot)(container);
|
|
6752
7963
|
(0, import_react_dom2.flushSync)(() => {
|
|
6753
7964
|
root.render(
|
|
6754
|
-
/* @__PURE__ */ (0,
|
|
7965
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
6755
7966
|
SchedulingWidget,
|
|
6756
7967
|
{
|
|
6757
7968
|
notifyOnConnect,
|
|
@@ -6813,7 +8024,20 @@ function isDragHandleDisabled(el) {
|
|
|
6813
8024
|
return raw === "true" || raw === "";
|
|
6814
8025
|
});
|
|
6815
8026
|
}
|
|
6816
|
-
function
|
|
8027
|
+
function canDragNavigationItem(anchor) {
|
|
8028
|
+
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
8029
|
+
return Boolean(key) && !disabled;
|
|
8030
|
+
}
|
|
8031
|
+
function syncNavigationDragCursorAttrs() {
|
|
8032
|
+
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]").forEach((el) => {
|
|
8033
|
+
if (!isNavigationItem(el) || !canDragNavigationItem(el)) {
|
|
8034
|
+
el.removeAttribute("data-ohw-can-drag");
|
|
8035
|
+
return;
|
|
8036
|
+
}
|
|
8037
|
+
el.setAttribute("data-ohw-can-drag", "");
|
|
8038
|
+
});
|
|
8039
|
+
}
|
|
8040
|
+
function collectEditableNodes(extraContent) {
|
|
6817
8041
|
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
6818
8042
|
if (el.dataset.ohwEditable === "image") {
|
|
6819
8043
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -6841,6 +8065,14 @@ function collectEditableNodes() {
|
|
|
6841
8065
|
if (!key) return;
|
|
6842
8066
|
nodes.push({ key, type: "link", text: getLinkHref2(el) });
|
|
6843
8067
|
});
|
|
8068
|
+
if (extraContent) {
|
|
8069
|
+
for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
|
|
8070
|
+
const text = extraContent[key];
|
|
8071
|
+
if (typeof text === "string" && text.length > 0) {
|
|
8072
|
+
nodes.push({ key, type: "meta", text });
|
|
8073
|
+
}
|
|
8074
|
+
}
|
|
8075
|
+
}
|
|
6844
8076
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
6845
8077
|
const key = el.dataset.ohwKey ?? "";
|
|
6846
8078
|
const video = getVideoEl(el);
|
|
@@ -6954,6 +8186,11 @@ function getNavigationItemAnchor(el) {
|
|
|
6954
8186
|
function isNavigationItem(el) {
|
|
6955
8187
|
return getNavigationItemAnchor(el) !== null;
|
|
6956
8188
|
}
|
|
8189
|
+
function listNavigationItems() {
|
|
8190
|
+
return Array.from(
|
|
8191
|
+
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
8192
|
+
).filter((el) => isNavigationItem(el));
|
|
8193
|
+
}
|
|
6957
8194
|
function getNavigationItemReorderState(anchor) {
|
|
6958
8195
|
if (isNavbarButton2(anchor)) return { key: null, disabled: false };
|
|
6959
8196
|
return getReorderHandleStateFromAnchor(anchor);
|
|
@@ -6982,18 +8219,20 @@ function getNavigationRoot(el) {
|
|
|
6982
8219
|
if (explicit) return explicit;
|
|
6983
8220
|
return el.closest("nav, footer, aside");
|
|
6984
8221
|
}
|
|
8222
|
+
function countFooterNavItems(el) {
|
|
8223
|
+
return Array.from(el.querySelectorAll("[data-ohw-href-key]")).filter(isNavigationItem).length;
|
|
8224
|
+
}
|
|
6985
8225
|
function findFooterItemGroup(item) {
|
|
8226
|
+
const explicit = item.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
8227
|
+
if (explicit) return explicit;
|
|
6986
8228
|
const footer = item.closest("footer");
|
|
6987
8229
|
if (!footer) return null;
|
|
6988
8230
|
let node = item.parentElement;
|
|
6989
8231
|
while (node && node !== footer) {
|
|
6990
|
-
|
|
6991
|
-
node.querySelectorAll(":scope > [data-ohw-href-key]")
|
|
6992
|
-
).some(isNavigationItem);
|
|
6993
|
-
if (hasDirectNavItems) return node;
|
|
8232
|
+
if (countFooterNavItems(node) >= 2) return node;
|
|
6994
8233
|
node = node.parentElement;
|
|
6995
8234
|
}
|
|
6996
|
-
return
|
|
8235
|
+
return footer;
|
|
6997
8236
|
}
|
|
6998
8237
|
function isNavigationRoot(el) {
|
|
6999
8238
|
return el.hasAttribute("data-ohw-nav-root") || el.matches("nav, footer, aside");
|
|
@@ -7001,16 +8240,49 @@ function isNavigationRoot(el) {
|
|
|
7001
8240
|
function isInferredFooterGroup(el) {
|
|
7002
8241
|
const footer = el.closest("footer");
|
|
7003
8242
|
if (!footer || el === footer) return false;
|
|
7004
|
-
|
|
8243
|
+
if (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column")) return true;
|
|
8244
|
+
return countFooterNavItems(el) >= 2;
|
|
7005
8245
|
}
|
|
7006
8246
|
function isNavigationContainer(el) {
|
|
7007
|
-
return el.hasAttribute("data-ohw-nav-container") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
8247
|
+
return el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
8248
|
+
}
|
|
8249
|
+
function isNavbarLinksContainer(el) {
|
|
8250
|
+
return el.hasAttribute("data-ohw-nav-container");
|
|
8251
|
+
}
|
|
8252
|
+
function getFooterColumn(el) {
|
|
8253
|
+
return el.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
8254
|
+
}
|
|
8255
|
+
function resolveFooterColumnSelectionTarget(target, clientX, clientY) {
|
|
8256
|
+
if (getNavigationItemAnchor(target)) return null;
|
|
8257
|
+
const column = getFooterColumn(target);
|
|
8258
|
+
if (!column) return null;
|
|
8259
|
+
if (isPointOverNavItem(column, clientX, clientY)) return null;
|
|
8260
|
+
return column;
|
|
7008
8261
|
}
|
|
7009
8262
|
function isPointOverNavigation(x, y) {
|
|
8263
|
+
const roots = /* @__PURE__ */ new Set();
|
|
7010
8264
|
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
7011
|
-
if (
|
|
7012
|
-
const
|
|
7013
|
-
|
|
8265
|
+
if (navRoot) roots.add(navRoot);
|
|
8266
|
+
const footer = document.querySelector("footer");
|
|
8267
|
+
if (footer) roots.add(footer);
|
|
8268
|
+
for (const root of roots) {
|
|
8269
|
+
const r2 = root.getBoundingClientRect();
|
|
8270
|
+
if (x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom) return true;
|
|
8271
|
+
}
|
|
8272
|
+
return false;
|
|
8273
|
+
}
|
|
8274
|
+
function findHoveredNavOrFooterContainer(x, y) {
|
|
8275
|
+
const candidates = [
|
|
8276
|
+
...document.querySelectorAll("[data-ohw-nav-container]"),
|
|
8277
|
+
...listFooterColumns()
|
|
8278
|
+
];
|
|
8279
|
+
for (const container of candidates) {
|
|
8280
|
+
const r2 = container.getBoundingClientRect();
|
|
8281
|
+
if (x < r2.left || x > r2.right || y < r2.top || y > r2.bottom) continue;
|
|
8282
|
+
if (isPointOverNavItem(container, x, y)) continue;
|
|
8283
|
+
return container;
|
|
8284
|
+
}
|
|
8285
|
+
return null;
|
|
7014
8286
|
}
|
|
7015
8287
|
function isPointOverNavItem(container, x, y) {
|
|
7016
8288
|
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
|
|
@@ -7043,36 +8315,63 @@ function getNavigationSelectionParent(el) {
|
|
|
7043
8315
|
if (isNavigationItem(el)) {
|
|
7044
8316
|
const explicit = el.closest("[data-ohw-nav-container]");
|
|
7045
8317
|
if (explicit) return explicit;
|
|
8318
|
+
const footerColumn = getFooterColumn(el);
|
|
8319
|
+
if (footerColumn) return footerColumn;
|
|
7046
8320
|
const footerGroup = findFooterItemGroup(el);
|
|
7047
8321
|
if (footerGroup) return footerGroup;
|
|
7048
8322
|
return getNavigationRoot(el);
|
|
7049
8323
|
}
|
|
7050
|
-
if (el.hasAttribute("data-ohw-nav-container") || isInferredFooterGroup(el)) {
|
|
8324
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup(el)) {
|
|
7051
8325
|
return getNavigationRoot(el);
|
|
7052
8326
|
}
|
|
7053
8327
|
return null;
|
|
7054
8328
|
}
|
|
8329
|
+
function collectNavigationItemSiblingHintRects(selected) {
|
|
8330
|
+
if (!isNavigationItem(selected)) return [];
|
|
8331
|
+
const footerColumn = getFooterColumn(selected);
|
|
8332
|
+
if (footerColumn) {
|
|
8333
|
+
return listFooterLinksInColumn(footerColumn).filter((link) => link !== selected).map((link) => link.getBoundingClientRect());
|
|
8334
|
+
}
|
|
8335
|
+
const navContainer = selected.closest("[data-ohw-nav-container], [data-ohw-nav-drawer]");
|
|
8336
|
+
if (navContainer) {
|
|
8337
|
+
return Array.from(navContainer.querySelectorAll("[data-ohw-href-key]")).filter((el) => isNavigationItem(el) && el !== selected).map((el) => el.getBoundingClientRect());
|
|
8338
|
+
}
|
|
8339
|
+
return listNavigationItems().filter((el) => el !== selected).map((el) => el.getBoundingClientRect());
|
|
8340
|
+
}
|
|
7055
8341
|
function placeCaretAtPoint(el, x, y) {
|
|
7056
8342
|
const selection = window.getSelection();
|
|
7057
8343
|
if (!selection) return;
|
|
7058
|
-
|
|
7059
|
-
|
|
7060
|
-
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
8344
|
+
const overlays = Array.from(
|
|
8345
|
+
document.querySelectorAll(
|
|
8346
|
+
"[data-ohw-item-drag-surface], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-ohw-item-toolbar-anchor]"
|
|
8347
|
+
)
|
|
8348
|
+
);
|
|
8349
|
+
const prevPointerEvents = overlays.map((node) => node.style.pointerEvents);
|
|
8350
|
+
for (const node of overlays) node.style.pointerEvents = "none";
|
|
8351
|
+
try {
|
|
8352
|
+
if (typeof document.caretRangeFromPoint === "function") {
|
|
8353
|
+
const range = document.caretRangeFromPoint(x, y);
|
|
8354
|
+
if (range && el.contains(range.startContainer)) {
|
|
8355
|
+
selection.removeAllRanges();
|
|
8356
|
+
selection.addRange(range);
|
|
8357
|
+
return;
|
|
8358
|
+
}
|
|
7064
8359
|
}
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
8360
|
+
const caretPositionFromPoint = document.caretPositionFromPoint;
|
|
8361
|
+
if (typeof caretPositionFromPoint === "function") {
|
|
8362
|
+
const position = caretPositionFromPoint(x, y);
|
|
8363
|
+
if (position && el.contains(position.offsetNode)) {
|
|
8364
|
+
const range = document.createRange();
|
|
8365
|
+
range.setStart(position.offsetNode, position.offset);
|
|
8366
|
+
range.collapse(true);
|
|
8367
|
+
selection.removeAllRanges();
|
|
8368
|
+
selection.addRange(range);
|
|
8369
|
+
}
|
|
7075
8370
|
}
|
|
8371
|
+
} finally {
|
|
8372
|
+
overlays.forEach((node, i) => {
|
|
8373
|
+
node.style.pointerEvents = prevPointerEvents[i] ?? "";
|
|
8374
|
+
});
|
|
7076
8375
|
}
|
|
7077
8376
|
}
|
|
7078
8377
|
function selectAllTextInEditable(el) {
|
|
@@ -7214,6 +8513,9 @@ var ICONS = {
|
|
|
7214
8513
|
insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
|
|
7215
8514
|
insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
|
|
7216
8515
|
};
|
|
8516
|
+
var SELECTION_CHROME_GAP2 = 4;
|
|
8517
|
+
var TOOLBAR_STROKE_GAP2 = 4;
|
|
8518
|
+
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
7217
8519
|
var TOOLBAR_GROUPS = [
|
|
7218
8520
|
[
|
|
7219
8521
|
{ cmd: "bold", title: "Bold" },
|
|
@@ -7235,10 +8537,11 @@ function EditGlowChrome({
|
|
|
7235
8537
|
rect,
|
|
7236
8538
|
elRef,
|
|
7237
8539
|
reorderHrefKey,
|
|
7238
|
-
dragDisabled = false
|
|
8540
|
+
dragDisabled = false,
|
|
8541
|
+
hideHandle = false
|
|
7239
8542
|
}) {
|
|
7240
|
-
const GAP =
|
|
7241
|
-
return /* @__PURE__ */ (0,
|
|
8543
|
+
const GAP = SELECTION_CHROME_GAP2;
|
|
8544
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
7242
8545
|
"div",
|
|
7243
8546
|
{
|
|
7244
8547
|
ref: elRef,
|
|
@@ -7253,7 +8556,7 @@ function EditGlowChrome({
|
|
|
7253
8556
|
zIndex: 2147483646
|
|
7254
8557
|
},
|
|
7255
8558
|
children: [
|
|
7256
|
-
/* @__PURE__ */ (0,
|
|
8559
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
7257
8560
|
"div",
|
|
7258
8561
|
{
|
|
7259
8562
|
style: {
|
|
@@ -7261,12 +8564,12 @@ function EditGlowChrome({
|
|
|
7261
8564
|
inset: 0,
|
|
7262
8565
|
border: "2px solid var(--ohw-primary, #0885FE)",
|
|
7263
8566
|
borderRadius: 8,
|
|
7264
|
-
boxShadow: "0 0 0 4px
|
|
8567
|
+
boxShadow: "0 0 0 4px color-mix(in srgb, var(--ohw-primary, #0885FE) 12%, transparent)",
|
|
7265
8568
|
pointerEvents: "none"
|
|
7266
8569
|
}
|
|
7267
8570
|
}
|
|
7268
8571
|
),
|
|
7269
|
-
reorderHrefKey && /* @__PURE__ */ (0,
|
|
8572
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
7270
8573
|
"div",
|
|
7271
8574
|
{
|
|
7272
8575
|
"data-ohw-drag-handle-container": "",
|
|
@@ -7278,7 +8581,7 @@ function EditGlowChrome({
|
|
|
7278
8581
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
7279
8582
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
7280
8583
|
},
|
|
7281
|
-
children: /* @__PURE__ */ (0,
|
|
8584
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
7282
8585
|
DragHandle,
|
|
7283
8586
|
{
|
|
7284
8587
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -7309,6 +8612,7 @@ function applyVisibleViewport(el, parentScroll) {
|
|
|
7309
8612
|
el.style.top = `${top}px`;
|
|
7310
8613
|
el.style.height = `${height}px`;
|
|
7311
8614
|
}
|
|
8615
|
+
var TOOLBAR_EDGE_MARGIN2 = 4;
|
|
7312
8616
|
function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
7313
8617
|
const isAbove = transform.includes("translateY(-100%)");
|
|
7314
8618
|
let visualTop = isAbove ? top - approxH : top;
|
|
@@ -7332,10 +8636,16 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
7332
8636
|
const pinnedTop = Math.min(maxBottom - approxH, Math.max(minTop, clip.top + gap));
|
|
7333
8637
|
return { top: pinnedTop + approxH, transform: "translateX(-50%) translateY(-100%)" };
|
|
7334
8638
|
}
|
|
7335
|
-
function
|
|
7336
|
-
const
|
|
8639
|
+
function clampToolbarLeft(centerX, toolbarWidth) {
|
|
8640
|
+
const half = toolbarWidth / 2;
|
|
8641
|
+
return Math.max(
|
|
8642
|
+
TOOLBAR_EDGE_MARGIN2 + half,
|
|
8643
|
+
Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN2 - half)
|
|
8644
|
+
);
|
|
8645
|
+
}
|
|
8646
|
+
function calcToolbarPos(rect, parentScroll, toolbarW = 306) {
|
|
8647
|
+
const GAP = TOOLBAR_OFFSET_FROM_ELEMENT;
|
|
7337
8648
|
const APPROX_H = 32;
|
|
7338
|
-
const APPROX_W = approxW;
|
|
7339
8649
|
const clip = getIframeVisibleClip(parentScroll);
|
|
7340
8650
|
const clipTop = clip?.top ?? 0;
|
|
7341
8651
|
const canvasTopInIframe = parentScroll != null ? parentScroll.headerH - parentScroll.iframeOffsetTop : 0;
|
|
@@ -7365,7 +8675,7 @@ function calcToolbarPos(rect, parentScroll, approxW = 306) {
|
|
|
7365
8675
|
transform = clamped.transform;
|
|
7366
8676
|
}
|
|
7367
8677
|
const rawLeft = rect.left + rect.width / 2;
|
|
7368
|
-
const left =
|
|
8678
|
+
const left = clampToolbarLeft(rawLeft, toolbarW);
|
|
7369
8679
|
return { top, left, transform };
|
|
7370
8680
|
}
|
|
7371
8681
|
function resolveItemInteractionState(rect, parentScroll) {
|
|
@@ -7381,11 +8691,37 @@ function FloatingToolbar({
|
|
|
7381
8691
|
showEditLink,
|
|
7382
8692
|
onEditLink
|
|
7383
8693
|
}) {
|
|
7384
|
-
const
|
|
7385
|
-
|
|
8694
|
+
const localRef = import_react9.default.useRef(null);
|
|
8695
|
+
const [measuredW, setMeasuredW] = import_react9.default.useState(330);
|
|
8696
|
+
const setRefs = import_react9.default.useCallback(
|
|
8697
|
+
(node) => {
|
|
8698
|
+
localRef.current = node;
|
|
8699
|
+
if (typeof elRef === "function") elRef(node);
|
|
8700
|
+
else if (elRef) elRef.current = node;
|
|
8701
|
+
if (node) {
|
|
8702
|
+
const w = node.offsetWidth;
|
|
8703
|
+
if (w > 0) setMeasuredW(w);
|
|
8704
|
+
}
|
|
8705
|
+
},
|
|
8706
|
+
[elRef]
|
|
8707
|
+
);
|
|
8708
|
+
import_react9.default.useLayoutEffect(() => {
|
|
8709
|
+
const node = localRef.current;
|
|
8710
|
+
if (!node) return;
|
|
8711
|
+
const update = () => {
|
|
8712
|
+
const w = node.offsetWidth;
|
|
8713
|
+
if (w > 0) setMeasuredW(w);
|
|
8714
|
+
};
|
|
8715
|
+
update();
|
|
8716
|
+
const ro = new ResizeObserver(update);
|
|
8717
|
+
ro.observe(node);
|
|
8718
|
+
return () => ro.disconnect();
|
|
8719
|
+
}, [showEditLink, activeCommands]);
|
|
8720
|
+
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
8721
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
7386
8722
|
"div",
|
|
7387
8723
|
{
|
|
7388
|
-
ref:
|
|
8724
|
+
ref: setRefs,
|
|
7389
8725
|
style: {
|
|
7390
8726
|
position: "fixed",
|
|
7391
8727
|
top,
|
|
@@ -7394,12 +8730,12 @@ function FloatingToolbar({
|
|
|
7394
8730
|
zIndex: 2147483647,
|
|
7395
8731
|
pointerEvents: "auto"
|
|
7396
8732
|
},
|
|
7397
|
-
children: /* @__PURE__ */ (0,
|
|
7398
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
7399
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
8733
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(CustomToolbar, { children: [
|
|
8734
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react9.default.Fragment, { children: [
|
|
8735
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CustomToolbarDivider, {}),
|
|
7400
8736
|
btns.map((btn) => {
|
|
7401
8737
|
const isActive = activeCommands.has(btn.cmd);
|
|
7402
|
-
return /* @__PURE__ */ (0,
|
|
8738
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
7403
8739
|
CustomToolbarButton,
|
|
7404
8740
|
{
|
|
7405
8741
|
title: btn.title,
|
|
@@ -7408,7 +8744,7 @@ function FloatingToolbar({
|
|
|
7408
8744
|
e.preventDefault();
|
|
7409
8745
|
onCommand(btn.cmd);
|
|
7410
8746
|
},
|
|
7411
|
-
children: /* @__PURE__ */ (0,
|
|
8747
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
7412
8748
|
"svg",
|
|
7413
8749
|
{
|
|
7414
8750
|
width: "16",
|
|
@@ -7429,7 +8765,7 @@ function FloatingToolbar({
|
|
|
7429
8765
|
);
|
|
7430
8766
|
})
|
|
7431
8767
|
] }, gi)),
|
|
7432
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
8768
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
7433
8769
|
CustomToolbarButton,
|
|
7434
8770
|
{
|
|
7435
8771
|
type: "button",
|
|
@@ -7443,7 +8779,7 @@ function FloatingToolbar({
|
|
|
7443
8779
|
e.preventDefault();
|
|
7444
8780
|
e.stopPropagation();
|
|
7445
8781
|
},
|
|
7446
|
-
children: /* @__PURE__ */ (0,
|
|
8782
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react11.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
7447
8783
|
}
|
|
7448
8784
|
) : null
|
|
7449
8785
|
] })
|
|
@@ -7460,7 +8796,7 @@ function StateToggle({
|
|
|
7460
8796
|
states,
|
|
7461
8797
|
onStateChange
|
|
7462
8798
|
}) {
|
|
7463
|
-
return /* @__PURE__ */ (0,
|
|
8799
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
7464
8800
|
ToggleGroup,
|
|
7465
8801
|
{
|
|
7466
8802
|
"data-ohw-state-toggle": "",
|
|
@@ -7474,7 +8810,7 @@ function StateToggle({
|
|
|
7474
8810
|
left: rect.right - 8,
|
|
7475
8811
|
transform: "translateX(-100%)"
|
|
7476
8812
|
},
|
|
7477
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
8813
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
7478
8814
|
}
|
|
7479
8815
|
);
|
|
7480
8816
|
}
|
|
@@ -7501,8 +8837,8 @@ function OhhwellsBridge() {
|
|
|
7501
8837
|
const router = (0, import_navigation2.useRouter)();
|
|
7502
8838
|
const searchParams = (0, import_navigation2.useSearchParams)();
|
|
7503
8839
|
const isEditMode = isEditSessionActive();
|
|
7504
|
-
const [bridgeRoot, setBridgeRoot] = (0,
|
|
7505
|
-
(0,
|
|
8840
|
+
const [bridgeRoot, setBridgeRoot] = (0, import_react9.useState)(null);
|
|
8841
|
+
(0, import_react9.useEffect)(() => {
|
|
7506
8842
|
const figtreeFontId = "ohw-figtree-font";
|
|
7507
8843
|
if (!document.getElementById(figtreeFontId)) {
|
|
7508
8844
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -7530,91 +8866,136 @@ function OhhwellsBridge() {
|
|
|
7530
8866
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
7531
8867
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
7532
8868
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
7533
|
-
const postToParent2 = (0,
|
|
8869
|
+
const postToParent2 = (0, import_react9.useCallback)((data) => {
|
|
7534
8870
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
7535
8871
|
window.parent.postMessage(data, "*");
|
|
7536
8872
|
}
|
|
7537
8873
|
}, []);
|
|
7538
|
-
const [fetchState, setFetchState] = (0,
|
|
7539
|
-
const autoSaveTimers = (0,
|
|
7540
|
-
const activeElRef = (0,
|
|
7541
|
-
const selectedElRef = (0,
|
|
7542
|
-
const
|
|
7543
|
-
const
|
|
7544
|
-
const
|
|
7545
|
-
const
|
|
7546
|
-
const
|
|
7547
|
-
const
|
|
8874
|
+
const [fetchState, setFetchState] = (0, import_react9.useState)("idle");
|
|
8875
|
+
const autoSaveTimers = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
8876
|
+
const activeElRef = (0, import_react9.useRef)(null);
|
|
8877
|
+
const selectedElRef = (0, import_react9.useRef)(null);
|
|
8878
|
+
const selectedHrefKeyRef = (0, import_react9.useRef)(null);
|
|
8879
|
+
const selectedFooterColAttrRef = (0, import_react9.useRef)(null);
|
|
8880
|
+
const originalContentRef = (0, import_react9.useRef)(null);
|
|
8881
|
+
const activeStateElRef = (0, import_react9.useRef)(null);
|
|
8882
|
+
const parentScrollRef = (0, import_react9.useRef)(null);
|
|
8883
|
+
const visibleViewportRef = (0, import_react9.useRef)(null);
|
|
8884
|
+
const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react9.useState)(null);
|
|
8885
|
+
const attachVisibleViewport = (0, import_react9.useCallback)((node) => {
|
|
7548
8886
|
visibleViewportRef.current = node;
|
|
7549
8887
|
setDialogPortalContainer(node);
|
|
7550
8888
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
7551
8889
|
}, []);
|
|
7552
|
-
const toolbarElRef = (0,
|
|
7553
|
-
const glowElRef = (0,
|
|
7554
|
-
const hoveredImageRef = (0,
|
|
7555
|
-
const hoveredImageHasTextOverlapRef = (0,
|
|
7556
|
-
const dragOverElRef = (0,
|
|
7557
|
-
const [mediaHover, setMediaHover] = (0,
|
|
7558
|
-
const [uploadingRects, setUploadingRects] = (0,
|
|
7559
|
-
const hoveredGapRef = (0,
|
|
7560
|
-
const imageUnhoverTimerRef = (0,
|
|
7561
|
-
const imageShowTimerRef = (0,
|
|
7562
|
-
const editStylesRef = (0,
|
|
7563
|
-
const activateRef = (0,
|
|
8890
|
+
const toolbarElRef = (0, import_react9.useRef)(null);
|
|
8891
|
+
const glowElRef = (0, import_react9.useRef)(null);
|
|
8892
|
+
const hoveredImageRef = (0, import_react9.useRef)(null);
|
|
8893
|
+
const hoveredImageHasTextOverlapRef = (0, import_react9.useRef)(false);
|
|
8894
|
+
const dragOverElRef = (0, import_react9.useRef)(null);
|
|
8895
|
+
const [mediaHover, setMediaHover] = (0, import_react9.useState)(null);
|
|
8896
|
+
const [uploadingRects, setUploadingRects] = (0, import_react9.useState)({});
|
|
8897
|
+
const hoveredGapRef = (0, import_react9.useRef)(null);
|
|
8898
|
+
const imageUnhoverTimerRef = (0, import_react9.useRef)(null);
|
|
8899
|
+
const imageShowTimerRef = (0, import_react9.useRef)(null);
|
|
8900
|
+
const editStylesRef = (0, import_react9.useRef)(null);
|
|
8901
|
+
const activateRef = (0, import_react9.useRef)(() => {
|
|
7564
8902
|
});
|
|
7565
|
-
const deactivateRef = (0,
|
|
8903
|
+
const deactivateRef = (0, import_react9.useRef)(() => {
|
|
7566
8904
|
});
|
|
7567
|
-
const selectRef = (0,
|
|
8905
|
+
const selectRef = (0, import_react9.useRef)(() => {
|
|
7568
8906
|
});
|
|
7569
|
-
const selectFrameRef = (0,
|
|
8907
|
+
const selectFrameRef = (0, import_react9.useRef)(() => {
|
|
7570
8908
|
});
|
|
7571
|
-
const deselectRef = (0,
|
|
8909
|
+
const deselectRef = (0, import_react9.useRef)(() => {
|
|
7572
8910
|
});
|
|
7573
|
-
const reselectNavigationItemRef = (0,
|
|
8911
|
+
const reselectNavigationItemRef = (0, import_react9.useRef)(() => {
|
|
7574
8912
|
});
|
|
7575
|
-
const commitNavigationTextEditRef = (0,
|
|
8913
|
+
const commitNavigationTextEditRef = (0, import_react9.useRef)(() => {
|
|
7576
8914
|
});
|
|
7577
|
-
const refreshActiveCommandsRef = (0,
|
|
8915
|
+
const refreshActiveCommandsRef = (0, import_react9.useRef)(() => {
|
|
7578
8916
|
});
|
|
7579
|
-
const postToParentRef = (0,
|
|
8917
|
+
const postToParentRef = (0, import_react9.useRef)(postToParent2);
|
|
7580
8918
|
postToParentRef.current = postToParent2;
|
|
7581
|
-
const sectionsLoadedRef = (0,
|
|
7582
|
-
const pendingScheduleConfigRequests = (0,
|
|
7583
|
-
const [toolbarRect, setToolbarRect] = (0,
|
|
7584
|
-
const [toolbarVariant, setToolbarVariant] = (0,
|
|
7585
|
-
const toolbarVariantRef = (0,
|
|
8919
|
+
const sectionsLoadedRef = (0, import_react9.useRef)(false);
|
|
8920
|
+
const pendingScheduleConfigRequests = (0, import_react9.useRef)([]);
|
|
8921
|
+
const [toolbarRect, setToolbarRect] = (0, import_react9.useState)(null);
|
|
8922
|
+
const [toolbarVariant, setToolbarVariant] = (0, import_react9.useState)("none");
|
|
8923
|
+
const toolbarVariantRef = (0, import_react9.useRef)("none");
|
|
7586
8924
|
toolbarVariantRef.current = toolbarVariant;
|
|
7587
|
-
const [
|
|
7588
|
-
const [
|
|
7589
|
-
const [
|
|
7590
|
-
const [
|
|
7591
|
-
const [
|
|
7592
|
-
const [
|
|
7593
|
-
const [
|
|
7594
|
-
const
|
|
7595
|
-
const
|
|
7596
|
-
const
|
|
7597
|
-
const
|
|
7598
|
-
const
|
|
7599
|
-
const
|
|
7600
|
-
const [
|
|
7601
|
-
const [
|
|
7602
|
-
const
|
|
7603
|
-
const
|
|
7604
|
-
const
|
|
7605
|
-
const [
|
|
7606
|
-
const [
|
|
7607
|
-
const
|
|
7608
|
-
const
|
|
7609
|
-
const
|
|
7610
|
-
const
|
|
7611
|
-
const
|
|
8925
|
+
const [selectedIsCta, setSelectedIsCta] = (0, import_react9.useState)(false);
|
|
8926
|
+
const [reorderHrefKey, setReorderHrefKey] = (0, import_react9.useState)(null);
|
|
8927
|
+
const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react9.useState)(false);
|
|
8928
|
+
const [toggleState, setToggleState] = (0, import_react9.useState)(null);
|
|
8929
|
+
const [maxBadge, setMaxBadge] = (0, import_react9.useState)(null);
|
|
8930
|
+
const [activeCommands, setActiveCommands] = (0, import_react9.useState)(/* @__PURE__ */ new Set());
|
|
8931
|
+
const [sectionGap, setSectionGap] = (0, import_react9.useState)(null);
|
|
8932
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react9.useState)(false);
|
|
8933
|
+
const hoveredNavContainerRef = (0, import_react9.useRef)(null);
|
|
8934
|
+
const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react9.useState)(null);
|
|
8935
|
+
const hoveredItemElRef = (0, import_react9.useRef)(null);
|
|
8936
|
+
const [hoveredItemRect, setHoveredItemRect] = (0, import_react9.useState)(null);
|
|
8937
|
+
const siblingHintElRef = (0, import_react9.useRef)(null);
|
|
8938
|
+
const [siblingHintRect, setSiblingHintRect] = (0, import_react9.useState)(null);
|
|
8939
|
+
const [siblingHintRects, setSiblingHintRects] = (0, import_react9.useState)([]);
|
|
8940
|
+
const [isItemDragging, setIsItemDragging] = (0, import_react9.useState)(false);
|
|
8941
|
+
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react9.useState)(false);
|
|
8942
|
+
const footerDragRef = (0, import_react9.useRef)(null);
|
|
8943
|
+
const [footerDropSlots, setFooterDropSlots] = (0, import_react9.useState)([]);
|
|
8944
|
+
const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react9.useState)(null);
|
|
8945
|
+
const [draggedItemRect, setDraggedItemRect] = (0, import_react9.useState)(null);
|
|
8946
|
+
const footerPointerDragRef = (0, import_react9.useRef)(null);
|
|
8947
|
+
const suppressNextClickRef = (0, import_react9.useRef)(false);
|
|
8948
|
+
const suppressClickUntilRef = (0, import_react9.useRef)(0);
|
|
8949
|
+
const [linkPopover, setLinkPopover] = (0, import_react9.useState)(null);
|
|
8950
|
+
const linkPopoverSessionRef = (0, import_react9.useRef)(null);
|
|
8951
|
+
const addNavAfterAnchorRef = (0, import_react9.useRef)(null);
|
|
8952
|
+
const editContentRef = (0, import_react9.useRef)({});
|
|
8953
|
+
const [sitePages, setSitePages] = (0, import_react9.useState)([]);
|
|
8954
|
+
const [sectionsByPath, setSectionsByPath] = (0, import_react9.useState)({});
|
|
8955
|
+
const sectionsPrefetchGenRef = (0, import_react9.useRef)(0);
|
|
8956
|
+
const setLinkPopoverRef = (0, import_react9.useRef)(setLinkPopover);
|
|
8957
|
+
const linkPopoverPanelRef = (0, import_react9.useRef)(null);
|
|
8958
|
+
const linkPopoverOpenRef = (0, import_react9.useRef)(false);
|
|
8959
|
+
const linkPopoverGraceUntilRef = (0, import_react9.useRef)(0);
|
|
7612
8960
|
setLinkPopoverRef.current = setLinkPopover;
|
|
7613
8961
|
linkPopoverSessionRef.current = linkPopover;
|
|
8962
|
+
const {
|
|
8963
|
+
navDragRef,
|
|
8964
|
+
navDropSlots,
|
|
8965
|
+
activeNavDropIndex,
|
|
8966
|
+
startNavLinkDrag,
|
|
8967
|
+
commitNavDrag,
|
|
8968
|
+
onNavDragOver,
|
|
8969
|
+
armNavPressFromChrome,
|
|
8970
|
+
refreshNavDragVisualsRef
|
|
8971
|
+
} = useNavItemDrag({
|
|
8972
|
+
isEditMode,
|
|
8973
|
+
editContentRef,
|
|
8974
|
+
selectedElRef,
|
|
8975
|
+
activeElRef,
|
|
8976
|
+
footerDragRef,
|
|
8977
|
+
suppressNextClickRef,
|
|
8978
|
+
suppressClickUntilRef,
|
|
8979
|
+
siblingHintElRef,
|
|
8980
|
+
postToParentRef,
|
|
8981
|
+
deselectRef,
|
|
8982
|
+
selectRef,
|
|
8983
|
+
deactivateRef,
|
|
8984
|
+
setLinkPopover: () => setLinkPopover(null),
|
|
8985
|
+
linkPopoverOpenRef,
|
|
8986
|
+
setIsItemDragging,
|
|
8987
|
+
setDraggedItemRect,
|
|
8988
|
+
setSiblingHintRect,
|
|
8989
|
+
setSiblingHintRects,
|
|
8990
|
+
setToolbarRect,
|
|
8991
|
+
getNavigationItemAnchor,
|
|
8992
|
+
isDragHandleDisabled,
|
|
8993
|
+
isNavbarButton: isNavbarButton2
|
|
8994
|
+
});
|
|
7614
8995
|
const bumpLinkPopoverGrace = () => {
|
|
7615
8996
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
7616
8997
|
};
|
|
7617
|
-
const runSectionsPrefetch = (0,
|
|
8998
|
+
const runSectionsPrefetch = (0, import_react9.useCallback)((pages) => {
|
|
7618
8999
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
7619
9000
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
7620
9001
|
const paths = pages.map((p) => p.path);
|
|
@@ -7633,10 +9014,24 @@ function OhhwellsBridge() {
|
|
|
7633
9014
|
);
|
|
7634
9015
|
});
|
|
7635
9016
|
}, [isEditMode, pathname]);
|
|
7636
|
-
const runSectionsPrefetchRef = (0,
|
|
9017
|
+
const runSectionsPrefetchRef = (0, import_react9.useRef)(runSectionsPrefetch);
|
|
7637
9018
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
7638
|
-
(0,
|
|
7639
|
-
if (!linkPopover)
|
|
9019
|
+
(0, import_react9.useEffect)(() => {
|
|
9020
|
+
if (!linkPopover) {
|
|
9021
|
+
document.documentElement.removeAttribute("data-ohw-link-popover-open");
|
|
9022
|
+
return;
|
|
9023
|
+
}
|
|
9024
|
+
document.documentElement.setAttribute("data-ohw-link-popover-open", "");
|
|
9025
|
+
hoveredItemElRef.current = null;
|
|
9026
|
+
setHoveredItemRect(null);
|
|
9027
|
+
hoveredNavContainerRef.current = null;
|
|
9028
|
+
setHoveredNavContainerRect(null);
|
|
9029
|
+
siblingHintElRef.current = null;
|
|
9030
|
+
setSiblingHintRect(null);
|
|
9031
|
+
setSiblingHintRects([]);
|
|
9032
|
+
if (selectedElRef.current || toolbarVariantRef.current !== "none") {
|
|
9033
|
+
deselectRef.current();
|
|
9034
|
+
}
|
|
7640
9035
|
if (hoveredImageRef.current) {
|
|
7641
9036
|
hoveredImageRef.current = null;
|
|
7642
9037
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -7670,7 +9065,7 @@ function OhhwellsBridge() {
|
|
|
7670
9065
|
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
7671
9066
|
};
|
|
7672
9067
|
}, [linkPopover, postToParent2]);
|
|
7673
|
-
(0,
|
|
9068
|
+
(0, import_react9.useEffect)(() => {
|
|
7674
9069
|
if (!isEditMode) return;
|
|
7675
9070
|
const useFixtures = shouldUseDevFixtures();
|
|
7676
9071
|
if (useFixtures) {
|
|
@@ -7694,14 +9089,14 @@ function OhhwellsBridge() {
|
|
|
7694
9089
|
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
7695
9090
|
return () => window.removeEventListener("message", onSitePages);
|
|
7696
9091
|
}, [isEditMode, postToParent2]);
|
|
7697
|
-
(0,
|
|
9092
|
+
(0, import_react9.useEffect)(() => {
|
|
7698
9093
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
7699
9094
|
void loadAllSectionsManifest().then((manifest) => {
|
|
7700
9095
|
if (Object.keys(manifest).length === 0) return;
|
|
7701
9096
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
7702
9097
|
});
|
|
7703
9098
|
}, [isEditMode]);
|
|
7704
|
-
(0,
|
|
9099
|
+
(0, import_react9.useEffect)(() => {
|
|
7705
9100
|
const update = () => {
|
|
7706
9101
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
7707
9102
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -7725,10 +9120,10 @@ function OhhwellsBridge() {
|
|
|
7725
9120
|
vvp.removeEventListener("resize", update);
|
|
7726
9121
|
};
|
|
7727
9122
|
}, []);
|
|
7728
|
-
const refreshStateRules = (0,
|
|
9123
|
+
const refreshStateRules = (0, import_react9.useCallback)(() => {
|
|
7729
9124
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
7730
9125
|
}, []);
|
|
7731
|
-
const processConfigRequest = (0,
|
|
9126
|
+
const processConfigRequest = (0, import_react9.useCallback)((insertAfterVal) => {
|
|
7732
9127
|
const tracker = getSectionsTracker();
|
|
7733
9128
|
let entries = [];
|
|
7734
9129
|
try {
|
|
@@ -7751,7 +9146,7 @@ function OhhwellsBridge() {
|
|
|
7751
9146
|
}
|
|
7752
9147
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
7753
9148
|
}, [isEditMode]);
|
|
7754
|
-
const deactivate = (0,
|
|
9149
|
+
const deactivate = (0, import_react9.useCallback)(() => {
|
|
7755
9150
|
const el = activeElRef.current;
|
|
7756
9151
|
if (!el) return;
|
|
7757
9152
|
const key = el.dataset.ohwKey;
|
|
@@ -7770,6 +9165,7 @@ function OhhwellsBridge() {
|
|
|
7770
9165
|
}
|
|
7771
9166
|
}
|
|
7772
9167
|
el.removeAttribute("contenteditable");
|
|
9168
|
+
el.removeAttribute("data-ohw-editing");
|
|
7773
9169
|
activeElRef.current = null;
|
|
7774
9170
|
setReorderHrefKey(null);
|
|
7775
9171
|
setReorderDragDisabled(false);
|
|
@@ -7782,12 +9178,23 @@ function OhhwellsBridge() {
|
|
|
7782
9178
|
setToolbarShowEditLink(false);
|
|
7783
9179
|
postToParent2({ type: "ow:exit-edit" });
|
|
7784
9180
|
}, [postToParent2]);
|
|
7785
|
-
const
|
|
9181
|
+
const clearSelectedAttr = (0, import_react9.useCallback)(() => {
|
|
9182
|
+
document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
|
|
9183
|
+
el.removeAttribute("data-ohw-selected");
|
|
9184
|
+
});
|
|
9185
|
+
}, []);
|
|
9186
|
+
const deselect = (0, import_react9.useCallback)(() => {
|
|
9187
|
+
clearSelectedAttr();
|
|
7786
9188
|
selectedElRef.current = null;
|
|
9189
|
+
selectedHrefKeyRef.current = null;
|
|
9190
|
+
selectedFooterColAttrRef.current = null;
|
|
9191
|
+
setSelectedIsCta(false);
|
|
7787
9192
|
setReorderHrefKey(null);
|
|
7788
9193
|
setReorderDragDisabled(false);
|
|
9194
|
+
setIsFooterFrameSelection(false);
|
|
7789
9195
|
siblingHintElRef.current = null;
|
|
7790
9196
|
setSiblingHintRect(null);
|
|
9197
|
+
setSiblingHintRects([]);
|
|
7791
9198
|
setIsItemDragging(false);
|
|
7792
9199
|
hoveredNavContainerRef.current = null;
|
|
7793
9200
|
setHoveredNavContainerRect(null);
|
|
@@ -7795,18 +9202,70 @@ function OhhwellsBridge() {
|
|
|
7795
9202
|
setToolbarRect(null);
|
|
7796
9203
|
setToolbarVariant("none");
|
|
7797
9204
|
}
|
|
9205
|
+
}, [clearSelectedAttr]);
|
|
9206
|
+
const markSelected = (0, import_react9.useCallback)((el) => {
|
|
9207
|
+
clearSelectedAttr();
|
|
9208
|
+
el.setAttribute("data-ohw-selected", "");
|
|
9209
|
+
}, [clearSelectedAttr]);
|
|
9210
|
+
const resolveHrefKeyElement = (0, import_react9.useCallback)((hrefKey) => {
|
|
9211
|
+
if (isFooterHrefKey(hrefKey)) {
|
|
9212
|
+
return document.querySelector(
|
|
9213
|
+
`footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
9214
|
+
);
|
|
9215
|
+
}
|
|
9216
|
+
if (isNavbarHrefKey(hrefKey)) {
|
|
9217
|
+
const desktop = document.querySelector("[data-ohw-nav-container]");
|
|
9218
|
+
const drawer = document.querySelector("[data-ohw-nav-drawer]");
|
|
9219
|
+
return desktop?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? drawer?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
9220
|
+
}
|
|
9221
|
+
return document.querySelector(
|
|
9222
|
+
`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
|
|
9223
|
+
);
|
|
7798
9224
|
}, []);
|
|
7799
|
-
const
|
|
9225
|
+
const resyncSelectedNavigationItem = (0, import_react9.useCallback)(() => {
|
|
9226
|
+
const hrefKey = selectedHrefKeyRef.current;
|
|
9227
|
+
if (hrefKey) {
|
|
9228
|
+
const link = resolveHrefKeyElement(hrefKey);
|
|
9229
|
+
if (!link || !isNavigationItem(link)) return;
|
|
9230
|
+
selectedElRef.current = link;
|
|
9231
|
+
const { key, disabled } = getNavigationItemReorderState(link);
|
|
9232
|
+
setReorderHrefKey(key);
|
|
9233
|
+
setReorderDragDisabled(disabled);
|
|
9234
|
+
setIsFooterFrameSelection(false);
|
|
9235
|
+
setToolbarVariant("link-action");
|
|
9236
|
+
setToolbarRect(link.getBoundingClientRect());
|
|
9237
|
+
setSiblingHintRects(collectNavigationItemSiblingHintRects(link));
|
|
9238
|
+
return;
|
|
9239
|
+
}
|
|
9240
|
+
const colAttr = selectedFooterColAttrRef.current;
|
|
9241
|
+
if (colAttr != null) {
|
|
9242
|
+
const column = document.querySelector(`[data-ohw-footer-col="${CSS.escape(colAttr)}"]`) ?? listFooterColumns()[Number(colAttr)] ?? null;
|
|
9243
|
+
if (!column || !isNavigationContainer(column)) return;
|
|
9244
|
+
selectedElRef.current = column;
|
|
9245
|
+
setIsFooterFrameSelection(true);
|
|
9246
|
+
setToolbarVariant("select-frame");
|
|
9247
|
+
setToolbarRect(column.getBoundingClientRect());
|
|
9248
|
+
setSiblingHintRects(
|
|
9249
|
+
listFooterColumns().filter((c) => c !== column).map((c) => c.getBoundingClientRect())
|
|
9250
|
+
);
|
|
9251
|
+
}
|
|
9252
|
+
}, [resolveHrefKeyElement]);
|
|
9253
|
+
const reselectNavigationItem = (0, import_react9.useCallback)((navAnchor) => {
|
|
7800
9254
|
selectedElRef.current = navAnchor;
|
|
9255
|
+
selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
|
|
9256
|
+
selectedFooterColAttrRef.current = null;
|
|
9257
|
+
markSelected(navAnchor);
|
|
9258
|
+
setSelectedIsCta(isNavbarButton2(navAnchor));
|
|
7801
9259
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
7802
9260
|
setReorderHrefKey(key);
|
|
7803
9261
|
setReorderDragDisabled(disabled);
|
|
7804
9262
|
setToolbarVariant("link-action");
|
|
7805
9263
|
setToolbarRect(navAnchor.getBoundingClientRect());
|
|
9264
|
+
setSiblingHintRects(collectNavigationItemSiblingHintRects(navAnchor));
|
|
7806
9265
|
setToolbarShowEditLink(false);
|
|
7807
9266
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7808
|
-
}, []);
|
|
7809
|
-
const commitNavigationTextEdit = (0,
|
|
9267
|
+
}, [markSelected]);
|
|
9268
|
+
const commitNavigationTextEdit = (0, import_react9.useCallback)((navAnchor) => {
|
|
7810
9269
|
const el = activeElRef.current;
|
|
7811
9270
|
if (!el) return;
|
|
7812
9271
|
const key = el.dataset.ohwKey;
|
|
@@ -7825,6 +9284,7 @@ function OhhwellsBridge() {
|
|
|
7825
9284
|
}
|
|
7826
9285
|
}
|
|
7827
9286
|
el.removeAttribute("contenteditable");
|
|
9287
|
+
el.removeAttribute("data-ohw-editing");
|
|
7828
9288
|
activeElRef.current = null;
|
|
7829
9289
|
setMaxBadge(null);
|
|
7830
9290
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
@@ -7832,7 +9292,7 @@ function OhhwellsBridge() {
|
|
|
7832
9292
|
postToParent2({ type: "ow:exit-edit" });
|
|
7833
9293
|
reselectNavigationItem(navAnchor);
|
|
7834
9294
|
}, [postToParent2, reselectNavigationItem]);
|
|
7835
|
-
const handleAddTopLevelNavItem = (0,
|
|
9295
|
+
const handleAddTopLevelNavItem = (0, import_react9.useCallback)(() => {
|
|
7836
9296
|
const items = listNavbarItems();
|
|
7837
9297
|
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
7838
9298
|
deselectRef.current();
|
|
@@ -7844,20 +9304,310 @@ function OhhwellsBridge() {
|
|
|
7844
9304
|
intent: "add-nav"
|
|
7845
9305
|
});
|
|
7846
9306
|
}, []);
|
|
7847
|
-
const
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
9307
|
+
const clearFooterDragVisuals = (0, import_react9.useCallback)(() => {
|
|
9308
|
+
footerDragRef.current = null;
|
|
9309
|
+
setSiblingHintRects([]);
|
|
9310
|
+
setFooterDropSlots([]);
|
|
9311
|
+
setActiveFooterDropIndex(null);
|
|
9312
|
+
setDraggedItemRect(null);
|
|
7853
9313
|
setIsItemDragging(false);
|
|
9314
|
+
unlockFooterDragInteraction();
|
|
9315
|
+
}, []);
|
|
9316
|
+
const refreshFooterDragVisuals = (0, import_react9.useCallback)((session, activeSlot, clientX, clientY) => {
|
|
9317
|
+
const dragged = session.draggedEl;
|
|
9318
|
+
setDraggedItemRect(dragged.getBoundingClientRect());
|
|
9319
|
+
if (typeof clientX === "number" && typeof clientY === "number") {
|
|
9320
|
+
session.lastClientX = clientX;
|
|
9321
|
+
session.lastClientY = clientY;
|
|
9322
|
+
}
|
|
9323
|
+
session.activeSlot = activeSlot;
|
|
9324
|
+
setSiblingHintRects([]);
|
|
9325
|
+
if (session.kind === "link") {
|
|
9326
|
+
const columns = listFooterColumns();
|
|
9327
|
+
const slots2 = [];
|
|
9328
|
+
columns.forEach((col, i) => {
|
|
9329
|
+
slots2.push(...buildLinkDropSlots(col, i));
|
|
9330
|
+
});
|
|
9331
|
+
setFooterDropSlots(slots2);
|
|
9332
|
+
const activeIdx2 = activeSlot ? slots2.findIndex((s) => s.columnIndex === activeSlot.columnIndex && s.insertIndex === activeSlot.insertIndex) : -1;
|
|
9333
|
+
setActiveFooterDropIndex(activeIdx2 >= 0 ? activeIdx2 : null);
|
|
9334
|
+
return;
|
|
9335
|
+
}
|
|
9336
|
+
const slots = buildColumnDropSlots();
|
|
9337
|
+
setFooterDropSlots(slots);
|
|
9338
|
+
const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
|
|
9339
|
+
setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
|
|
9340
|
+
}, []);
|
|
9341
|
+
const refreshFooterDragVisualsRef = (0, import_react9.useRef)(refreshFooterDragVisuals);
|
|
9342
|
+
refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
|
|
9343
|
+
const commitFooterDragRef = (0, import_react9.useRef)(() => {
|
|
9344
|
+
});
|
|
9345
|
+
const beginFooterDragRef = (0, import_react9.useRef)(() => {
|
|
9346
|
+
});
|
|
9347
|
+
const beginFooterDrag = (0, import_react9.useCallback)(
|
|
9348
|
+
(session) => {
|
|
9349
|
+
const rect = session.draggedEl.getBoundingClientRect();
|
|
9350
|
+
session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
|
|
9351
|
+
session.lastClientY = session.lastClientY || rect.top + rect.height / 2;
|
|
9352
|
+
session.activeSlot = session.activeSlot ?? null;
|
|
9353
|
+
footerDragRef.current = session;
|
|
9354
|
+
setIsItemDragging(true);
|
|
9355
|
+
lockFooterDuringDrag();
|
|
9356
|
+
siblingHintElRef.current = null;
|
|
9357
|
+
setSiblingHintRect(null);
|
|
9358
|
+
if (session.wasSelected && selectedElRef.current === session.draggedEl) {
|
|
9359
|
+
setToolbarRect(rect);
|
|
9360
|
+
}
|
|
9361
|
+
const initialSlot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
9362
|
+
refreshFooterDragVisuals(session, initialSlot, session.lastClientX, session.lastClientY);
|
|
9363
|
+
},
|
|
9364
|
+
[refreshFooterDragVisuals]
|
|
9365
|
+
);
|
|
9366
|
+
beginFooterDragRef.current = beginFooterDrag;
|
|
9367
|
+
const commitFooterDrag = (0, import_react9.useCallback)(
|
|
9368
|
+
(clientX, clientY) => {
|
|
9369
|
+
const session = footerDragRef.current;
|
|
9370
|
+
if (!session) {
|
|
9371
|
+
clearFooterDragVisuals();
|
|
9372
|
+
return;
|
|
9373
|
+
}
|
|
9374
|
+
const x = typeof clientX === "number" && (clientX !== 0 || clientY !== 0) ? clientX : session.lastClientX;
|
|
9375
|
+
const y = typeof clientY === "number" && (clientX !== 0 || clientY !== 0) ? clientY : session.lastClientY;
|
|
9376
|
+
let nextOrder = null;
|
|
9377
|
+
const slot = session.activeSlot ?? (session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(x, y, session.hrefKey) : session.kind === "column" ? hitTestColumnDropSlot(x, y) : null);
|
|
9378
|
+
if (session.kind === "link" && session.hrefKey && slot) {
|
|
9379
|
+
nextOrder = planFooterLinkMove(session.hrefKey, slot.columnIndex, slot.insertIndex);
|
|
9380
|
+
} else if (session.kind === "column" && slot) {
|
|
9381
|
+
nextOrder = planFooterColumnMove(session.sourceColumnIndex, slot.insertIndex);
|
|
9382
|
+
}
|
|
9383
|
+
const wasSelected = session.wasSelected;
|
|
9384
|
+
const draggedEl = session.draggedEl;
|
|
9385
|
+
const hrefKey = session.hrefKey;
|
|
9386
|
+
let movedColumnIndex = null;
|
|
9387
|
+
if (session.kind === "column" && slot && nextOrder) {
|
|
9388
|
+
let adjusted = slot.insertIndex;
|
|
9389
|
+
if (session.sourceColumnIndex < slot.insertIndex) adjusted -= 1;
|
|
9390
|
+
movedColumnIndex = Math.max(0, Math.min(adjusted, nextOrder.length - 1));
|
|
9391
|
+
}
|
|
9392
|
+
const applySelectionAfterDrop = () => {
|
|
9393
|
+
if (!wasSelected) {
|
|
9394
|
+
deselectRef.current();
|
|
9395
|
+
return;
|
|
9396
|
+
}
|
|
9397
|
+
if (hrefKey) {
|
|
9398
|
+
selectedHrefKeyRef.current = hrefKey;
|
|
9399
|
+
selectedFooterColAttrRef.current = null;
|
|
9400
|
+
const link = resolveHrefKeyElement(hrefKey);
|
|
9401
|
+
if (link && isNavigationItem(link)) {
|
|
9402
|
+
selectRef.current(link);
|
|
9403
|
+
return;
|
|
9404
|
+
}
|
|
9405
|
+
}
|
|
9406
|
+
if (movedColumnIndex !== null && nextOrder) {
|
|
9407
|
+
const colKeys = nextOrder[movedColumnIndex] ?? [];
|
|
9408
|
+
let column = null;
|
|
9409
|
+
for (const key of colKeys) {
|
|
9410
|
+
const link = document.querySelector(
|
|
9411
|
+
`footer [data-ohw-href-key="${CSS.escape(key)}"]`
|
|
9412
|
+
);
|
|
9413
|
+
if (link) {
|
|
9414
|
+
column = findFooterColumnForLink(link);
|
|
9415
|
+
if (column) break;
|
|
9416
|
+
}
|
|
9417
|
+
}
|
|
9418
|
+
if (!column) column = listFooterColumns()[movedColumnIndex] ?? null;
|
|
9419
|
+
if (column && isNavigationContainer(column)) {
|
|
9420
|
+
selectFrameRef.current(column);
|
|
9421
|
+
return;
|
|
9422
|
+
}
|
|
9423
|
+
}
|
|
9424
|
+
if (document.body.contains(draggedEl)) {
|
|
9425
|
+
if (isNavigationItem(draggedEl)) {
|
|
9426
|
+
selectRef.current(draggedEl);
|
|
9427
|
+
return;
|
|
9428
|
+
}
|
|
9429
|
+
if (isNavigationContainer(draggedEl)) {
|
|
9430
|
+
selectFrameRef.current(draggedEl);
|
|
9431
|
+
return;
|
|
9432
|
+
}
|
|
9433
|
+
}
|
|
9434
|
+
deselectRef.current();
|
|
9435
|
+
};
|
|
9436
|
+
if (nextOrder) {
|
|
9437
|
+
const orderJson = JSON.stringify(nextOrder);
|
|
9438
|
+
editContentRef.current = {
|
|
9439
|
+
...editContentRef.current,
|
|
9440
|
+
[FOOTER_ORDER_KEY]: orderJson
|
|
9441
|
+
};
|
|
9442
|
+
applyFooterOrder(nextOrder);
|
|
9443
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
9444
|
+
postToParentRef.current({
|
|
9445
|
+
type: "ow:change",
|
|
9446
|
+
nodes: [{ key: FOOTER_ORDER_KEY, text: orderJson }]
|
|
9447
|
+
});
|
|
9448
|
+
applySelectionAfterDrop();
|
|
9449
|
+
clearFooterDragVisuals();
|
|
9450
|
+
requestAnimationFrame(() => {
|
|
9451
|
+
if (editContentRef.current[FOOTER_ORDER_KEY] === orderJson) {
|
|
9452
|
+
applyFooterOrder(nextOrder);
|
|
9453
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach(disableNativeHrefDrag);
|
|
9454
|
+
}
|
|
9455
|
+
applySelectionAfterDrop();
|
|
9456
|
+
requestAnimationFrame(() => {
|
|
9457
|
+
if (editContentRef.current[FOOTER_ORDER_KEY] === orderJson) {
|
|
9458
|
+
applyFooterOrder(nextOrder);
|
|
9459
|
+
}
|
|
9460
|
+
resyncSelectedNavigationItem();
|
|
9461
|
+
});
|
|
9462
|
+
});
|
|
9463
|
+
return;
|
|
9464
|
+
}
|
|
9465
|
+
applySelectionAfterDrop();
|
|
9466
|
+
clearFooterDragVisuals();
|
|
9467
|
+
},
|
|
9468
|
+
[clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
|
|
9469
|
+
);
|
|
9470
|
+
commitFooterDragRef.current = commitFooterDrag;
|
|
9471
|
+
const startFooterLinkDrag = (0, import_react9.useCallback)(
|
|
9472
|
+
(anchor, clientX, clientY, wasSelected) => {
|
|
9473
|
+
const hrefKey = anchor.getAttribute("data-ohw-href-key");
|
|
9474
|
+
if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
|
|
9475
|
+
const column = findFooterColumnForLink(anchor);
|
|
9476
|
+
const columns = listFooterColumns();
|
|
9477
|
+
beginFooterDrag({
|
|
9478
|
+
kind: "link",
|
|
9479
|
+
hrefKey,
|
|
9480
|
+
columnEl: column,
|
|
9481
|
+
sourceColumnIndex: column ? columns.indexOf(column) : 0,
|
|
9482
|
+
wasSelected,
|
|
9483
|
+
draggedEl: anchor,
|
|
9484
|
+
lastClientX: clientX,
|
|
9485
|
+
lastClientY: clientY,
|
|
9486
|
+
activeSlot: null
|
|
9487
|
+
});
|
|
9488
|
+
return true;
|
|
9489
|
+
},
|
|
9490
|
+
[beginFooterDrag]
|
|
9491
|
+
);
|
|
9492
|
+
const startFooterColumnDrag = (0, import_react9.useCallback)(
|
|
9493
|
+
(columnEl, clientX, clientY, wasSelected) => {
|
|
9494
|
+
const columns = listFooterColumns();
|
|
9495
|
+
const idx = columns.indexOf(columnEl);
|
|
9496
|
+
if (idx < 0) return false;
|
|
9497
|
+
beginFooterDrag({
|
|
9498
|
+
kind: "column",
|
|
9499
|
+
hrefKey: null,
|
|
9500
|
+
columnEl,
|
|
9501
|
+
sourceColumnIndex: idx,
|
|
9502
|
+
wasSelected,
|
|
9503
|
+
draggedEl: columnEl,
|
|
9504
|
+
lastClientX: clientX,
|
|
9505
|
+
lastClientY: clientY,
|
|
9506
|
+
activeSlot: null
|
|
9507
|
+
});
|
|
9508
|
+
return true;
|
|
9509
|
+
},
|
|
9510
|
+
[beginFooterDrag]
|
|
9511
|
+
);
|
|
9512
|
+
const handleItemDragStart = (0, import_react9.useCallback)(
|
|
9513
|
+
(e) => {
|
|
9514
|
+
const selected = selectedElRef.current;
|
|
9515
|
+
if (!selected) {
|
|
9516
|
+
setIsItemDragging(true);
|
|
9517
|
+
return;
|
|
9518
|
+
}
|
|
9519
|
+
const clientX = e?.clientX ?? selected.getBoundingClientRect().left + 8;
|
|
9520
|
+
const clientY = e?.clientY ?? selected.getBoundingClientRect().top + 8;
|
|
9521
|
+
if (startFooterLinkDrag(selected, clientX, clientY, true)) return;
|
|
9522
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
9523
|
+
if (startFooterColumnDrag(selected, clientX, clientY, true)) return;
|
|
9524
|
+
}
|
|
9525
|
+
if (startNavLinkDrag(selected, clientX, clientY, true)) return;
|
|
9526
|
+
siblingHintElRef.current = null;
|
|
9527
|
+
setSiblingHintRect(null);
|
|
9528
|
+
setIsItemDragging(true);
|
|
9529
|
+
},
|
|
9530
|
+
[startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag]
|
|
9531
|
+
);
|
|
9532
|
+
const handleItemDragEnd = (0, import_react9.useCallback)(
|
|
9533
|
+
(e) => {
|
|
9534
|
+
if (footerDragRef.current) {
|
|
9535
|
+
const x = e?.clientX;
|
|
9536
|
+
const y = e?.clientY;
|
|
9537
|
+
if (typeof x === "number" && typeof y === "number" && (x !== 0 || y !== 0)) {
|
|
9538
|
+
commitFooterDrag(x, y);
|
|
9539
|
+
} else {
|
|
9540
|
+
commitFooterDrag();
|
|
9541
|
+
}
|
|
9542
|
+
return;
|
|
9543
|
+
}
|
|
9544
|
+
if (navDragRef.current) {
|
|
9545
|
+
const x = e?.clientX;
|
|
9546
|
+
const y = e?.clientY;
|
|
9547
|
+
if (typeof x === "number" && typeof y === "number" && (x !== 0 || y !== 0)) {
|
|
9548
|
+
commitNavDrag(x, y);
|
|
9549
|
+
} else {
|
|
9550
|
+
commitNavDrag();
|
|
9551
|
+
}
|
|
9552
|
+
return;
|
|
9553
|
+
}
|
|
9554
|
+
setIsItemDragging(false);
|
|
9555
|
+
},
|
|
9556
|
+
[commitFooterDrag, commitNavDrag, navDragRef]
|
|
9557
|
+
);
|
|
9558
|
+
const handleItemChromePointerDown = (0, import_react9.useCallback)((e) => {
|
|
9559
|
+
if (e.button !== 0) return;
|
|
9560
|
+
const selected = selectedElRef.current;
|
|
9561
|
+
if (!selected) return;
|
|
9562
|
+
armFooterPressDrag();
|
|
9563
|
+
const hrefKey = selected.getAttribute("data-ohw-href-key");
|
|
9564
|
+
if (hrefKey && isFooterHrefKey(hrefKey)) {
|
|
9565
|
+
footerPointerDragRef.current = {
|
|
9566
|
+
el: selected,
|
|
9567
|
+
kind: "link",
|
|
9568
|
+
startX: e.clientX,
|
|
9569
|
+
startY: e.clientY,
|
|
9570
|
+
pointerId: e.pointerId,
|
|
9571
|
+
wasSelected: true,
|
|
9572
|
+
started: false
|
|
9573
|
+
};
|
|
9574
|
+
return;
|
|
9575
|
+
}
|
|
9576
|
+
if (selected.hasAttribute("data-ohw-footer-col") || isInferredFooterGroup(selected) && selected.closest("footer")) {
|
|
9577
|
+
footerPointerDragRef.current = {
|
|
9578
|
+
el: selected,
|
|
9579
|
+
kind: "column",
|
|
9580
|
+
startX: e.clientX,
|
|
9581
|
+
startY: e.clientY,
|
|
9582
|
+
pointerId: e.pointerId,
|
|
9583
|
+
wasSelected: true,
|
|
9584
|
+
started: false
|
|
9585
|
+
};
|
|
9586
|
+
return;
|
|
9587
|
+
}
|
|
9588
|
+
if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
|
|
9589
|
+
}, [armNavPressFromChrome]);
|
|
9590
|
+
const handleItemChromeClick = (0, import_react9.useCallback)((clientX, clientY) => {
|
|
9591
|
+
if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
|
|
9592
|
+
suppressNextClickRef.current = false;
|
|
9593
|
+
return;
|
|
9594
|
+
}
|
|
9595
|
+
const selected = selectedElRef.current;
|
|
9596
|
+
if (!selected || !isNavigationItem(selected)) return;
|
|
9597
|
+
const editable = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
9598
|
+
if (!editable) return;
|
|
9599
|
+
activateRef.current(editable, { caretX: clientX, caretY: clientY });
|
|
7854
9600
|
}, []);
|
|
7855
9601
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
7856
9602
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
7857
|
-
const select = (0,
|
|
9603
|
+
const select = (0, import_react9.useCallback)((anchor) => {
|
|
7858
9604
|
if (!isNavigationItem(anchor)) return;
|
|
7859
9605
|
if (activeElRef.current) deactivate();
|
|
7860
9606
|
selectedElRef.current = anchor;
|
|
9607
|
+
selectedHrefKeyRef.current = anchor.getAttribute("data-ohw-href-key");
|
|
9608
|
+
selectedFooterColAttrRef.current = null;
|
|
9609
|
+
markSelected(anchor);
|
|
9610
|
+
setSelectedIsCta(isNavbarButton2(anchor));
|
|
7861
9611
|
clearHrefKeyHover(anchor);
|
|
7862
9612
|
hoveredNavContainerRef.current = null;
|
|
7863
9613
|
setHoveredNavContainerRect(null);
|
|
@@ -7865,19 +9615,26 @@ function OhhwellsBridge() {
|
|
|
7865
9615
|
hoveredItemElRef.current = null;
|
|
7866
9616
|
siblingHintElRef.current = null;
|
|
7867
9617
|
setSiblingHintRect(null);
|
|
9618
|
+
setSiblingHintRects(collectNavigationItemSiblingHintRects(anchor));
|
|
7868
9619
|
setIsItemDragging(false);
|
|
7869
9620
|
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
7870
9621
|
setReorderHrefKey(key);
|
|
7871
9622
|
setReorderDragDisabled(disabled);
|
|
9623
|
+
setIsFooterFrameSelection(false);
|
|
7872
9624
|
setToolbarVariant("link-action");
|
|
7873
9625
|
setToolbarRect(anchor.getBoundingClientRect());
|
|
7874
9626
|
setToolbarShowEditLink(false);
|
|
7875
9627
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7876
|
-
}, [deactivate]);
|
|
7877
|
-
const selectFrame = (0,
|
|
9628
|
+
}, [deactivate, markSelected]);
|
|
9629
|
+
const selectFrame = (0, import_react9.useCallback)((el) => {
|
|
7878
9630
|
if (!isNavigationContainer(el)) return;
|
|
7879
9631
|
if (activeElRef.current) deactivate();
|
|
9632
|
+
const isFooterColumn = el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el));
|
|
7880
9633
|
selectedElRef.current = el;
|
|
9634
|
+
selectedHrefKeyRef.current = null;
|
|
9635
|
+
selectedFooterColAttrRef.current = isFooterColumn ? el.getAttribute("data-ohw-footer-col") ?? String(listFooterColumns().indexOf(el)) : null;
|
|
9636
|
+
markSelected(el);
|
|
9637
|
+
setSelectedIsCta(false);
|
|
7881
9638
|
clearHrefKeyHover(el);
|
|
7882
9639
|
hoveredNavContainerRef.current = null;
|
|
7883
9640
|
setHoveredNavContainerRect(null);
|
|
@@ -7885,17 +9642,25 @@ function OhhwellsBridge() {
|
|
|
7885
9642
|
hoveredItemElRef.current = null;
|
|
7886
9643
|
siblingHintElRef.current = null;
|
|
7887
9644
|
setSiblingHintRect(null);
|
|
9645
|
+
setSiblingHintRects(
|
|
9646
|
+
isFooterColumn ? listFooterColumns().filter((column) => column !== el).map((column) => column.getBoundingClientRect()) : []
|
|
9647
|
+
);
|
|
7888
9648
|
setIsItemDragging(false);
|
|
7889
9649
|
setReorderHrefKey(null);
|
|
7890
9650
|
setReorderDragDisabled(false);
|
|
9651
|
+
setIsFooterFrameSelection(isFooterColumn);
|
|
7891
9652
|
setToolbarVariant("select-frame");
|
|
7892
9653
|
setToolbarRect(el.getBoundingClientRect());
|
|
7893
9654
|
setToolbarShowEditLink(false);
|
|
7894
9655
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7895
|
-
}, [deactivate]);
|
|
7896
|
-
const activate = (0,
|
|
9656
|
+
}, [deactivate, markSelected]);
|
|
9657
|
+
const activate = (0, import_react9.useCallback)((el, options) => {
|
|
7897
9658
|
if (activeElRef.current === el) return;
|
|
9659
|
+
clearSelectedAttr();
|
|
7898
9660
|
selectedElRef.current = null;
|
|
9661
|
+
selectedHrefKeyRef.current = null;
|
|
9662
|
+
selectedFooterColAttrRef.current = null;
|
|
9663
|
+
setSelectedIsCta(false);
|
|
7899
9664
|
deactivate();
|
|
7900
9665
|
if (hoveredImageRef.current) {
|
|
7901
9666
|
hoveredImageRef.current = null;
|
|
@@ -7906,13 +9671,27 @@ function OhhwellsBridge() {
|
|
|
7906
9671
|
setSiblingHintRect(null);
|
|
7907
9672
|
setIsItemDragging(false);
|
|
7908
9673
|
el.setAttribute("contenteditable", "true");
|
|
9674
|
+
el.setAttribute("data-ohw-editing", "");
|
|
7909
9675
|
el.removeAttribute("data-ohw-hovered");
|
|
7910
9676
|
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
7911
9677
|
activeElRef.current = el;
|
|
7912
9678
|
originalContentRef.current = el.innerHTML;
|
|
7913
|
-
el.focus();
|
|
9679
|
+
el.focus({ preventScroll: true });
|
|
7914
9680
|
if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
7915
|
-
|
|
9681
|
+
const { caretX, caretY } = options;
|
|
9682
|
+
placeCaretAtPoint(el, caretX, caretY);
|
|
9683
|
+
requestAnimationFrame(() => {
|
|
9684
|
+
if (activeElRef.current === el) placeCaretAtPoint(el, caretX, caretY);
|
|
9685
|
+
});
|
|
9686
|
+
} else {
|
|
9687
|
+
const selection = window.getSelection();
|
|
9688
|
+
if (selection && selection.rangeCount === 0) {
|
|
9689
|
+
const range = document.createRange();
|
|
9690
|
+
range.selectNodeContents(el);
|
|
9691
|
+
range.collapse(false);
|
|
9692
|
+
selection.removeAllRanges();
|
|
9693
|
+
selection.addRange(range);
|
|
9694
|
+
}
|
|
7916
9695
|
}
|
|
7917
9696
|
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
7918
9697
|
const navAnchor = getNavigationItemAnchor(el);
|
|
@@ -7927,13 +9706,13 @@ function OhhwellsBridge() {
|
|
|
7927
9706
|
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
7928
9707
|
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
7929
9708
|
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
7930
|
-
}, [deactivate, postToParent2]);
|
|
9709
|
+
}, [clearSelectedAttr, deactivate, postToParent2]);
|
|
7931
9710
|
activateRef.current = activate;
|
|
7932
9711
|
deactivateRef.current = deactivate;
|
|
7933
9712
|
selectRef.current = select;
|
|
7934
9713
|
selectFrameRef.current = selectFrame;
|
|
7935
9714
|
deselectRef.current = deselect;
|
|
7936
|
-
(0,
|
|
9715
|
+
(0, import_react9.useLayoutEffect)(() => {
|
|
7937
9716
|
if (!subdomain || isEditMode) {
|
|
7938
9717
|
setFetchState("done");
|
|
7939
9718
|
return;
|
|
@@ -7974,6 +9753,7 @@ function OhhwellsBridge() {
|
|
|
7974
9753
|
applyLinkByKey(key, val);
|
|
7975
9754
|
}
|
|
7976
9755
|
reconcileNavbarItemsFromContent(content);
|
|
9756
|
+
reconcileFooterOrderFromContent(content);
|
|
7977
9757
|
enforceLinkHrefs();
|
|
7978
9758
|
initSectionsFromContent(content, true);
|
|
7979
9759
|
sectionsLoadedRef.current = true;
|
|
@@ -8002,7 +9782,7 @@ function OhhwellsBridge() {
|
|
|
8002
9782
|
cancelled = true;
|
|
8003
9783
|
};
|
|
8004
9784
|
}, [subdomain, isEditMode]);
|
|
8005
|
-
(0,
|
|
9785
|
+
(0, import_react9.useEffect)(() => {
|
|
8006
9786
|
if (!subdomain || isEditMode) return;
|
|
8007
9787
|
let debounceTimer = null;
|
|
8008
9788
|
let observer = null;
|
|
@@ -8034,6 +9814,7 @@ function OhhwellsBridge() {
|
|
|
8034
9814
|
applyLinkByKey(key, val);
|
|
8035
9815
|
}
|
|
8036
9816
|
reconcileNavbarItemsFromContent(content);
|
|
9817
|
+
reconcileFooterOrderFromContent(content);
|
|
8037
9818
|
} finally {
|
|
8038
9819
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
8039
9820
|
}
|
|
@@ -8051,16 +9832,16 @@ function OhhwellsBridge() {
|
|
|
8051
9832
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
8052
9833
|
};
|
|
8053
9834
|
}, [subdomain, isEditMode, pathname]);
|
|
8054
|
-
(0,
|
|
9835
|
+
(0, import_react9.useLayoutEffect)(() => {
|
|
8055
9836
|
const el = document.getElementById("ohw-loader");
|
|
8056
9837
|
if (!el) return;
|
|
8057
9838
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
8058
9839
|
el.style.display = visible ? "flex" : "none";
|
|
8059
9840
|
}, [subdomain, fetchState]);
|
|
8060
|
-
(0,
|
|
9841
|
+
(0, import_react9.useEffect)(() => {
|
|
8061
9842
|
postToParent2({ type: "ow:navigation", path: pathname });
|
|
8062
9843
|
}, [pathname, postToParent2]);
|
|
8063
|
-
(0,
|
|
9844
|
+
(0, import_react9.useEffect)(() => {
|
|
8064
9845
|
if (!isEditMode) return;
|
|
8065
9846
|
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
8066
9847
|
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
@@ -8068,23 +9849,72 @@ function OhhwellsBridge() {
|
|
|
8068
9849
|
deselectRef.current();
|
|
8069
9850
|
deactivateRef.current();
|
|
8070
9851
|
}, [pathname, isEditMode]);
|
|
8071
|
-
(0,
|
|
9852
|
+
(0, import_react9.useEffect)(() => {
|
|
8072
9853
|
const contentForNav = () => {
|
|
8073
9854
|
if (isEditMode) return editContentRef.current;
|
|
8074
9855
|
if (!subdomain) return {};
|
|
8075
9856
|
return contentCache.get(subdomain) ?? {};
|
|
8076
9857
|
};
|
|
8077
|
-
const
|
|
9858
|
+
const observeRoots = () => [document.querySelector("nav"), document.querySelector("footer")].filter(
|
|
9859
|
+
(el) => Boolean(el)
|
|
9860
|
+
);
|
|
9861
|
+
const roots = observeRoots();
|
|
9862
|
+
if (roots.length === 0) {
|
|
9863
|
+
reconcileNavbarItemsFromContent(contentForNav());
|
|
9864
|
+
reconcileFooterOrderFromContent(contentForNav());
|
|
9865
|
+
if (isEditMode) syncNavigationDragCursorAttrs();
|
|
9866
|
+
return;
|
|
9867
|
+
}
|
|
9868
|
+
let rafId = null;
|
|
9869
|
+
let applying = false;
|
|
9870
|
+
let observer = null;
|
|
9871
|
+
const attach = () => {
|
|
9872
|
+
for (const root of observeRoots()) {
|
|
9873
|
+
observer?.observe(root, { childList: true, subtree: true });
|
|
9874
|
+
}
|
|
9875
|
+
};
|
|
9876
|
+
const run = () => {
|
|
9877
|
+
if (footerDragRef.current || navDragRef.current || applying) return;
|
|
9878
|
+
applying = true;
|
|
9879
|
+
observer?.disconnect();
|
|
9880
|
+
try {
|
|
9881
|
+
const content = contentForNav();
|
|
9882
|
+
reconcileNavbarItemsFromContent(content);
|
|
9883
|
+
reconcileFooterOrderFromContent(content);
|
|
9884
|
+
document.querySelectorAll("footer [data-ohw-href-key]").forEach((el) => {
|
|
9885
|
+
if (isFooterHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
9886
|
+
disableNativeHrefDrag(el);
|
|
9887
|
+
}
|
|
9888
|
+
});
|
|
9889
|
+
document.querySelectorAll(
|
|
9890
|
+
"nav [data-ohw-href-key], [data-ohw-nav-container] [data-ohw-href-key], [data-ohw-nav-drawer] [data-ohw-href-key]"
|
|
9891
|
+
).forEach((el) => {
|
|
9892
|
+
if (isNavbarHrefKey(el.getAttribute("data-ohw-href-key"))) {
|
|
9893
|
+
disableNativeHrefDrag(el);
|
|
9894
|
+
}
|
|
9895
|
+
});
|
|
9896
|
+
resyncSelectedNavigationItem();
|
|
9897
|
+
if (isEditMode) syncNavigationDragCursorAttrs();
|
|
9898
|
+
} finally {
|
|
9899
|
+
applying = false;
|
|
9900
|
+
attach();
|
|
9901
|
+
}
|
|
9902
|
+
};
|
|
9903
|
+
const schedule = () => {
|
|
9904
|
+
if (applying || rafId != null) return;
|
|
9905
|
+
rafId = requestAnimationFrame(() => {
|
|
9906
|
+
rafId = null;
|
|
9907
|
+
run();
|
|
9908
|
+
});
|
|
9909
|
+
};
|
|
9910
|
+
observer = new MutationObserver(schedule);
|
|
8078
9911
|
run();
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
return () => observer.disconnect();
|
|
8086
|
-
}, [isEditMode, pathname, subdomain, fetchState]);
|
|
8087
|
-
(0, import_react8.useEffect)(() => {
|
|
9912
|
+
return () => {
|
|
9913
|
+
if (rafId != null) cancelAnimationFrame(rafId);
|
|
9914
|
+
observer?.disconnect();
|
|
9915
|
+
};
|
|
9916
|
+
}, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
|
|
9917
|
+
(0, import_react9.useEffect)(() => {
|
|
8088
9918
|
if (!isEditMode) return;
|
|
8089
9919
|
const measure = () => {
|
|
8090
9920
|
const h = document.body.scrollHeight;
|
|
@@ -8108,7 +9938,7 @@ function OhhwellsBridge() {
|
|
|
8108
9938
|
window.removeEventListener("resize", handleResize);
|
|
8109
9939
|
};
|
|
8110
9940
|
}, [pathname, isEditMode, postToParent2]);
|
|
8111
|
-
(0,
|
|
9941
|
+
(0, import_react9.useEffect)(() => {
|
|
8112
9942
|
if (!subdomainFromQuery || isEditMode) return;
|
|
8113
9943
|
const handleClick = (e) => {
|
|
8114
9944
|
const anchor = e.target.closest("a");
|
|
@@ -8124,19 +9954,24 @@ function OhhwellsBridge() {
|
|
|
8124
9954
|
document.addEventListener("click", handleClick, true);
|
|
8125
9955
|
return () => document.removeEventListener("click", handleClick, true);
|
|
8126
9956
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
8127
|
-
(0,
|
|
9957
|
+
(0, import_react9.useEffect)(() => {
|
|
8128
9958
|
if (!isEditMode) {
|
|
8129
9959
|
editStylesRef.current?.base.remove();
|
|
8130
9960
|
editStylesRef.current?.forceHover.remove();
|
|
8131
9961
|
editStylesRef.current?.stateViews.remove();
|
|
8132
9962
|
editStylesRef.current = null;
|
|
9963
|
+
document.querySelectorAll("[data-ohw-can-drag]").forEach((el) => {
|
|
9964
|
+
el.removeAttribute("data-ohw-can-drag");
|
|
9965
|
+
});
|
|
8133
9966
|
return;
|
|
8134
9967
|
}
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
base.
|
|
8139
|
-
|
|
9968
|
+
const existing = editStylesRef.current;
|
|
9969
|
+
let initialVh = window.innerHeight;
|
|
9970
|
+
if (existing?.base.textContent) {
|
|
9971
|
+
const match = existing.base.textContent.match(/\.min-h-screen[^{]*\{[^}]*min-height:\s*(\d+)px/);
|
|
9972
|
+
if (match) initialVh = parseInt(match[1], 10);
|
|
9973
|
+
}
|
|
9974
|
+
const baseCss = `
|
|
8140
9975
|
html { height: auto !important; }
|
|
8141
9976
|
body { height: auto !important; min-height: 0 !important; overflow: hidden !important; }
|
|
8142
9977
|
.min-h-screen, .min-h-svh, .min-h-dvh { min-height: ${initialVh}px !important; }
|
|
@@ -8147,7 +9982,25 @@ function OhhwellsBridge() {
|
|
|
8147
9982
|
[data-ohw-editable] {
|
|
8148
9983
|
display: block;
|
|
8149
9984
|
}
|
|
8150
|
-
|
|
9985
|
+
/* Body text (no item-action toolbar) \u2014 first click enters text edit \u2192 I-beam.
|
|
9986
|
+
Exclude select-first nav/footer labels so grab/default on [data-ohw-href-key] can win. */
|
|
9987
|
+
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]):not([data-ohw-editable="link"]):not(:is([data-ohw-href-key] *)) {
|
|
9988
|
+
cursor: text !important;
|
|
9989
|
+
}
|
|
9990
|
+
/* Select-first items: default arrow; grab only when drag-start is allowed (data-ohw-can-drag). */
|
|
9991
|
+
[data-ohw-href-key]:not([data-ohw-selected]),
|
|
9992
|
+
[data-ohw-href-key]:not([data-ohw-selected]) * {
|
|
9993
|
+
cursor: default !important;
|
|
9994
|
+
}
|
|
9995
|
+
[data-ohw-href-key][data-ohw-can-drag]:not([data-ohw-selected]),
|
|
9996
|
+
[data-ohw-href-key][data-ohw-can-drag]:not([data-ohw-selected]) * {
|
|
9997
|
+
cursor: grab !important;
|
|
9998
|
+
}
|
|
9999
|
+
/* Selected (action-toolbar) \u2014 next click enters text edit at caret. */
|
|
10000
|
+
[data-ohw-href-key][data-ohw-selected],
|
|
10001
|
+
[data-ohw-href-key][data-ohw-selected] * {
|
|
10002
|
+
cursor: text !important;
|
|
10003
|
+
}
|
|
8151
10004
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
8152
10005
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
8153
10006
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
@@ -8163,9 +10016,32 @@ function OhhwellsBridge() {
|
|
|
8163
10016
|
outline: none !important;
|
|
8164
10017
|
outline-offset: 0 !important;
|
|
8165
10018
|
}
|
|
8166
|
-
|
|
10019
|
+
/* Editor chrome owns selection \u2014 suppress native focus rings on nav/footer items. */
|
|
10020
|
+
nav [data-ohw-href-key]:focus,
|
|
10021
|
+
nav [data-ohw-href-key]:focus-visible,
|
|
10022
|
+
nav [data-ohw-href-key]:focus-within,
|
|
10023
|
+
footer [data-ohw-href-key]:focus,
|
|
10024
|
+
footer [data-ohw-href-key]:focus-visible,
|
|
10025
|
+
footer [data-ohw-href-key]:focus-within,
|
|
10026
|
+
nav [data-ohw-href-key] [data-ohw-editable]:focus,
|
|
10027
|
+
nav [data-ohw-href-key] [data-ohw-editable]:focus-visible,
|
|
10028
|
+
footer [data-ohw-href-key] [data-ohw-editable]:focus,
|
|
10029
|
+
footer [data-ohw-href-key] [data-ohw-editable]:focus-visible {
|
|
10030
|
+
outline: none !important;
|
|
10031
|
+
outline-offset: 0 !important;
|
|
10032
|
+
box-shadow: none !important;
|
|
10033
|
+
}
|
|
10034
|
+
/* Text edit wins over grab/default (must beat [data-ohw-can-drag] *). */
|
|
10035
|
+
[data-ohw-editing],
|
|
10036
|
+
[data-ohw-editing] *,
|
|
10037
|
+
[data-ohw-editable][contenteditable],
|
|
10038
|
+
[data-ohw-editable][contenteditable] *,
|
|
10039
|
+
nav [data-ohw-href-key] [data-ohw-editable][contenteditable],
|
|
10040
|
+
nav [data-ohw-href-key] [data-ohw-editable][contenteditable] *,
|
|
10041
|
+
footer [data-ohw-href-key] [data-ohw-editable][contenteditable],
|
|
10042
|
+
footer [data-ohw-href-key] [data-ohw-editable][contenteditable] * {
|
|
8167
10043
|
outline: none !important;
|
|
8168
|
-
caret-color: ${PRIMARY2};
|
|
10044
|
+
caret-color: ${PRIMARY2} !important;
|
|
8169
10045
|
cursor: text !important;
|
|
8170
10046
|
}
|
|
8171
10047
|
[data-ohw-editable][contenteditable]::selection,
|
|
@@ -8174,6 +10050,9 @@ function OhhwellsBridge() {
|
|
|
8174
10050
|
[data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
|
|
8175
10051
|
[data-ohw-editable-state][data-ohw-active-state][data-ohw-editable] { pointer-events: auto !important; }
|
|
8176
10052
|
`;
|
|
10053
|
+
if (!existing) {
|
|
10054
|
+
const base = document.createElement("style");
|
|
10055
|
+
base.setAttribute("data-ohw-edit-style", "");
|
|
8177
10056
|
const forceHover = document.createElement("style");
|
|
8178
10057
|
forceHover.setAttribute("data-ohw-active-state-style", "");
|
|
8179
10058
|
const stateViews = document.createElement("style");
|
|
@@ -8189,14 +10068,43 @@ function OhhwellsBridge() {
|
|
|
8189
10068
|
document.head.appendChild(stateViews);
|
|
8190
10069
|
editStylesRef.current = { base, forceHover, stateViews };
|
|
8191
10070
|
}
|
|
10071
|
+
editStylesRef.current.base.textContent = baseCss;
|
|
10072
|
+
syncNavigationDragCursorAttrs();
|
|
8192
10073
|
refreshStateRules();
|
|
8193
10074
|
const handleClick = (e) => {
|
|
10075
|
+
if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
|
|
10076
|
+
suppressNextClickRef.current = false;
|
|
10077
|
+
e.preventDefault();
|
|
10078
|
+
e.stopPropagation();
|
|
10079
|
+
return;
|
|
10080
|
+
}
|
|
8194
10081
|
const target = e.target;
|
|
8195
10082
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
8196
10083
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
8197
10084
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
8198
10085
|
if (isInsideLinkEditor(target)) return;
|
|
8199
10086
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
10087
|
+
if (target.closest("[data-ohw-item-drag-surface]")) {
|
|
10088
|
+
e.preventDefault();
|
|
10089
|
+
e.stopPropagation();
|
|
10090
|
+
const selected = selectedElRef.current;
|
|
10091
|
+
if (selected && isNavigationItem(selected)) {
|
|
10092
|
+
const editable2 = selected.querySelector('[data-ohw-editable="text"]') ?? selected.querySelector("[data-ohw-editable]");
|
|
10093
|
+
if (editable2) {
|
|
10094
|
+
activateRef.current(editable2, {
|
|
10095
|
+
caretX: e.clientX,
|
|
10096
|
+
caretY: e.clientY
|
|
10097
|
+
});
|
|
10098
|
+
}
|
|
10099
|
+
} else if (selected?.hasAttribute("data-ohw-footer-col")) {
|
|
10100
|
+
const link = listFooterLinksInColumn(selected).find((el) => {
|
|
10101
|
+
const r2 = el.getBoundingClientRect();
|
|
10102
|
+
return e.clientX >= r2.left && e.clientX <= r2.right && e.clientY >= r2.top && e.clientY <= r2.bottom;
|
|
10103
|
+
});
|
|
10104
|
+
if (link) selectRef.current(link);
|
|
10105
|
+
}
|
|
10106
|
+
return;
|
|
10107
|
+
}
|
|
8200
10108
|
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8201
10109
|
if (navFromChrome) {
|
|
8202
10110
|
e.preventDefault();
|
|
@@ -8204,10 +10112,34 @@ function OhhwellsBridge() {
|
|
|
8204
10112
|
selectFrameRef.current(navFromChrome);
|
|
8205
10113
|
return;
|
|
8206
10114
|
}
|
|
10115
|
+
const footerFromChrome = resolveFooterColumnSelectionTarget(target, e.clientX, e.clientY);
|
|
10116
|
+
if (footerFromChrome) {
|
|
10117
|
+
e.preventDefault();
|
|
10118
|
+
e.stopPropagation();
|
|
10119
|
+
selectFrameRef.current(footerFromChrome);
|
|
10120
|
+
return;
|
|
10121
|
+
}
|
|
8207
10122
|
e.preventDefault();
|
|
8208
10123
|
e.stopPropagation();
|
|
8209
10124
|
return;
|
|
8210
10125
|
}
|
|
10126
|
+
if (activeElRef.current) {
|
|
10127
|
+
const active = activeElRef.current;
|
|
10128
|
+
const inActive = active === target || active.contains(target);
|
|
10129
|
+
const navAnchor = getNavigationItemAnchor(active);
|
|
10130
|
+
const inActiveNav = Boolean(
|
|
10131
|
+
navAnchor && (navAnchor === target || navAnchor.contains(target))
|
|
10132
|
+
);
|
|
10133
|
+
if (inActive || inActiveNav) {
|
|
10134
|
+
e.preventDefault();
|
|
10135
|
+
e.stopPropagation();
|
|
10136
|
+
if (e.detail < 2) {
|
|
10137
|
+
placeCaretAtPoint(active, e.clientX, e.clientY);
|
|
10138
|
+
refreshActiveCommandsRef.current();
|
|
10139
|
+
}
|
|
10140
|
+
return;
|
|
10141
|
+
}
|
|
10142
|
+
}
|
|
8211
10143
|
const editable = target.closest("[data-ohw-editable]");
|
|
8212
10144
|
if (editable) {
|
|
8213
10145
|
if (editable.dataset.ohwEditable === "link") {
|
|
@@ -8251,10 +10183,26 @@ function OhhwellsBridge() {
|
|
|
8251
10183
|
if (hrefAnchor) {
|
|
8252
10184
|
e.preventDefault();
|
|
8253
10185
|
e.stopPropagation();
|
|
8254
|
-
if (selectedElRef.current === hrefAnchor)
|
|
10186
|
+
if (selectedElRef.current === hrefAnchor) {
|
|
10187
|
+
const textEditable = hrefAnchor.querySelector('[data-ohw-editable="text"]') ?? hrefAnchor.querySelector("[data-ohw-editable]");
|
|
10188
|
+
if (textEditable) {
|
|
10189
|
+
activateRef.current(textEditable, {
|
|
10190
|
+
caretX: e.clientX,
|
|
10191
|
+
caretY: e.clientY
|
|
10192
|
+
});
|
|
10193
|
+
}
|
|
10194
|
+
return;
|
|
10195
|
+
}
|
|
8255
10196
|
selectRef.current(hrefAnchor);
|
|
8256
10197
|
return;
|
|
8257
10198
|
}
|
|
10199
|
+
const footerColClick = target.closest("[data-ohw-footer-col]");
|
|
10200
|
+
if (footerColClick) {
|
|
10201
|
+
e.preventDefault();
|
|
10202
|
+
e.stopPropagation();
|
|
10203
|
+
selectFrameRef.current(footerColClick);
|
|
10204
|
+
return;
|
|
10205
|
+
}
|
|
8258
10206
|
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8259
10207
|
if (navContainerToSelect) {
|
|
8260
10208
|
e.preventDefault();
|
|
@@ -8262,6 +10210,13 @@ function OhhwellsBridge() {
|
|
|
8262
10210
|
selectFrameRef.current(navContainerToSelect);
|
|
8263
10211
|
return;
|
|
8264
10212
|
}
|
|
10213
|
+
const footerColumnToSelect = resolveFooterColumnSelectionTarget(target, e.clientX, e.clientY);
|
|
10214
|
+
if (footerColumnToSelect) {
|
|
10215
|
+
e.preventDefault();
|
|
10216
|
+
e.stopPropagation();
|
|
10217
|
+
selectFrameRef.current(footerColumnToSelect);
|
|
10218
|
+
return;
|
|
10219
|
+
}
|
|
8265
10220
|
const selectedContainer = selectedElRef.current;
|
|
8266
10221
|
if (selectedContainer && isNavigationContainer(selectedContainer)) {
|
|
8267
10222
|
const navItem = getNavigationItemAnchor(target);
|
|
@@ -8321,6 +10276,13 @@ function OhhwellsBridge() {
|
|
|
8321
10276
|
const handleMouseOver = (e) => {
|
|
8322
10277
|
if (document.documentElement.hasAttribute("data-ohw-section-picking")) return;
|
|
8323
10278
|
const target = e.target;
|
|
10279
|
+
if (linkPopoverOpenRef.current) {
|
|
10280
|
+
hoveredItemElRef.current = null;
|
|
10281
|
+
setHoveredItemRect(null);
|
|
10282
|
+
hoveredNavContainerRef.current = null;
|
|
10283
|
+
setHoveredNavContainerRect(null);
|
|
10284
|
+
return;
|
|
10285
|
+
}
|
|
8324
10286
|
if (toolbarVariantRef.current !== "select-frame") {
|
|
8325
10287
|
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
8326
10288
|
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
@@ -8340,12 +10302,21 @@ function OhhwellsBridge() {
|
|
|
8340
10302
|
hoveredNavContainerRef.current = null;
|
|
8341
10303
|
setHoveredNavContainerRect(null);
|
|
8342
10304
|
const selected2 = selectedElRef.current;
|
|
8343
|
-
if (selected2 === navAnchor
|
|
10305
|
+
if (selected2 === navAnchor) return;
|
|
8344
10306
|
clearHrefKeyHover(navAnchor);
|
|
8345
10307
|
hoveredItemElRef.current = navAnchor;
|
|
8346
10308
|
setHoveredItemRect(navAnchor.getBoundingClientRect());
|
|
8347
10309
|
return;
|
|
8348
10310
|
}
|
|
10311
|
+
const footerCol = target.closest("[data-ohw-footer-col]") ?? target.closest("[data-ohw-footer-column]");
|
|
10312
|
+
if (footerCol) {
|
|
10313
|
+
hoveredNavContainerRef.current = null;
|
|
10314
|
+
setHoveredNavContainerRect(null);
|
|
10315
|
+
if (selectedElRef.current === footerCol) return;
|
|
10316
|
+
hoveredItemElRef.current = footerCol;
|
|
10317
|
+
setHoveredItemRect(footerCol.getBoundingClientRect());
|
|
10318
|
+
return;
|
|
10319
|
+
}
|
|
8349
10320
|
const editable = target.closest("[data-ohw-editable]");
|
|
8350
10321
|
if (!editable) return;
|
|
8351
10322
|
const selected = selectedElRef.current;
|
|
@@ -8363,14 +10334,25 @@ function OhhwellsBridge() {
|
|
|
8363
10334
|
};
|
|
8364
10335
|
const handleMouseOut = (e) => {
|
|
8365
10336
|
const target = e.target;
|
|
8366
|
-
if (target.closest("[data-ohw-nav-container]")) {
|
|
10337
|
+
if (target.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column]")) {
|
|
8367
10338
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
8368
|
-
if (related2?.closest("[data-ohw-nav-container], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
10339
|
+
if (related2?.closest("[data-ohw-nav-container], [data-ohw-footer-col], [data-ohw-footer-column], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
8369
10340
|
return;
|
|
8370
10341
|
}
|
|
8371
10342
|
hoveredNavContainerRef.current = null;
|
|
8372
10343
|
setHoveredNavContainerRect(null);
|
|
8373
10344
|
}
|
|
10345
|
+
const footerCol = target.closest("[data-ohw-footer-col]") ?? target.closest("[data-ohw-footer-column]");
|
|
10346
|
+
if (footerCol && hoveredItemElRef.current === footerCol) {
|
|
10347
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
10348
|
+
if (related2?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
10349
|
+
if (related2?.closest("[data-ohw-footer-col], [data-ohw-footer-column]") === footerCol) {
|
|
10350
|
+
return;
|
|
10351
|
+
}
|
|
10352
|
+
hoveredItemElRef.current = null;
|
|
10353
|
+
setHoveredItemRect(null);
|
|
10354
|
+
return;
|
|
10355
|
+
}
|
|
8374
10356
|
const navAnchor = getNavigationItemAnchor(target);
|
|
8375
10357
|
if (navAnchor) {
|
|
8376
10358
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -8504,43 +10486,75 @@ function OhhwellsBridge() {
|
|
|
8504
10486
|
if (toolbarVariantRef.current === "select-frame") {
|
|
8505
10487
|
hoveredNavContainerRef.current = null;
|
|
8506
10488
|
setHoveredNavContainerRect(null);
|
|
8507
|
-
return;
|
|
8508
10489
|
}
|
|
8509
|
-
const
|
|
8510
|
-
|
|
8511
|
-
|
|
8512
|
-
|
|
8513
|
-
|
|
10490
|
+
const navContainers = Array.from(
|
|
10491
|
+
document.querySelectorAll("[data-ohw-nav-container]")
|
|
10492
|
+
);
|
|
10493
|
+
const footerColumns = listFooterColumns();
|
|
10494
|
+
for (const container of [...navContainers, ...footerColumns]) {
|
|
10495
|
+
const containerRect = container.getBoundingClientRect();
|
|
10496
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
10497
|
+
if (!overContainer) continue;
|
|
10498
|
+
const navItemHit = Array.from(
|
|
10499
|
+
container.querySelectorAll("[data-ohw-href-key]")
|
|
10500
|
+
).find((el) => {
|
|
10501
|
+
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
10502
|
+
const itemRect = el.getBoundingClientRect();
|
|
10503
|
+
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
10504
|
+
});
|
|
10505
|
+
if (navItemHit) {
|
|
10506
|
+
hoveredNavContainerRef.current = null;
|
|
10507
|
+
setHoveredNavContainerRect(null);
|
|
10508
|
+
const selected = selectedElRef.current;
|
|
10509
|
+
if (selected !== navItemHit) {
|
|
10510
|
+
clearHrefKeyHover(navItemHit);
|
|
10511
|
+
hoveredItemElRef.current = navItemHit;
|
|
10512
|
+
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
10513
|
+
} else if (hoveredItemElRef.current === navItemHit) {
|
|
10514
|
+
hoveredItemElRef.current = null;
|
|
10515
|
+
setHoveredItemRect(null);
|
|
10516
|
+
}
|
|
10517
|
+
return;
|
|
10518
|
+
}
|
|
8514
10519
|
}
|
|
8515
|
-
|
|
8516
|
-
|
|
8517
|
-
|
|
10520
|
+
if (toolbarVariantRef.current !== "select-frame") {
|
|
10521
|
+
for (const container of navContainers) {
|
|
10522
|
+
const containerRect = container.getBoundingClientRect();
|
|
10523
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
10524
|
+
if (!overContainer) continue;
|
|
10525
|
+
if (isPointOverNavItem(container, x, y)) continue;
|
|
10526
|
+
hoveredNavContainerRef.current = container;
|
|
10527
|
+
setHoveredNavContainerRect(container.getBoundingClientRect());
|
|
10528
|
+
hoveredItemElRef.current = null;
|
|
10529
|
+
setHoveredItemRect(null);
|
|
10530
|
+
return;
|
|
10531
|
+
}
|
|
8518
10532
|
hoveredNavContainerRef.current = null;
|
|
8519
10533
|
setHoveredNavContainerRect(null);
|
|
8520
|
-
|
|
8521
|
-
}
|
|
8522
|
-
const navItemHit = Array.from(
|
|
8523
|
-
navContainer.querySelectorAll("[data-ohw-href-key]")
|
|
8524
|
-
).find((el) => {
|
|
8525
|
-
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
8526
|
-
const itemRect = el.getBoundingClientRect();
|
|
8527
|
-
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
8528
|
-
});
|
|
8529
|
-
if (navItemHit) {
|
|
10534
|
+
} else {
|
|
8530
10535
|
hoveredNavContainerRef.current = null;
|
|
8531
10536
|
setHoveredNavContainerRect(null);
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
|
|
10537
|
+
}
|
|
10538
|
+
for (const column of footerColumns) {
|
|
10539
|
+
const containerRect = column.getBoundingClientRect();
|
|
10540
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
10541
|
+
if (!overContainer) continue;
|
|
10542
|
+
if (isPointOverNavItem(column, x, y)) continue;
|
|
10543
|
+
if (selectedElRef.current === column) {
|
|
10544
|
+
if (hoveredItemElRef.current === column) {
|
|
10545
|
+
hoveredItemElRef.current = null;
|
|
10546
|
+
setHoveredItemRect(null);
|
|
10547
|
+
}
|
|
10548
|
+
return;
|
|
8537
10549
|
}
|
|
10550
|
+
hoveredItemElRef.current = column;
|
|
10551
|
+
setHoveredItemRect(column.getBoundingClientRect());
|
|
8538
10552
|
return;
|
|
8539
10553
|
}
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
|
|
10554
|
+
if (hoveredItemElRef.current?.hasAttribute("data-ohw-footer-col") || hoveredItemElRef.current?.hasAttribute("data-ohw-footer-column")) {
|
|
10555
|
+
hoveredItemElRef.current = null;
|
|
10556
|
+
setHoveredItemRect(null);
|
|
10557
|
+
}
|
|
8544
10558
|
};
|
|
8545
10559
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
8546
10560
|
if (linkPopoverOpenRef.current) {
|
|
@@ -8561,6 +10575,10 @@ function OhhwellsBridge() {
|
|
|
8561
10575
|
}
|
|
8562
10576
|
hoveredNavContainerRef.current = null;
|
|
8563
10577
|
setHoveredNavContainerRect(null);
|
|
10578
|
+
if (hoveredItemElRef.current?.hasAttribute("data-ohw-footer-col") || hoveredItemElRef.current?.hasAttribute("data-ohw-footer-column")) {
|
|
10579
|
+
hoveredItemElRef.current = null;
|
|
10580
|
+
setHoveredItemRect(null);
|
|
10581
|
+
}
|
|
8564
10582
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
8565
10583
|
if (toggleEl) {
|
|
8566
10584
|
const tr = toggleEl.getBoundingClientRect();
|
|
@@ -8808,6 +10826,15 @@ function OhhwellsBridge() {
|
|
|
8808
10826
|
probeHoverCardsAt(clientX, clientY);
|
|
8809
10827
|
};
|
|
8810
10828
|
const handleDragOver = (e) => {
|
|
10829
|
+
const footerSession = footerDragRef.current;
|
|
10830
|
+
if (footerSession) {
|
|
10831
|
+
e.preventDefault();
|
|
10832
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
|
|
10833
|
+
const slot = footerSession.kind === "link" && footerSession.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, footerSession.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
10834
|
+
refreshFooterDragVisualsRef.current(footerSession, slot, e.clientX, e.clientY);
|
|
10835
|
+
return;
|
|
10836
|
+
}
|
|
10837
|
+
if (onNavDragOver(e)) return;
|
|
8811
10838
|
e.preventDefault();
|
|
8812
10839
|
const el = findImageAtPoint(e.clientX, e.clientY, false);
|
|
8813
10840
|
if (!el) {
|
|
@@ -8970,8 +10997,8 @@ function OhhwellsBridge() {
|
|
|
8970
10997
|
if (sibling !== el) sibling.innerHTML = html;
|
|
8971
10998
|
});
|
|
8972
10999
|
const timers = autoSaveTimers.current;
|
|
8973
|
-
const
|
|
8974
|
-
if (
|
|
11000
|
+
const existing2 = timers.get(key);
|
|
11001
|
+
if (existing2) clearTimeout(existing2);
|
|
8975
11002
|
timers.set(key, setTimeout(() => {
|
|
8976
11003
|
timers.delete(key);
|
|
8977
11004
|
postToParentRef.current({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
@@ -9014,6 +11041,7 @@ function OhhwellsBridge() {
|
|
|
9014
11041
|
}
|
|
9015
11042
|
editContentRef.current = { ...editContentRef.current, ...content };
|
|
9016
11043
|
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
11044
|
+
syncNavigationDragCursorAttrs();
|
|
9017
11045
|
enforceLinkHrefs();
|
|
9018
11046
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
9019
11047
|
};
|
|
@@ -9034,6 +11062,48 @@ function OhhwellsBridge() {
|
|
|
9034
11062
|
if (e.data?.type !== "ui:escape") return;
|
|
9035
11063
|
if (linkPopoverOpenRef.current) {
|
|
9036
11064
|
setLinkPopoverRef.current(null);
|
|
11065
|
+
return;
|
|
11066
|
+
}
|
|
11067
|
+
if (activeElRef.current) {
|
|
11068
|
+
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
11069
|
+
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
11070
|
+
if (navAnchor) {
|
|
11071
|
+
const el = activeElRef.current;
|
|
11072
|
+
if (originalContentRef.current !== null) {
|
|
11073
|
+
el.innerHTML = originalContentRef.current;
|
|
11074
|
+
}
|
|
11075
|
+
el.removeAttribute("contenteditable");
|
|
11076
|
+
el.removeAttribute("data-ohw-editing");
|
|
11077
|
+
activeElRef.current = null;
|
|
11078
|
+
setMaxBadge(null);
|
|
11079
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
11080
|
+
setToolbarShowEditLink(false);
|
|
11081
|
+
postToParentRef.current({ type: "ow:exit-edit" });
|
|
11082
|
+
reselectNavigationItemRef.current(navAnchor);
|
|
11083
|
+
return;
|
|
11084
|
+
}
|
|
11085
|
+
if (originalContentRef.current !== null) {
|
|
11086
|
+
activeElRef.current.innerHTML = originalContentRef.current;
|
|
11087
|
+
const key = activeElRef.current.dataset.ohwKey;
|
|
11088
|
+
if (key) {
|
|
11089
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key, text: originalContentRef.current }] });
|
|
11090
|
+
}
|
|
11091
|
+
}
|
|
11092
|
+
deselectRef.current();
|
|
11093
|
+
deactivateRef.current();
|
|
11094
|
+
return;
|
|
11095
|
+
}
|
|
11096
|
+
if (selectedElRef.current) {
|
|
11097
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
11098
|
+
deselectRef.current();
|
|
11099
|
+
return;
|
|
11100
|
+
}
|
|
11101
|
+
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
11102
|
+
if (parent && isNavigationContainer(parent)) {
|
|
11103
|
+
selectFrameRef.current(parent);
|
|
11104
|
+
} else {
|
|
11105
|
+
deselectRef.current();
|
|
11106
|
+
}
|
|
9037
11107
|
}
|
|
9038
11108
|
};
|
|
9039
11109
|
window.addEventListener("message", handleUiEscape);
|
|
@@ -9058,7 +11128,7 @@ function OhhwellsBridge() {
|
|
|
9058
11128
|
return;
|
|
9059
11129
|
}
|
|
9060
11130
|
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
9061
|
-
if (parent) {
|
|
11131
|
+
if (parent && isNavigationContainer(parent)) {
|
|
9062
11132
|
e.preventDefault();
|
|
9063
11133
|
selectFrameRef.current(parent);
|
|
9064
11134
|
} else {
|
|
@@ -9076,6 +11146,7 @@ function OhhwellsBridge() {
|
|
|
9076
11146
|
el2.innerHTML = originalContentRef.current;
|
|
9077
11147
|
}
|
|
9078
11148
|
el2.removeAttribute("contenteditable");
|
|
11149
|
+
el2.removeAttribute("data-ohw-editing");
|
|
9079
11150
|
activeElRef.current = null;
|
|
9080
11151
|
setMaxBadge(null);
|
|
9081
11152
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
@@ -9127,6 +11198,26 @@ function OhhwellsBridge() {
|
|
|
9127
11198
|
if (siblingHintElRef.current) {
|
|
9128
11199
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
9129
11200
|
}
|
|
11201
|
+
const selected = selectedElRef.current;
|
|
11202
|
+
if (selected && !footerDragRef.current && !navDragRef.current) {
|
|
11203
|
+
if (selected.hasAttribute("data-ohw-footer-col") || Boolean(selected.closest("footer") && isInferredFooterGroup(selected))) {
|
|
11204
|
+
setSiblingHintRects(
|
|
11205
|
+
listFooterColumns().filter((column) => column !== selected).map((column) => column.getBoundingClientRect())
|
|
11206
|
+
);
|
|
11207
|
+
} else if (isNavigationItem(selected)) {
|
|
11208
|
+
setSiblingHintRects(collectNavigationItemSiblingHintRects(selected));
|
|
11209
|
+
}
|
|
11210
|
+
}
|
|
11211
|
+
if (footerDragRef.current) {
|
|
11212
|
+
const session = footerDragRef.current;
|
|
11213
|
+
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(session.lastClientX, session.lastClientY, session.hrefKey) : hitTestColumnDropSlot(session.lastClientX, session.lastClientY);
|
|
11214
|
+
refreshFooterDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
11215
|
+
}
|
|
11216
|
+
if (navDragRef.current) {
|
|
11217
|
+
const session = navDragRef.current;
|
|
11218
|
+
const slot = hitTestNavDropSlot(session.lastClientX, session.lastClientY, session.hrefKey);
|
|
11219
|
+
refreshNavDragVisualsRef.current(session, slot, session.lastClientX, session.lastClientY);
|
|
11220
|
+
}
|
|
9130
11221
|
if (hoveredImageRef.current) {
|
|
9131
11222
|
const el = hoveredImageRef.current;
|
|
9132
11223
|
const r2 = el.getBoundingClientRect();
|
|
@@ -9137,7 +11228,7 @@ function OhhwellsBridge() {
|
|
|
9137
11228
|
};
|
|
9138
11229
|
const handleSave = (e) => {
|
|
9139
11230
|
if (e.data?.type !== "ow:save") return;
|
|
9140
|
-
const nodes = collectEditableNodes();
|
|
11231
|
+
const nodes = collectEditableNodes(editContentRef.current);
|
|
9141
11232
|
const tracker = document.querySelector("[data-ohw-sections-tracker]");
|
|
9142
11233
|
if (tracker?.textContent) nodes.push({ key: "__ohw_sections", type: "sections", text: tracker.textContent });
|
|
9143
11234
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
@@ -9263,15 +11354,15 @@ function OhhwellsBridge() {
|
|
|
9263
11354
|
};
|
|
9264
11355
|
const applyToolbarPos = (rect) => {
|
|
9265
11356
|
const ps = parentScrollRef.current;
|
|
9266
|
-
const
|
|
11357
|
+
const measuredW = toolbarElRef.current?.offsetWidth || 330;
|
|
9267
11358
|
if (toolbarElRef.current) {
|
|
9268
|
-
const { top, left, transform } = calcToolbarPos(rect, ps,
|
|
11359
|
+
const { top, left, transform } = calcToolbarPos(rect, ps, measuredW);
|
|
9269
11360
|
toolbarElRef.current.style.top = `${top}px`;
|
|
9270
11361
|
toolbarElRef.current.style.left = `${left}px`;
|
|
9271
11362
|
toolbarElRef.current.style.transform = transform;
|
|
9272
11363
|
}
|
|
9273
11364
|
if (glowElRef.current) {
|
|
9274
|
-
const GAP =
|
|
11365
|
+
const GAP = SELECTION_CHROME_GAP2;
|
|
9275
11366
|
glowElRef.current.style.top = `${rect.top - GAP}px`;
|
|
9276
11367
|
glowElRef.current.style.left = `${rect.left - GAP}px`;
|
|
9277
11368
|
glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
|
|
@@ -9359,6 +11450,11 @@ function OhhwellsBridge() {
|
|
|
9359
11450
|
return;
|
|
9360
11451
|
}
|
|
9361
11452
|
}
|
|
11453
|
+
const footerColumn = findHoveredNavOrFooterContainer(clientX, clientY);
|
|
11454
|
+
if (footerColumn?.hasAttribute("data-ohw-footer-col") || footerColumn?.hasAttribute("data-ohw-footer-column")) {
|
|
11455
|
+
selectFrameRef.current(footerColumn);
|
|
11456
|
+
return;
|
|
11457
|
+
}
|
|
9362
11458
|
deactivateRef.current();
|
|
9363
11459
|
};
|
|
9364
11460
|
window.addEventListener("message", handleSave);
|
|
@@ -9430,7 +11526,161 @@ function OhhwellsBridge() {
|
|
|
9430
11526
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
9431
11527
|
};
|
|
9432
11528
|
}, [isEditMode, refreshStateRules]);
|
|
9433
|
-
(0,
|
|
11529
|
+
(0, import_react9.useEffect)(() => {
|
|
11530
|
+
if (!isEditMode) return;
|
|
11531
|
+
const THRESHOLD = 10;
|
|
11532
|
+
const resolveWasSelected = (el) => {
|
|
11533
|
+
if (selectedElRef.current === el) return true;
|
|
11534
|
+
const activeAnchor = activeElRef.current ? getNavigationItemAnchor(activeElRef.current) : null;
|
|
11535
|
+
return activeAnchor === el;
|
|
11536
|
+
};
|
|
11537
|
+
const onPointerDown = (e) => {
|
|
11538
|
+
if (e.button !== 0) return;
|
|
11539
|
+
if (suppressNextClickRef.current && Date.now() >= suppressClickUntilRef.current && !footerDragRef.current && !footerPointerDragRef.current?.started) {
|
|
11540
|
+
suppressNextClickRef.current = false;
|
|
11541
|
+
}
|
|
11542
|
+
if (footerDragRef.current) return;
|
|
11543
|
+
const target = e.target;
|
|
11544
|
+
if (!target) return;
|
|
11545
|
+
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]')) {
|
|
11546
|
+
return;
|
|
11547
|
+
}
|
|
11548
|
+
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
11549
|
+
const anchor = getNavigationItemAnchor(target);
|
|
11550
|
+
const hrefKey = anchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
11551
|
+
if (anchor && isFooterHrefKey(hrefKey)) {
|
|
11552
|
+
armFooterPressDrag();
|
|
11553
|
+
footerPointerDragRef.current = {
|
|
11554
|
+
el: anchor,
|
|
11555
|
+
kind: "link",
|
|
11556
|
+
startX: e.clientX,
|
|
11557
|
+
startY: e.clientY,
|
|
11558
|
+
pointerId: e.pointerId,
|
|
11559
|
+
wasSelected: resolveWasSelected(anchor),
|
|
11560
|
+
started: false
|
|
11561
|
+
};
|
|
11562
|
+
return;
|
|
11563
|
+
}
|
|
11564
|
+
const col = target.closest("[data-ohw-footer-col]");
|
|
11565
|
+
if (col && !getNavigationItemAnchor(target)) {
|
|
11566
|
+
armFooterPressDrag();
|
|
11567
|
+
footerPointerDragRef.current = {
|
|
11568
|
+
el: col,
|
|
11569
|
+
kind: "column",
|
|
11570
|
+
startX: e.clientX,
|
|
11571
|
+
startY: e.clientY,
|
|
11572
|
+
pointerId: e.pointerId,
|
|
11573
|
+
wasSelected: resolveWasSelected(col),
|
|
11574
|
+
started: false
|
|
11575
|
+
};
|
|
11576
|
+
}
|
|
11577
|
+
};
|
|
11578
|
+
const onPointerMove = (e) => {
|
|
11579
|
+
const pending = footerPointerDragRef.current;
|
|
11580
|
+
if (!pending) return;
|
|
11581
|
+
if (pending.started) {
|
|
11582
|
+
e.preventDefault();
|
|
11583
|
+
clearTextSelection();
|
|
11584
|
+
const session = footerDragRef.current;
|
|
11585
|
+
if (!session) return;
|
|
11586
|
+
const slot = session.kind === "link" && session.hrefKey ? hitTestLinkDropSlot(e.clientX, e.clientY, session.hrefKey) : hitTestColumnDropSlot(e.clientX, e.clientY);
|
|
11587
|
+
refreshFooterDragVisualsRef.current(session, slot, e.clientX, e.clientY);
|
|
11588
|
+
return;
|
|
11589
|
+
}
|
|
11590
|
+
const dx = e.clientX - pending.startX;
|
|
11591
|
+
const dy = e.clientY - pending.startY;
|
|
11592
|
+
if (dx * dx + dy * dy < THRESHOLD * THRESHOLD) return;
|
|
11593
|
+
e.preventDefault();
|
|
11594
|
+
pending.started = true;
|
|
11595
|
+
clearTextSelection();
|
|
11596
|
+
try {
|
|
11597
|
+
document.body.setPointerCapture(pending.pointerId);
|
|
11598
|
+
} catch {
|
|
11599
|
+
}
|
|
11600
|
+
if (linkPopoverOpenRef.current) {
|
|
11601
|
+
setLinkPopoverRef.current(null);
|
|
11602
|
+
}
|
|
11603
|
+
if (activeElRef.current) {
|
|
11604
|
+
deactivateRef.current();
|
|
11605
|
+
}
|
|
11606
|
+
if (pending.kind === "link") {
|
|
11607
|
+
const key = pending.el.getAttribute("data-ohw-href-key");
|
|
11608
|
+
if (!key) return;
|
|
11609
|
+
const column = findFooterColumnForLink(pending.el);
|
|
11610
|
+
const columns2 = listFooterColumns();
|
|
11611
|
+
beginFooterDragRef.current({
|
|
11612
|
+
kind: "link",
|
|
11613
|
+
hrefKey: key,
|
|
11614
|
+
columnEl: column,
|
|
11615
|
+
sourceColumnIndex: column ? columns2.indexOf(column) : 0,
|
|
11616
|
+
wasSelected: pending.wasSelected,
|
|
11617
|
+
draggedEl: pending.el,
|
|
11618
|
+
lastClientX: e.clientX,
|
|
11619
|
+
lastClientY: e.clientY,
|
|
11620
|
+
activeSlot: null
|
|
11621
|
+
});
|
|
11622
|
+
return;
|
|
11623
|
+
}
|
|
11624
|
+
const columns = listFooterColumns();
|
|
11625
|
+
const idx = columns.indexOf(pending.el);
|
|
11626
|
+
if (idx < 0) return;
|
|
11627
|
+
beginFooterDragRef.current({
|
|
11628
|
+
kind: "column",
|
|
11629
|
+
hrefKey: null,
|
|
11630
|
+
columnEl: pending.el,
|
|
11631
|
+
sourceColumnIndex: idx,
|
|
11632
|
+
wasSelected: pending.wasSelected,
|
|
11633
|
+
draggedEl: pending.el,
|
|
11634
|
+
lastClientX: e.clientX,
|
|
11635
|
+
lastClientY: e.clientY,
|
|
11636
|
+
activeSlot: null
|
|
11637
|
+
});
|
|
11638
|
+
};
|
|
11639
|
+
const endPointerDrag = (e) => {
|
|
11640
|
+
const pending = footerPointerDragRef.current;
|
|
11641
|
+
footerPointerDragRef.current = null;
|
|
11642
|
+
try {
|
|
11643
|
+
if (document.body.hasPointerCapture(e.pointerId)) {
|
|
11644
|
+
document.body.releasePointerCapture(e.pointerId);
|
|
11645
|
+
}
|
|
11646
|
+
} catch {
|
|
11647
|
+
}
|
|
11648
|
+
if (!pending?.started) {
|
|
11649
|
+
unlockFooterDragInteraction();
|
|
11650
|
+
return;
|
|
11651
|
+
}
|
|
11652
|
+
suppressNextClickRef.current = true;
|
|
11653
|
+
suppressClickUntilRef.current = Date.now() + 500;
|
|
11654
|
+
commitFooterDragRef.current(e.clientX, e.clientY);
|
|
11655
|
+
};
|
|
11656
|
+
const blockSelectStart = (e) => {
|
|
11657
|
+
if (footerDragRef.current || footerPointerDragRef.current?.started || document.documentElement.hasAttribute("data-ohw-footer-press-drag")) {
|
|
11658
|
+
e.preventDefault();
|
|
11659
|
+
}
|
|
11660
|
+
};
|
|
11661
|
+
const onDragEnd = (_e) => {
|
|
11662
|
+
if (!footerDragRef.current) return;
|
|
11663
|
+
suppressNextClickRef.current = true;
|
|
11664
|
+
suppressClickUntilRef.current = Date.now() + 500;
|
|
11665
|
+
commitFooterDragRef.current();
|
|
11666
|
+
};
|
|
11667
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
11668
|
+
document.addEventListener("pointermove", onPointerMove, true);
|
|
11669
|
+
document.addEventListener("pointerup", endPointerDrag, true);
|
|
11670
|
+
document.addEventListener("pointercancel", endPointerDrag, true);
|
|
11671
|
+
document.addEventListener("selectstart", blockSelectStart, true);
|
|
11672
|
+
document.addEventListener("dragend", onDragEnd, true);
|
|
11673
|
+
return () => {
|
|
11674
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
11675
|
+
document.removeEventListener("pointermove", onPointerMove, true);
|
|
11676
|
+
document.removeEventListener("pointerup", endPointerDrag, true);
|
|
11677
|
+
document.removeEventListener("pointercancel", endPointerDrag, true);
|
|
11678
|
+
document.removeEventListener("selectstart", blockSelectStart, true);
|
|
11679
|
+
document.removeEventListener("dragend", onDragEnd, true);
|
|
11680
|
+
unlockFooterDragInteraction();
|
|
11681
|
+
};
|
|
11682
|
+
}, [isEditMode]);
|
|
11683
|
+
(0, import_react9.useEffect)(() => {
|
|
9434
11684
|
const handler = (e) => {
|
|
9435
11685
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
9436
11686
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -9446,7 +11696,7 @@ function OhhwellsBridge() {
|
|
|
9446
11696
|
window.addEventListener("message", handler);
|
|
9447
11697
|
return () => window.removeEventListener("message", handler);
|
|
9448
11698
|
}, [processConfigRequest]);
|
|
9449
|
-
(0,
|
|
11699
|
+
(0, import_react9.useEffect)(() => {
|
|
9450
11700
|
if (!isEditMode) return;
|
|
9451
11701
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
9452
11702
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -9467,7 +11717,13 @@ function OhhwellsBridge() {
|
|
|
9467
11717
|
const next = { ...prev, [pathKey]: sections };
|
|
9468
11718
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
9469
11719
|
});
|
|
9470
|
-
postToParent2({
|
|
11720
|
+
postToParent2({
|
|
11721
|
+
type: "ow:ready",
|
|
11722
|
+
version: "1",
|
|
11723
|
+
path: pathname,
|
|
11724
|
+
nodes: collectEditableNodes(editContentRef.current),
|
|
11725
|
+
sections
|
|
11726
|
+
});
|
|
9471
11727
|
postToParent2({ type: "ow:request-site-pages" });
|
|
9472
11728
|
}, 150);
|
|
9473
11729
|
return () => {
|
|
@@ -9475,19 +11731,19 @@ function OhhwellsBridge() {
|
|
|
9475
11731
|
clearTimeout(timer);
|
|
9476
11732
|
};
|
|
9477
11733
|
}, [pathname, isEditMode, refreshStateRules, postToParent2]);
|
|
9478
|
-
(0,
|
|
11734
|
+
(0, import_react9.useEffect)(() => {
|
|
9479
11735
|
scrollToHashSectionWhenReady();
|
|
9480
11736
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
9481
11737
|
window.addEventListener("hashchange", onHashChange);
|
|
9482
11738
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
9483
11739
|
}, [pathname]);
|
|
9484
|
-
const handleCommand = (0,
|
|
11740
|
+
const handleCommand = (0, import_react9.useCallback)((cmd) => {
|
|
9485
11741
|
document.execCommand(cmd, false);
|
|
9486
11742
|
activeElRef.current?.focus();
|
|
9487
11743
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
9488
11744
|
refreshActiveCommandsRef.current();
|
|
9489
11745
|
}, []);
|
|
9490
|
-
const handleStateChange = (0,
|
|
11746
|
+
const handleStateChange = (0, import_react9.useCallback)((state) => {
|
|
9491
11747
|
if (!activeStateElRef.current) return;
|
|
9492
11748
|
const el = activeStateElRef.current;
|
|
9493
11749
|
if (state === "Default") {
|
|
@@ -9500,11 +11756,11 @@ function OhhwellsBridge() {
|
|
|
9500
11756
|
}
|
|
9501
11757
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
9502
11758
|
}, [deactivate]);
|
|
9503
|
-
const closeLinkPopover = (0,
|
|
11759
|
+
const closeLinkPopover = (0, import_react9.useCallback)(() => {
|
|
9504
11760
|
addNavAfterAnchorRef.current = null;
|
|
9505
11761
|
setLinkPopover(null);
|
|
9506
11762
|
}, []);
|
|
9507
|
-
const openLinkPopoverForActive = (0,
|
|
11763
|
+
const openLinkPopoverForActive = (0, import_react9.useCallback)(() => {
|
|
9508
11764
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
9509
11765
|
if (!hrefCtx) return;
|
|
9510
11766
|
bumpLinkPopoverGrace();
|
|
@@ -9515,7 +11771,7 @@ function OhhwellsBridge() {
|
|
|
9515
11771
|
});
|
|
9516
11772
|
deactivate();
|
|
9517
11773
|
}, [deactivate]);
|
|
9518
|
-
const openLinkPopoverForSelected = (0,
|
|
11774
|
+
const openLinkPopoverForSelected = (0, import_react9.useCallback)(() => {
|
|
9519
11775
|
const anchor = selectedElRef.current;
|
|
9520
11776
|
if (!anchor) return;
|
|
9521
11777
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -9528,7 +11784,7 @@ function OhhwellsBridge() {
|
|
|
9528
11784
|
});
|
|
9529
11785
|
deselect();
|
|
9530
11786
|
}, [deselect]);
|
|
9531
|
-
const handleLinkPopoverSubmit = (0,
|
|
11787
|
+
const handleLinkPopoverSubmit = (0, import_react9.useCallback)(
|
|
9532
11788
|
(target) => {
|
|
9533
11789
|
const session = linkPopoverSessionRef.current;
|
|
9534
11790
|
if (!session) return;
|
|
@@ -9587,13 +11843,13 @@ function OhhwellsBridge() {
|
|
|
9587
11843
|
const showEditLink = toolbarShowEditLink;
|
|
9588
11844
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
9589
11845
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
9590
|
-
const handleMediaReplace = (0,
|
|
11846
|
+
const handleMediaReplace = (0, import_react9.useCallback)(
|
|
9591
11847
|
(key) => {
|
|
9592
11848
|
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
9593
11849
|
},
|
|
9594
11850
|
[postToParent2, mediaHover?.elementType]
|
|
9595
11851
|
);
|
|
9596
|
-
const handleMediaFadeOutComplete = (0,
|
|
11852
|
+
const handleMediaFadeOutComplete = (0, import_react9.useCallback)((key) => {
|
|
9597
11853
|
setUploadingRects((prev) => {
|
|
9598
11854
|
if (!(key in prev)) return prev;
|
|
9599
11855
|
const next = { ...prev };
|
|
@@ -9601,7 +11857,7 @@ function OhhwellsBridge() {
|
|
|
9601
11857
|
return next;
|
|
9602
11858
|
});
|
|
9603
11859
|
}, []);
|
|
9604
|
-
const handleVideoSettingsChange = (0,
|
|
11860
|
+
const handleVideoSettingsChange = (0, import_react9.useCallback)(
|
|
9605
11861
|
(key, settings) => {
|
|
9606
11862
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
9607
11863
|
const video = getVideoEl(el);
|
|
@@ -9624,9 +11880,9 @@ function OhhwellsBridge() {
|
|
|
9624
11880
|
[postToParent2]
|
|
9625
11881
|
);
|
|
9626
11882
|
return bridgeRoot ? (0, import_react_dom3.createPortal)(
|
|
9627
|
-
/* @__PURE__ */ (0,
|
|
9628
|
-
/* @__PURE__ */ (0,
|
|
9629
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0,
|
|
11883
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
11884
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
11885
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9630
11886
|
MediaOverlay,
|
|
9631
11887
|
{
|
|
9632
11888
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -9637,7 +11893,7 @@ function OhhwellsBridge() {
|
|
|
9637
11893
|
},
|
|
9638
11894
|
`uploading-${key}`
|
|
9639
11895
|
)),
|
|
9640
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0,
|
|
11896
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9641
11897
|
MediaOverlay,
|
|
9642
11898
|
{
|
|
9643
11899
|
hover: mediaHover,
|
|
@@ -9646,49 +11902,93 @@ function OhhwellsBridge() {
|
|
|
9646
11902
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
9647
11903
|
}
|
|
9648
11904
|
),
|
|
9649
|
-
siblingHintRect && !isItemDragging && /* @__PURE__ */ (0,
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
|
|
11905
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
11906
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
11907
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
11908
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
11909
|
+
"div",
|
|
9653
11910
|
{
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
11911
|
+
className: "pointer-events-none fixed z-2147483646",
|
|
11912
|
+
style: {
|
|
11913
|
+
left: slot.left,
|
|
11914
|
+
top: slot.top,
|
|
11915
|
+
width: slot.width,
|
|
11916
|
+
height: slot.height
|
|
11917
|
+
},
|
|
11918
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
11919
|
+
DropIndicator,
|
|
11920
|
+
{
|
|
11921
|
+
direction: slot.direction,
|
|
11922
|
+
state: activeFooterDropIndex === i ? "dragActive" : "dragIdle",
|
|
11923
|
+
className: "!h-full !w-full"
|
|
11924
|
+
}
|
|
11925
|
+
)
|
|
11926
|
+
},
|
|
11927
|
+
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
11928
|
+
)),
|
|
11929
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
11930
|
+
"div",
|
|
11931
|
+
{
|
|
11932
|
+
className: "pointer-events-none fixed z-2147483646",
|
|
11933
|
+
style: {
|
|
11934
|
+
left: slot.left,
|
|
11935
|
+
top: slot.top,
|
|
11936
|
+
width: slot.width,
|
|
11937
|
+
height: slot.height
|
|
11938
|
+
},
|
|
11939
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
11940
|
+
DropIndicator,
|
|
11941
|
+
{
|
|
11942
|
+
direction: slot.direction,
|
|
11943
|
+
state: activeNavDropIndex === i ? "dragActive" : "dragIdle",
|
|
11944
|
+
className: "!h-full !w-full"
|
|
11945
|
+
}
|
|
11946
|
+
)
|
|
11947
|
+
},
|
|
11948
|
+
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
11949
|
+
)),
|
|
11950
|
+
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
11951
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
11952
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
11953
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9660
11954
|
ItemInteractionLayer,
|
|
9661
11955
|
{
|
|
9662
|
-
rect: toolbarRect,
|
|
11956
|
+
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
9663
11957
|
elRef: glowElRef,
|
|
9664
11958
|
state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
|
|
9665
|
-
showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey),
|
|
11959
|
+
showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection,
|
|
9666
11960
|
dragDisabled: reorderDragDisabled,
|
|
9667
11961
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
9668
11962
|
onDragHandleDragStart: handleItemDragStart,
|
|
9669
11963
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
9670
|
-
|
|
11964
|
+
onItemPointerDown: handleItemChromePointerDown,
|
|
11965
|
+
onItemClick: handleItemChromeClick,
|
|
11966
|
+
itemDragSurface: !isFooterFrameSelection,
|
|
11967
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9671
11968
|
ItemActionToolbar,
|
|
9672
11969
|
{
|
|
9673
11970
|
onEditLink: openLinkPopoverForSelected,
|
|
9674
11971
|
addItemDisabled: true,
|
|
9675
11972
|
editLinkDisabled: false,
|
|
9676
|
-
moreDisabled: true
|
|
11973
|
+
moreDisabled: true,
|
|
11974
|
+
showAddItem: !selectedIsCta,
|
|
11975
|
+
showMore: !selectedIsCta
|
|
9677
11976
|
}
|
|
9678
11977
|
) : void 0
|
|
9679
11978
|
}
|
|
9680
11979
|
),
|
|
9681
|
-
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0,
|
|
9682
|
-
/* @__PURE__ */ (0,
|
|
11980
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
11981
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9683
11982
|
EditGlowChrome,
|
|
9684
11983
|
{
|
|
9685
11984
|
rect: toolbarRect,
|
|
9686
11985
|
elRef: glowElRef,
|
|
9687
11986
|
reorderHrefKey,
|
|
9688
|
-
dragDisabled: reorderDragDisabled
|
|
11987
|
+
dragDisabled: reorderDragDisabled,
|
|
11988
|
+
hideHandle: isItemDragging
|
|
9689
11989
|
}
|
|
9690
11990
|
),
|
|
9691
|
-
/* @__PURE__ */ (0,
|
|
11991
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9692
11992
|
FloatingToolbar,
|
|
9693
11993
|
{
|
|
9694
11994
|
rect: toolbarRect,
|
|
@@ -9701,7 +12001,7 @@ function OhhwellsBridge() {
|
|
|
9701
12001
|
}
|
|
9702
12002
|
)
|
|
9703
12003
|
] }),
|
|
9704
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
12004
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9705
12005
|
"div",
|
|
9706
12006
|
{
|
|
9707
12007
|
"data-ohw-max-badge": "",
|
|
@@ -9727,7 +12027,7 @@ function OhhwellsBridge() {
|
|
|
9727
12027
|
]
|
|
9728
12028
|
}
|
|
9729
12029
|
),
|
|
9730
|
-
toggleState && !linkPopover && /* @__PURE__ */ (0,
|
|
12030
|
+
toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9731
12031
|
StateToggle,
|
|
9732
12032
|
{
|
|
9733
12033
|
rect: toggleState.rect,
|
|
@@ -9736,32 +12036,36 @@ function OhhwellsBridge() {
|
|
|
9736
12036
|
onStateChange: handleStateChange
|
|
9737
12037
|
}
|
|
9738
12038
|
),
|
|
9739
|
-
sectionGap && !linkPopover && /* @__PURE__ */ (0,
|
|
12039
|
+
sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
9740
12040
|
"div",
|
|
9741
12041
|
{
|
|
9742
12042
|
"data-ohw-section-insert-line": "",
|
|
9743
12043
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
9744
12044
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
9745
12045
|
children: [
|
|
9746
|
-
/* @__PURE__ */ (0,
|
|
9747
|
-
/* @__PURE__ */ (0,
|
|
12046
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
12047
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9748
12048
|
Badge,
|
|
9749
12049
|
{
|
|
9750
12050
|
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",
|
|
9751
12051
|
onClick: () => {
|
|
9752
12052
|
window.parent.postMessage(
|
|
9753
|
-
{
|
|
12053
|
+
{
|
|
12054
|
+
type: "ow:add-section",
|
|
12055
|
+
insertAfter: sectionGap.insertAfter,
|
|
12056
|
+
insertBefore: sectionGap.insertBefore
|
|
12057
|
+
},
|
|
9754
12058
|
"*"
|
|
9755
12059
|
);
|
|
9756
12060
|
},
|
|
9757
12061
|
children: "Add Section"
|
|
9758
12062
|
}
|
|
9759
12063
|
),
|
|
9760
|
-
/* @__PURE__ */ (0,
|
|
12064
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
9761
12065
|
]
|
|
9762
12066
|
}
|
|
9763
12067
|
),
|
|
9764
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0,
|
|
12068
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9765
12069
|
LinkPopover,
|
|
9766
12070
|
{
|
|
9767
12071
|
panelRef: linkPopoverPanelRef,
|
|
@@ -9782,48 +12086,6 @@ function OhhwellsBridge() {
|
|
|
9782
12086
|
bridgeRoot
|
|
9783
12087
|
) : null;
|
|
9784
12088
|
}
|
|
9785
|
-
|
|
9786
|
-
// src/ui/drop-indicator.tsx
|
|
9787
|
-
var React10 = __toESM(require("react"), 1);
|
|
9788
|
-
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
9789
|
-
var dropIndicatorVariants = cva(
|
|
9790
|
-
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
9791
|
-
{
|
|
9792
|
-
variants: {
|
|
9793
|
-
direction: {
|
|
9794
|
-
vertical: "h-6 w-[3px]",
|
|
9795
|
-
horizontal: "h-[3px] w-[200px]"
|
|
9796
|
-
},
|
|
9797
|
-
state: {
|
|
9798
|
-
default: "opacity-0",
|
|
9799
|
-
hover: "opacity-100",
|
|
9800
|
-
dragIdle: "opacity-40",
|
|
9801
|
-
dragActive: "opacity-100"
|
|
9802
|
-
}
|
|
9803
|
-
},
|
|
9804
|
-
defaultVariants: {
|
|
9805
|
-
direction: "vertical",
|
|
9806
|
-
state: "default"
|
|
9807
|
-
}
|
|
9808
|
-
}
|
|
9809
|
-
);
|
|
9810
|
-
var DropIndicator = React10.forwardRef(
|
|
9811
|
-
({ className, direction, state, ...props }, ref) => {
|
|
9812
|
-
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
9813
|
-
"div",
|
|
9814
|
-
{
|
|
9815
|
-
ref,
|
|
9816
|
-
"data-slot": "drop-indicator",
|
|
9817
|
-
"data-direction": direction ?? "vertical",
|
|
9818
|
-
"data-state": state ?? "default",
|
|
9819
|
-
"aria-hidden": "true",
|
|
9820
|
-
className: cn(dropIndicatorVariants({ direction, state }), className),
|
|
9821
|
-
...props
|
|
9822
|
-
}
|
|
9823
|
-
);
|
|
9824
|
-
}
|
|
9825
|
-
);
|
|
9826
|
-
DropIndicator.displayName = "DropIndicator";
|
|
9827
12089
|
// Annotate the CommonJS export names for ESM import in node:
|
|
9828
12090
|
0 && (module.exports = {
|
|
9829
12091
|
CustomToolbar,
|