@ohhwells/bridge 0.1.33 → 0.1.34-next.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -31,6 +31,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/index.ts
32
32
  var index_exports = {};
33
33
  __export(index_exports, {
34
+ CustomToolbar: () => CustomToolbar,
35
+ CustomToolbarButton: () => CustomToolbarButton,
36
+ CustomToolbarDivider: () => CustomToolbarDivider,
37
+ DragHandle: () => DragHandle,
38
+ ItemActionToolbar: () => ItemActionToolbar,
39
+ ItemInteractionLayer: () => ItemInteractionLayer,
34
40
  LinkEditorPanel: () => LinkEditorPanel,
35
41
  LinkPopover: () => LinkPopover,
36
42
  OhhwellsBridge: () => OhhwellsBridge,
@@ -38,9 +44,14 @@ __export(index_exports, {
38
44
  Toggle: () => Toggle,
39
45
  ToggleGroup: () => ToggleGroup,
40
46
  ToggleGroupItem: () => ToggleGroupItem,
47
+ Tooltip: () => Tooltip,
48
+ TooltipContent: () => TooltipContent,
49
+ TooltipProvider: () => TooltipProvider,
50
+ TooltipTrigger: () => TooltipTrigger,
41
51
  buildTarget: () => buildTarget,
42
52
  filterAvailablePages: () => filterAvailablePages,
43
53
  getEditModeInitialState: () => getEditModeInitialState,
54
+ isEditSessionActive: () => isEditSessionActive,
44
55
  isValidUrl: () => isValidUrl,
45
56
  parseTarget: () => parseTarget,
46
57
  toggleVariants: () => toggleVariants,
@@ -269,12 +280,20 @@ function formatClassTime(cls) {
269
280
  const em = endTotal % 60;
270
281
  return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
271
282
  }
283
+ function formatBookingLabel(cls) {
284
+ const price = cls.price;
285
+ const isFree = price === null || price === void 0 || `${price}` === "" || `${price}` === "0";
286
+ return isFree ? "Book for free" : `Book for ${cls.currency ?? ""} ${price}`.trim();
287
+ }
272
288
  function getBookingsOnDate(cls, date) {
273
289
  if (!cls.bookings?.length) return 0;
274
- const ds = date.toISOString().split("T")[0];
290
+ const target = new Date(date);
291
+ target.setHours(0, 0, 0, 0);
275
292
  return cls.bookings.filter((b) => {
276
293
  try {
277
- return new Date(b.classDate).toISOString().split("T")[0] === ds;
294
+ const bookingDate = new Date(b.classDate);
295
+ bookingDate.setHours(0, 0, 0, 0);
296
+ return bookingDate.getTime() === target.getTime();
278
297
  } catch {
279
298
  return false;
280
299
  }
@@ -578,7 +597,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
578
597
  if (!cls.id) return;
579
598
  onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
580
599
  },
581
- children: isFull ? "Join Waitlist" : "Book Now"
600
+ children: isFull ? "Join Waitlist" : formatBookingLabel(cls)
582
601
  }
583
602
  )
584
603
  ] })
@@ -760,15 +779,10 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
760
779
  };
761
780
  const handleReplaceSchedule = () => {
762
781
  setIsHovered(false);
763
- if (schedule) {
764
- window.parent.postMessage({
765
- type: "ow:schedule-connected",
766
- schedule: { id: schedule.id, name: schedule.name },
767
- insertAfter
768
- }, "*");
769
- } else {
770
- window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
771
- }
782
+ window.parent.postMessage(
783
+ { type: "ow:scheduling-not-connected", insertAfter, currentScheduleId: schedule?.id },
784
+ "*"
785
+ );
772
786
  };
773
787
  if (!inEditor && !loading && !schedule) return null;
774
788
  const sectionId = `scheduling-${insertAfter}`;
@@ -811,7 +825,19 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
811
825
  ),
812
826
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
813
827
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
814
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "font-display text-4xl sm:text-5xl font-bold text-center m-0 text-(--color-dark,#200C02)", children: schedule?.name ?? "Book an appointment" }),
828
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
829
+ "h2",
830
+ {
831
+ className: "font-display text-center m-0 text-(--color-dark,#200C02)",
832
+ style: {
833
+ fontSize: "var(--fs-section-h2, clamp(40px, 4.4vw, 64px))",
834
+ fontWeight: "var(--font-weight-heading, 400)",
835
+ lineHeight: 1.05,
836
+ letterSpacing: "-0.02em"
837
+ },
838
+ children: schedule?.name ?? "Book an appointment"
839
+ }
840
+ ),
815
841
  schedule?.description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "font-body text-body text-center m-0 text-(--color-accent,#A89B83)", children: schedule.description })
816
842
  ] }),
817
843
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "w-full flex flex-col items-end gap-3", children: [
@@ -4250,6 +4276,336 @@ function ToggleGroupItem({
4250
4276
  );
4251
4277
  }
4252
4278
 
4279
+ // src/ui/drag-handle.tsx
4280
+ var React3 = __toESM(require("react"), 1);
4281
+ var import_lucide_react = require("lucide-react");
4282
+ var import_jsx_runtime5 = require("react/jsx-runtime");
4283
+ var DragHandle = React3.forwardRef(
4284
+ ({ className, type = "button", ...props }, ref) => {
4285
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4286
+ "button",
4287
+ {
4288
+ ref,
4289
+ type,
4290
+ "data-slot": "drag-handle",
4291
+ className: cn(
4292
+ "inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-[30px]",
4293
+ "bg-white border border-transparent text-stone-500 shadow-md cursor-grab",
4294
+ "enabled:hover:border enabled:hover:border-stone-200 enabled:hover:text-stone-950",
4295
+ "enabled:active:border enabled:active:border-primary enabled:active:bg-primary-50 enabled:active:text-stone-950 enabled:active:shadow enabled:active:cursor-grabbing",
4296
+ "disabled:cursor-not-allowed disabled:opacity-40 disabled:text-stone-950 disabled:pointer-events-none",
4297
+ className
4298
+ ),
4299
+ ...props,
4300
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.GripVertical, { className: "size-4 shrink-0", "aria-hidden": "true" })
4301
+ }
4302
+ );
4303
+ }
4304
+ );
4305
+ DragHandle.displayName = "DragHandle";
4306
+
4307
+ // src/ui/custom-toolbar.tsx
4308
+ var React4 = __toESM(require("react"), 1);
4309
+ var import_jsx_runtime6 = require("react/jsx-runtime");
4310
+ var CustomToolbar = React4.forwardRef(({ className, onMouseDown, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4311
+ "div",
4312
+ {
4313
+ ref,
4314
+ "data-ohw-toolbar": "",
4315
+ className: cn(
4316
+ "inline-flex items-center gap-1 rounded-lg border border-border bg-background p-0.5 font-sans whitespace-nowrap shadow-[0px_2px_4px_-2px_rgba(0,0,0,0.1),0px_4px_6px_-1px_rgba(0,0,0,0.1)]",
4317
+ className
4318
+ ),
4319
+ onMouseDown: (e) => {
4320
+ e.stopPropagation();
4321
+ onMouseDown?.(e);
4322
+ },
4323
+ ...props
4324
+ }
4325
+ ));
4326
+ CustomToolbar.displayName = "CustomToolbar";
4327
+ function CustomToolbarDivider({ className, ...props }) {
4328
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4329
+ "span",
4330
+ {
4331
+ "aria-hidden": true,
4332
+ className: cn("block h-6 w-px shrink-0 bg-border", className),
4333
+ ...props
4334
+ }
4335
+ );
4336
+ }
4337
+ var CustomToolbarButton = React4.forwardRef(
4338
+ ({ className, active = false, type = "button", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4339
+ "button",
4340
+ {
4341
+ ref,
4342
+ type,
4343
+ className: cn(
4344
+ "inline-flex shrink-0 items-center justify-center rounded p-1.5 transition-colors",
4345
+ active ? "bg-primary text-primary-foreground" : "bg-transparent text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
4346
+ className
4347
+ ),
4348
+ ...props
4349
+ }
4350
+ )
4351
+ );
4352
+ CustomToolbarButton.displayName = "CustomToolbarButton";
4353
+
4354
+ // src/ui/item-action-toolbar.tsx
4355
+ var import_lucide_react2 = require("lucide-react");
4356
+
4357
+ // src/ui/tooltip.tsx
4358
+ var import_radix_ui3 = require("radix-ui");
4359
+ var import_jsx_runtime7 = require("react/jsx-runtime");
4360
+ function TooltipProvider({
4361
+ delayDuration = 0,
4362
+ ...props
4363
+ }) {
4364
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Tooltip.Provider, { "data-slot": "tooltip-provider", delayDuration, ...props });
4365
+ }
4366
+ function Tooltip({ ...props }) {
4367
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Tooltip.Root, { "data-slot": "tooltip", ...props });
4368
+ }
4369
+ function TooltipTrigger({ ...props }) {
4370
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Tooltip.Trigger, { "data-slot": "tooltip-trigger", ...props });
4371
+ }
4372
+ var arrowClassBySide = {
4373
+ top: "before:bottom-0 before:left-1/2 before:-translate-x-1/2 before:translate-y-1/2",
4374
+ bottom: "before:top-0 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2",
4375
+ left: "before:right-0 before:top-1/2 before:-translate-y-1/2 before:translate-x-1/2",
4376
+ right: "before:left-0 before:top-1/2 before:-translate-y-1/2 before:-translate-x-1/2"
4377
+ };
4378
+ function TooltipContent({
4379
+ className,
4380
+ sideOffset = 6,
4381
+ side = "bottom",
4382
+ children,
4383
+ ...props
4384
+ }) {
4385
+ const resolvedSide = side ?? "bottom";
4386
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Tooltip.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4387
+ import_radix_ui3.Tooltip.Content,
4388
+ {
4389
+ "data-slot": "tooltip-content",
4390
+ side,
4391
+ sideOffset,
4392
+ className: cn(
4393
+ "relative z-[2147483647] w-fit max-w-xs rounded-md bg-foreground px-3 py-1.5 text-xs text-background shadow-md",
4394
+ 'before:pointer-events-none before:absolute before:size-2 before:rotate-45 before:bg-foreground before:content-[""]',
4395
+ arrowClassBySide[resolvedSide],
4396
+ "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",
4397
+ "data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
4398
+ "data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2",
4399
+ className
4400
+ ),
4401
+ ...props,
4402
+ children
4403
+ }
4404
+ ) });
4405
+ }
4406
+
4407
+ // src/ui/item-action-toolbar.tsx
4408
+ var import_jsx_runtime8 = require("react/jsx-runtime");
4409
+ function ToolbarActionTooltip({
4410
+ label,
4411
+ side = "bottom",
4412
+ disabled = false,
4413
+ buttonProps,
4414
+ children
4415
+ }) {
4416
+ const button = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, ...buttonProps, children });
4417
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Tooltip, { children: [
4418
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "inline-flex", children: button }) : button }),
4419
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipContent, { side, children: label })
4420
+ ] });
4421
+ }
4422
+ function ItemActionToolbar({
4423
+ onEditLink,
4424
+ onAddItem,
4425
+ onMore,
4426
+ addItemDisabled = true,
4427
+ moreDisabled = true,
4428
+ tooltipSide = "bottom"
4429
+ }) {
4430
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CustomToolbar, { children: [
4431
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
4432
+ ToolbarActionTooltip,
4433
+ {
4434
+ label: "Add link",
4435
+ side: tooltipSide,
4436
+ buttonProps: {
4437
+ onMouseDown: (e) => {
4438
+ e.preventDefault();
4439
+ e.stopPropagation();
4440
+ onEditLink?.();
4441
+ },
4442
+ onClick: (e) => {
4443
+ e.preventDefault();
4444
+ e.stopPropagation();
4445
+ }
4446
+ },
4447
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Link, { className: "size-4 shrink-0", "aria-hidden": true })
4448
+ }
4449
+ ),
4450
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CustomToolbarDivider, {}),
4451
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
4452
+ ToolbarActionTooltip,
4453
+ {
4454
+ label: "Add item",
4455
+ side: tooltipSide,
4456
+ disabled: addItemDisabled,
4457
+ buttonProps: {
4458
+ onMouseDown: (e) => {
4459
+ if (addItemDisabled) return;
4460
+ e.preventDefault();
4461
+ e.stopPropagation();
4462
+ onAddItem?.();
4463
+ }
4464
+ },
4465
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Plus, { className: "size-4 shrink-0", "aria-hidden": true })
4466
+ }
4467
+ ),
4468
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CustomToolbarDivider, {}),
4469
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
4470
+ ToolbarActionTooltip,
4471
+ {
4472
+ label: "More",
4473
+ side: tooltipSide,
4474
+ disabled: moreDisabled,
4475
+ buttonProps: {
4476
+ onMouseDown: (e) => {
4477
+ if (moreDisabled) return;
4478
+ e.preventDefault();
4479
+ e.stopPropagation();
4480
+ onMore?.();
4481
+ }
4482
+ },
4483
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.MoreHorizontal, { className: "size-4 shrink-0", "aria-hidden": true })
4484
+ }
4485
+ )
4486
+ ] }) });
4487
+ }
4488
+
4489
+ // src/ui/item-interaction-layer.tsx
4490
+ var import_jsx_runtime9 = require("react/jsx-runtime");
4491
+ var PRIMARY = "var(--ohw-primary, #0885FE)";
4492
+ var FOCUS_RING = "0 0 0 4px rgba(8, 133, 254, 0.12)";
4493
+ var DRAG_SHADOW = "0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.1)";
4494
+ function getChromeStyle(state) {
4495
+ switch (state) {
4496
+ case "hover":
4497
+ return {
4498
+ border: `1.5px dashed ${PRIMARY}`,
4499
+ boxShadow: "none"
4500
+ };
4501
+ case "sibling-hint":
4502
+ return {
4503
+ border: `1.5px dashed color-mix(in srgb, ${PRIMARY} 30%, transparent)`,
4504
+ boxShadow: "none"
4505
+ };
4506
+ case "active-top":
4507
+ case "active-bottom":
4508
+ return {
4509
+ border: `2px solid ${PRIMARY}`,
4510
+ boxShadow: FOCUS_RING
4511
+ };
4512
+ case "dragging":
4513
+ return {
4514
+ border: `2px solid ${PRIMARY}`,
4515
+ boxShadow: DRAG_SHADOW
4516
+ };
4517
+ default:
4518
+ return {};
4519
+ }
4520
+ }
4521
+ function ItemInteractionLayer({
4522
+ rect,
4523
+ state,
4524
+ elRef,
4525
+ toolbar,
4526
+ showHandle = false,
4527
+ dragDisabled = false,
4528
+ dragHandleLabel = "Reorder item",
4529
+ onDragHandleDragStart,
4530
+ onDragHandleDragEnd,
4531
+ chromeGap = 6,
4532
+ className
4533
+ }) {
4534
+ if (state === "default") return null;
4535
+ const isActive = state === "active-top" || state === "active-bottom";
4536
+ const isDragging = state === "dragging";
4537
+ const showToolbar = isActive && toolbar;
4538
+ const showDragHandle = isActive && showHandle && !isDragging;
4539
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4540
+ "div",
4541
+ {
4542
+ ref: elRef,
4543
+ "data-ohw-item-interaction": "",
4544
+ "data-ohw-item-interaction-state": state,
4545
+ className: cn("pointer-events-none", className),
4546
+ style: {
4547
+ position: "fixed",
4548
+ top: rect.top - chromeGap,
4549
+ left: rect.left - chromeGap,
4550
+ width: rect.width + chromeGap * 2,
4551
+ height: rect.height + chromeGap * 2,
4552
+ zIndex: 2147483646
4553
+ },
4554
+ children: [
4555
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4556
+ "div",
4557
+ {
4558
+ "aria-hidden": true,
4559
+ className: "absolute inset-0 rounded-lg",
4560
+ style: getChromeStyle(state)
4561
+ }
4562
+ ),
4563
+ showDragHandle && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4564
+ "div",
4565
+ {
4566
+ "data-ohw-drag-handle-container": "",
4567
+ className: "pointer-events-auto absolute left-0 top-1/2 -translate-x-[calc(100%+7px)] -translate-y-1/2",
4568
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4569
+ DragHandle,
4570
+ {
4571
+ draggable: !dragDisabled,
4572
+ "aria-label": dragHandleLabel,
4573
+ disabled: dragDisabled,
4574
+ onDragStart: (e) => {
4575
+ if (dragDisabled) {
4576
+ e.preventDefault();
4577
+ return;
4578
+ }
4579
+ e.dataTransfer?.setData("text/plain", dragHandleLabel);
4580
+ e.dataTransfer.effectAllowed = "move";
4581
+ onDragHandleDragStart?.(e);
4582
+ },
4583
+ onDragEnd: onDragHandleDragEnd
4584
+ }
4585
+ )
4586
+ }
4587
+ ),
4588
+ showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4589
+ "div",
4590
+ {
4591
+ className: "pointer-events-auto absolute bottom-full left-1/2 mb-2 -translate-x-1/2",
4592
+ "data-ohw-item-toolbar-anchor": "top",
4593
+ children: toolbar
4594
+ }
4595
+ ),
4596
+ showToolbar && state === "active-bottom" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4597
+ "div",
4598
+ {
4599
+ className: "pointer-events-auto absolute left-1/2 top-full mt-2 -translate-x-1/2",
4600
+ "data-ohw-item-toolbar-anchor": "bottom",
4601
+ children: toolbar
4602
+ }
4603
+ )
4604
+ ]
4605
+ }
4606
+ );
4607
+ }
4608
+
4253
4609
  // src/OhhwellsBridge.tsx
4254
4610
  var import_react_dom2 = require("react-dom");
4255
4611
  var import_navigation = require("next/navigation");
@@ -4529,61 +4885,61 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
4529
4885
  }
4530
4886
 
4531
4887
  // src/ui/dialog.tsx
4532
- var React3 = __toESM(require("react"), 1);
4533
- var import_radix_ui3 = require("radix-ui");
4888
+ var React5 = __toESM(require("react"), 1);
4889
+ var import_radix_ui4 = require("radix-ui");
4534
4890
 
4535
4891
  // src/ui/icons.tsx
4536
- var import_jsx_runtime5 = require("react/jsx-runtime");
4892
+ var import_jsx_runtime10 = require("react/jsx-runtime");
4537
4893
  function IconX({ className, ...props }) {
4538
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4539
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M18 6 6 18" }),
4540
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m6 6 12 12" })
4894
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4895
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M18 6 6 18" }),
4896
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m6 6 12 12" })
4541
4897
  ] });
4542
4898
  }
4543
4899
  function IconChevronDown({ className, ...props }) {
4544
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m6 9 6 6 6-6" }) });
4900
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m6 9 6 6 6-6" }) });
4545
4901
  }
4546
4902
  function IconFile({ className, ...props }) {
4547
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4548
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
4549
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
4903
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4904
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
4905
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
4550
4906
  ] });
4551
4907
  }
4552
4908
  function IconInfo({ className, ...props }) {
4553
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4554
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
4555
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 16v-4" }),
4556
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M12 8h.01" })
4909
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4910
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
4911
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 16v-4" }),
4912
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 8h.01" })
4557
4913
  ] });
4558
4914
  }
4559
4915
  function IconArrowRight({ className, ...props }) {
4560
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4561
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "M5 12h14" }),
4562
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { d: "m12 5 7 7-7 7" })
4916
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4917
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M5 12h14" }),
4918
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m12 5 7 7-7 7" })
4563
4919
  ] });
4564
4920
  }
4565
4921
  function IconSection({ className, ...props }) {
4566
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4567
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
4568
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
4569
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
4922
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4923
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
4924
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
4925
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
4570
4926
  ] });
4571
4927
  }
4572
4928
 
4573
4929
  // src/ui/dialog.tsx
4574
- var import_jsx_runtime6 = require("react/jsx-runtime");
4930
+ var import_jsx_runtime11 = require("react/jsx-runtime");
4575
4931
  function Dialog2({ ...props }) {
4576
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_radix_ui3.Dialog.Root, { "data-slot": "dialog", ...props });
4932
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_radix_ui4.Dialog.Root, { "data-slot": "dialog", ...props });
4577
4933
  }
4578
4934
  function DialogPortal({ ...props }) {
4579
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_radix_ui3.Dialog.Portal, { ...props });
4935
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_radix_ui4.Dialog.Portal, { ...props });
4580
4936
  }
4581
4937
  function DialogOverlay({
4582
4938
  className,
4583
4939
  ...props
4584
4940
  }) {
4585
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4586
- import_radix_ui3.Dialog.Overlay,
4941
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4942
+ import_radix_ui4.Dialog.Overlay,
4587
4943
  {
4588
4944
  "data-slot": "dialog-overlay",
4589
4945
  "data-ohw-link-modal-root": "",
@@ -4592,12 +4948,12 @@ function DialogOverlay({
4592
4948
  }
4593
4949
  );
4594
4950
  }
4595
- var DialogContent = React3.forwardRef(({ className, children, showCloseButton = true, container, ...props }, ref) => {
4951
+ var DialogContent = React5.forwardRef(({ className, children, showCloseButton = true, container, ...props }, ref) => {
4596
4952
  const positionMode = container ? "absolute" : "fixed";
4597
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogPortal, { container: container ?? void 0, children: [
4598
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
4599
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4600
- import_radix_ui3.Dialog.Content,
4953
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogPortal, { container: container ?? void 0, children: [
4954
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
4955
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
4956
+ import_radix_ui4.Dialog.Content,
4601
4957
  {
4602
4958
  ref,
4603
4959
  "data-slot": "dialog-content",
@@ -4612,13 +4968,13 @@ var DialogContent = React3.forwardRef(({ className, children, showCloseButton =
4612
4968
  ...props,
4613
4969
  children: [
4614
4970
  children,
4615
- showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4616
- import_radix_ui3.Dialog.Close,
4971
+ showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4972
+ import_radix_ui4.Dialog.Close,
4617
4973
  {
4618
4974
  type: "button",
4619
4975
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
4620
4976
  "aria-label": "Close",
4621
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconX, { "aria-hidden": true })
4977
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(IconX, { "aria-hidden": true })
4622
4978
  }
4623
4979
  ) : null
4624
4980
  ]
@@ -4626,37 +4982,37 @@ var DialogContent = React3.forwardRef(({ className, children, showCloseButton =
4626
4982
  )
4627
4983
  ] });
4628
4984
  });
4629
- DialogContent.displayName = import_radix_ui3.Dialog.Content.displayName;
4985
+ DialogContent.displayName = import_radix_ui4.Dialog.Content.displayName;
4630
4986
  function DialogHeader({ className, ...props }) {
4631
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
4987
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
4632
4988
  }
4633
4989
  function DialogFooter({ className, ...props }) {
4634
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: cn("flex items-center justify-end gap-2", className), ...props });
4990
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cn("flex items-center justify-end gap-2", className), ...props });
4635
4991
  }
4636
- var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4637
- import_radix_ui3.Dialog.Title,
4992
+ var DialogTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4993
+ import_radix_ui4.Dialog.Title,
4638
4994
  {
4639
4995
  ref,
4640
4996
  className: cn("text-lg font-semibold leading-none tracking-tight text-card-foreground", className),
4641
4997
  ...props
4642
4998
  }
4643
4999
  ));
4644
- DialogTitle.displayName = import_radix_ui3.Dialog.Title.displayName;
4645
- var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4646
- import_radix_ui3.Dialog.Description,
5000
+ DialogTitle.displayName = import_radix_ui4.Dialog.Title.displayName;
5001
+ var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
5002
+ import_radix_ui4.Dialog.Description,
4647
5003
  {
4648
5004
  ref,
4649
5005
  className: cn("text-sm text-muted-foreground", className),
4650
5006
  ...props
4651
5007
  }
4652
5008
  ));
4653
- DialogDescription.displayName = import_radix_ui3.Dialog.Description.displayName;
4654
- var DialogClose = import_radix_ui3.Dialog.Close;
5009
+ DialogDescription.displayName = import_radix_ui4.Dialog.Description.displayName;
5010
+ var DialogClose = import_radix_ui4.Dialog.Close;
4655
5011
 
4656
5012
  // src/ui/button.tsx
4657
- var React4 = __toESM(require("react"), 1);
4658
- var import_radix_ui4 = require("radix-ui");
4659
- var import_jsx_runtime7 = require("react/jsx-runtime");
5013
+ var React6 = __toESM(require("react"), 1);
5014
+ var import_radix_ui5 = require("radix-ui");
5015
+ var import_jsx_runtime12 = require("react/jsx-runtime");
4660
5016
  var buttonVariants = cva(
4661
5017
  "inline-flex items-center justify-center gap-1 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none disabled:pointer-events-none disabled:opacity-50 min-w-[80px] px-3 py-2",
4662
5018
  {
@@ -4677,10 +5033,10 @@ var buttonVariants = cva(
4677
5033
  }
4678
5034
  }
4679
5035
  );
4680
- var Button = React4.forwardRef(
5036
+ var Button = React6.forwardRef(
4681
5037
  ({ className, variant, size, asChild = false, ...props }, ref) => {
4682
- const Comp = asChild ? import_radix_ui4.Slot.Root : "button";
4683
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5038
+ const Comp = asChild ? import_radix_ui5.Slot.Root : "button";
5039
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4684
5040
  Comp,
4685
5041
  {
4686
5042
  ref,
@@ -4694,37 +5050,37 @@ var Button = React4.forwardRef(
4694
5050
  Button.displayName = "Button";
4695
5051
 
4696
5052
  // src/ui/link-modal/DestinationBreadcrumb.tsx
4697
- var import_jsx_runtime8 = require("react/jsx-runtime");
5053
+ var import_jsx_runtime13 = require("react/jsx-runtime");
4698
5054
  function DestinationBreadcrumb({ pageTitle, sectionLabel }) {
4699
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
4700
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
4701
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-3", children: [
4702
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-2", children: [
4703
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconFile, { className: "shrink-0 text-foreground", "aria-hidden": true }),
4704
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-sm font-medium leading-none text-foreground", children: pageTitle })
5055
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
5056
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
5057
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-3", children: [
5058
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
5059
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconFile, { className: "shrink-0 text-foreground", "aria-hidden": true }),
5060
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-sm font-medium leading-none text-foreground", children: pageTitle })
4705
5061
  ] }),
4706
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconArrowRight, { className: "shrink-0 text-muted-foreground", "aria-hidden": true }),
4707
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
4708
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
4709
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
5062
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconArrowRight, { className: "shrink-0 text-muted-foreground", "aria-hidden": true }),
5063
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
5064
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
5065
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
4710
5066
  ] })
4711
5067
  ] })
4712
5068
  ] });
4713
5069
  }
4714
5070
 
4715
5071
  // src/ui/link-modal/SectionTreeItem.tsx
4716
- var import_jsx_runtime9 = require("react/jsx-runtime");
5072
+ var import_jsx_runtime14 = require("react/jsx-runtime");
4717
5073
  function SectionTreeItem({ section, onSelect, selected }) {
4718
5074
  const interactive = Boolean(onSelect);
4719
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
4720
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
5075
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
5076
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
4721
5077
  "div",
4722
5078
  {
4723
5079
  className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
4724
5080
  "aria-hidden": true
4725
5081
  }
4726
5082
  ),
4727
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
5083
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
4728
5084
  "div",
4729
5085
  {
4730
5086
  role: interactive ? "button" : void 0,
@@ -4742,8 +5098,8 @@ function SectionTreeItem({ section, onSelect, selected }) {
4742
5098
  interactive && selected && "border-primary"
4743
5099
  ),
4744
5100
  children: [
4745
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
4746
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
5101
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
5102
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
4747
5103
  ]
4748
5104
  }
4749
5105
  )
@@ -4751,11 +5107,11 @@ function SectionTreeItem({ section, onSelect, selected }) {
4751
5107
  }
4752
5108
  function SectionPickerList({ sections, onSelect }) {
4753
5109
  if (sections.length === 0) {
4754
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
5110
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
4755
5111
  }
4756
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col gap-1", children: [
4757
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
4758
- sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SectionTreeItem, { section, onSelect }, section.id))
5112
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-1", children: [
5113
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
5114
+ sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SectionTreeItem, { section, onSelect }, section.id))
4759
5115
  ] });
4760
5116
  }
4761
5117
 
@@ -4763,11 +5119,11 @@ function SectionPickerList({ sections, onSelect }) {
4763
5119
  var import_react4 = require("react");
4764
5120
 
4765
5121
  // src/ui/input.tsx
4766
- var React5 = __toESM(require("react"), 1);
4767
- var import_jsx_runtime10 = require("react/jsx-runtime");
4768
- var Input = React5.forwardRef(
5122
+ var React7 = __toESM(require("react"), 1);
5123
+ var import_jsx_runtime15 = require("react/jsx-runtime");
5124
+ var Input = React7.forwardRef(
4769
5125
  ({ className, type, ...props }, ref) => {
4770
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
5126
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4771
5127
  "input",
4772
5128
  {
4773
5129
  type,
@@ -4785,11 +5141,11 @@ var Input = React5.forwardRef(
4785
5141
  Input.displayName = "Input";
4786
5142
 
4787
5143
  // src/ui/label.tsx
4788
- var import_radix_ui5 = require("radix-ui");
4789
- var import_jsx_runtime11 = require("react/jsx-runtime");
5144
+ var import_radix_ui6 = require("radix-ui");
5145
+ var import_jsx_runtime16 = require("react/jsx-runtime");
4790
5146
  function Label({ className, ...props }) {
4791
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4792
- import_radix_ui5.Label.Root,
5147
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5148
+ import_radix_ui6.Label.Root,
4793
5149
  {
4794
5150
  "data-slot": "label",
4795
5151
  className: cn("text-sm font-medium leading-5 text-foreground", className),
@@ -4799,9 +5155,9 @@ function Label({ className, ...props }) {
4799
5155
  }
4800
5156
 
4801
5157
  // src/ui/link-modal/UrlOrPageInput.tsx
4802
- var import_jsx_runtime12 = require("react/jsx-runtime");
5158
+ var import_jsx_runtime17 = require("react/jsx-runtime");
4803
5159
  function FieldChevron({ onClick }) {
4804
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5160
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4805
5161
  "button",
4806
5162
  {
4807
5163
  type: "button",
@@ -4809,7 +5165,7 @@ function FieldChevron({ onClick }) {
4809
5165
  onClick,
4810
5166
  "aria-label": "Open page list",
4811
5167
  tabIndex: -1,
4812
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconChevronDown, {})
5168
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconChevronDown, {})
4813
5169
  }
4814
5170
  );
4815
5171
  }
@@ -4848,12 +5204,12 @@ function UrlOrPageInput({
4848
5204
  "data-ohw-link-field flex h-10 w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
4849
5205
  urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
4850
5206
  );
4851
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
4852
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
4853
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "relative w-full", children: [
4854
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
4855
- selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconFile, { className: "text-foreground", "aria-hidden": true }) }) : null,
4856
- readOnly ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5207
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
5208
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
5209
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "relative w-full", children: [
5210
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
5211
+ selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconFile, { className: "text-foreground", "aria-hidden": true }) }) : null,
5212
+ readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4857
5213
  Input,
4858
5214
  {
4859
5215
  ref: inputRef,
@@ -4872,7 +5228,7 @@ function UrlOrPageInput({
4872
5228
  )
4873
5229
  }
4874
5230
  ),
4875
- selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5231
+ selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4876
5232
  "button",
4877
5233
  {
4878
5234
  type: "button",
@@ -4880,26 +5236,26 @@ function UrlOrPageInput({
4880
5236
  onMouseDown: clearSelection,
4881
5237
  "aria-label": "Clear selected page",
4882
5238
  tabIndex: -1,
4883
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconX, { "aria-hidden": true })
5239
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconX, { "aria-hidden": true })
4884
5240
  }
4885
5241
  ) : null,
4886
- !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
5242
+ !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
4887
5243
  ] }),
4888
- dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5244
+ dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4889
5245
  "div",
4890
5246
  {
4891
5247
  "data-ohw-link-page-dropdown": "",
4892
5248
  className: "absolute left-0 right-0 h-20 top-[calc(100%+4px)] z-10 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
4893
5249
  onMouseDown: (e) => e.preventDefault(),
4894
- children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
5250
+ children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4895
5251
  "button",
4896
5252
  {
4897
5253
  type: "button",
4898
5254
  className: "flex h-9 w-full items-center gap-2 border-0 bg-transparent px-3 text-left text-sm leading-5 text-foreground outline-none hover:bg-muted",
4899
5255
  onClick: () => onPageSelect(page),
4900
5256
  children: [
4901
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconFile, { className: "shrink-0", "aria-hidden": true }),
4902
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "truncate", children: page.title })
5257
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconFile, { className: "shrink-0", "aria-hidden": true }),
5258
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "truncate", children: page.title })
4903
5259
  ]
4904
5260
  },
4905
5261
  page.path
@@ -4907,7 +5263,7 @@ function UrlOrPageInput({
4907
5263
  }
4908
5264
  ) : null
4909
5265
  ] }),
4910
- urlError ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
5266
+ urlError ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
4911
5267
  ] });
4912
5268
  }
4913
5269
 
@@ -5075,7 +5431,7 @@ function useLinkModalState({
5075
5431
  }
5076
5432
 
5077
5433
  // src/ui/link-modal/LinkEditorPanel.tsx
5078
- var import_jsx_runtime13 = require("react/jsx-runtime");
5434
+ var import_jsx_runtime18 = require("react/jsx-runtime");
5079
5435
  function LinkEditorPanel({
5080
5436
  open = true,
5081
5437
  mode = "create",
@@ -5099,25 +5455,25 @@ function LinkEditorPanel({
5099
5455
  onSubmit
5100
5456
  });
5101
5457
  const isCancel = state.secondaryLabel === "Cancel";
5102
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
5103
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5458
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
5459
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5104
5460
  "button",
5105
5461
  {
5106
5462
  type: "button",
5107
5463
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
5108
5464
  "aria-label": "Close",
5109
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconX, { "aria-hidden": true })
5465
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconX, { "aria-hidden": true })
5110
5466
  }
5111
5467
  ) }),
5112
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
5113
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
5114
- state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5468
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
5469
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
5470
+ state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5115
5471
  DestinationBreadcrumb,
5116
5472
  {
5117
5473
  pageTitle: state.selectedPage.title,
5118
5474
  sectionLabel: state.selectedSection.label
5119
5475
  }
5120
- ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5476
+ ) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5121
5477
  UrlOrPageInput,
5122
5478
  {
5123
5479
  value: state.searchValue,
@@ -5130,18 +5486,18 @@ function LinkEditorPanel({
5130
5486
  urlError: state.urlError
5131
5487
  }
5132
5488
  ),
5133
- state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
5134
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
5135
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
5136
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconInfo, { className: "shrink-0", "aria-hidden": true }),
5137
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Pick a section this link should scroll to." })
5489
+ state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
5490
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
5491
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
5492
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconInfo, { className: "shrink-0", "aria-hidden": true }),
5493
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "Pick a section this link should scroll to." })
5138
5494
  ] })
5139
5495
  ] }) : null,
5140
- state.showSectionPicker ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
5141
- state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
5496
+ state.showSectionPicker ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
5497
+ state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
5142
5498
  ] }),
5143
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
5144
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5499
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
5500
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5145
5501
  Button,
5146
5502
  {
5147
5503
  type: "button",
@@ -5156,7 +5512,7 @@ function LinkEditorPanel({
5156
5512
  children: state.secondaryLabel
5157
5513
  }
5158
5514
  ),
5159
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5515
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5160
5516
  Button,
5161
5517
  {
5162
5518
  type: "button",
@@ -5175,7 +5531,7 @@ function LinkEditorPanel({
5175
5531
  }
5176
5532
 
5177
5533
  // src/ui/link-modal/LinkPopover.tsx
5178
- var import_jsx_runtime14 = require("react/jsx-runtime");
5534
+ var import_jsx_runtime19 = require("react/jsx-runtime");
5179
5535
  function LinkPopover({
5180
5536
  open = true,
5181
5537
  panelRef,
@@ -5183,14 +5539,14 @@ function LinkPopover({
5183
5539
  onClose,
5184
5540
  ...editorProps
5185
5541
  }) {
5186
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5542
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5187
5543
  Dialog2,
5188
5544
  {
5189
5545
  open,
5190
5546
  onOpenChange: (next) => {
5191
5547
  if (!next) onClose?.();
5192
5548
  },
5193
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5549
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5194
5550
  DialogContent,
5195
5551
  {
5196
5552
  ref: panelRef,
@@ -5200,7 +5556,7 @@ function LinkPopover({
5200
5556
  "data-ohw-bridge": "",
5201
5557
  showCloseButton: false,
5202
5558
  className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
5203
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(LinkEditorPanel, { ...editorProps, open, onClose })
5559
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LinkEditorPanel, { ...editorProps, open, onClose })
5204
5560
  }
5205
5561
  )
5206
5562
  }
@@ -5266,7 +5622,7 @@ function shouldUseDevFixtures() {
5266
5622
  }
5267
5623
 
5268
5624
  // src/ui/badge.tsx
5269
- var import_jsx_runtime15 = require("react/jsx-runtime");
5625
+ var import_jsx_runtime20 = require("react/jsx-runtime");
5270
5626
  var badgeVariants = cva(
5271
5627
  "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",
5272
5628
  {
@@ -5284,12 +5640,13 @@ var badgeVariants = cva(
5284
5640
  }
5285
5641
  );
5286
5642
  function Badge({ className, variant, ...props }) {
5287
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
5643
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
5288
5644
  }
5289
5645
 
5290
5646
  // src/OhhwellsBridge.tsx
5291
- var import_jsx_runtime16 = require("react/jsx-runtime");
5292
- var PRIMARY = "#0885FE";
5647
+ var import_lucide_react3 = require("lucide-react");
5648
+ var import_jsx_runtime21 = require("react/jsx-runtime");
5649
+ var PRIMARY2 = "#0885FE";
5293
5650
  var IMAGE_FADE_MS = 300;
5294
5651
  function runOpacityFade(el, onDone) {
5295
5652
  const anim = el.animate([{ opacity: 0 }, { opacity: 1 }], {
@@ -5462,7 +5819,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
5462
5819
  const root = (0, import_client.createRoot)(container);
5463
5820
  (0, import_react_dom.flushSync)(() => {
5464
5821
  root.render(
5465
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5822
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5466
5823
  SchedulingWidget,
5467
5824
  {
5468
5825
  notifyOnConnect,
@@ -5510,6 +5867,20 @@ function applyLinkHref(el, val) {
5510
5867
  const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
5511
5868
  if (anchor) anchor.setAttribute("href", val);
5512
5869
  }
5870
+ function getEditMeasureEl(editable) {
5871
+ return editable.closest("[data-ohw-href-key]") ?? editable;
5872
+ }
5873
+ function isDragHandleDisabled(el) {
5874
+ const carriers = [
5875
+ el.closest("[data-ohw-href-key]"),
5876
+ el.closest("[data-ohw-editable]")
5877
+ ];
5878
+ return carriers.some((carrier) => {
5879
+ if (!carrier) return false;
5880
+ const raw = carrier.getAttribute("data-ohw-drag-disabled");
5881
+ return raw === "true" || raw === "";
5882
+ });
5883
+ }
5513
5884
  function collectEditableNodes() {
5514
5885
  const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
5515
5886
  if (el.dataset.ohwEditable === "image") {
@@ -5563,12 +5934,49 @@ function getHrefKeyFromElement(el) {
5563
5934
  function isNavbarButton(el) {
5564
5935
  return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
5565
5936
  }
5937
+ function getNavigationItemAnchor(el) {
5938
+ const anchor = el.matches("[data-ohw-href-key]") ? el : el.closest("[data-ohw-href-key]");
5939
+ if (!anchor) return null;
5940
+ if (!anchor.querySelector('[data-ohw-editable="text"]')) return null;
5941
+ return anchor;
5942
+ }
5943
+ function isNavigationItem(el) {
5944
+ return getNavigationItemAnchor(el) !== null;
5945
+ }
5946
+ function getNavigationItemAddHintTarget(anchor) {
5947
+ const items = listNavigationItems();
5948
+ const idx = items.indexOf(anchor);
5949
+ if (idx >= 0 && idx < items.length - 1) return items[idx + 1];
5950
+ return anchor;
5951
+ }
5952
+ function listNavigationItems() {
5953
+ return Array.from(
5954
+ document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
5955
+ ).filter((el) => isNavigationItem(el));
5956
+ }
5957
+ function getNavigationItemReorderState(anchor) {
5958
+ if (isNavbarButton(anchor)) return { key: null, disabled: false };
5959
+ return getReorderHandleStateFromAnchor(anchor);
5960
+ }
5961
+ function getReorderHandleState(el) {
5962
+ const linkEl = el.closest("[data-ohw-href-key]");
5963
+ if (!linkEl || getNavigationItemAnchor(linkEl)) return { key: null, disabled: false };
5964
+ return getReorderHandleStateFromAnchor(linkEl);
5965
+ }
5966
+ function getReorderHandleStateFromAnchor(anchor) {
5967
+ const key = anchor.getAttribute("data-ohw-href-key");
5968
+ if (!key) return { key: null, disabled: false };
5969
+ return { key, disabled: isDragHandleDisabled(anchor) };
5970
+ }
5566
5971
  function clearHrefKeyHover(anchor) {
5567
5972
  anchor.removeAttribute("data-ohw-hovered");
5568
5973
  anchor.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
5569
5974
  el.removeAttribute("data-ohw-hovered");
5570
5975
  });
5571
5976
  }
5977
+ function isInsideNavigationItem(el) {
5978
+ return getNavigationItemAnchor(el) !== null;
5979
+ }
5572
5980
  function collectSections() {
5573
5981
  return collectSectionsFromDom();
5574
5982
  }
@@ -5692,6 +6100,8 @@ var ICONS = {
5692
6100
  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"/>',
5693
6101
  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"/>'
5694
6102
  };
6103
+ var TOOLBAR_PILL_PADDING = 2;
6104
+ var TOOLBAR_TOGGLE_GAP = 4;
5695
6105
  var TOOLBAR_GROUPS = [
5696
6106
  [
5697
6107
  { cmd: "bold", title: "Bold" },
@@ -5709,24 +6119,64 @@ var TOOLBAR_GROUPS = [
5709
6119
  { cmd: "insertOrderedList", title: "Numbered List" }
5710
6120
  ]
5711
6121
  ];
5712
- function GlowFrame({ rect, elRef }) {
6122
+ function EditGlowChrome({
6123
+ rect,
6124
+ elRef,
6125
+ reorderHrefKey,
6126
+ dragDisabled = false
6127
+ }) {
5713
6128
  const GAP = 6;
5714
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6129
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
5715
6130
  "div",
5716
6131
  {
5717
6132
  ref: elRef,
6133
+ "data-ohw-edit-chrome": "",
5718
6134
  style: {
5719
6135
  position: "fixed",
5720
6136
  top: rect.top - GAP,
5721
6137
  left: rect.left - GAP,
5722
6138
  width: rect.width + GAP * 2,
5723
6139
  height: rect.height + GAP * 2,
5724
- border: "2px solid #0885FE",
5725
- borderRadius: 8,
5726
- boxShadow: "0 0 0 4px rgba(8, 133, 254, 0.12)",
5727
6140
  pointerEvents: "none",
5728
6141
  zIndex: 2147483646
5729
- }
6142
+ },
6143
+ children: [
6144
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6145
+ "div",
6146
+ {
6147
+ style: {
6148
+ position: "absolute",
6149
+ inset: 0,
6150
+ border: "2px solid var(--ohw-primary, #0885FE)",
6151
+ borderRadius: 8,
6152
+ boxShadow: "0 0 0 4px rgba(8, 133, 254, 0.12)",
6153
+ pointerEvents: "none"
6154
+ }
6155
+ }
6156
+ ),
6157
+ reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6158
+ "div",
6159
+ {
6160
+ "data-ohw-drag-handle-container": "",
6161
+ "data-ohw-drag-disabled": dragDisabled ? "" : void 0,
6162
+ style: {
6163
+ position: "absolute",
6164
+ left: 0,
6165
+ top: "50%",
6166
+ transform: "translate(calc(-100% - 7px), -50%)",
6167
+ pointerEvents: dragDisabled ? "none" : "auto"
6168
+ },
6169
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6170
+ DragHandle,
6171
+ {
6172
+ "aria-label": `Reorder ${reorderHrefKey}`,
6173
+ disabled: dragDisabled,
6174
+ "aria-disabled": dragDisabled
6175
+ }
6176
+ )
6177
+ }
6178
+ )
6179
+ ]
5730
6180
  }
5731
6181
  );
5732
6182
  }
@@ -5770,9 +6220,9 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
5770
6220
  const pinnedTop = Math.min(maxBottom - approxH, Math.max(minTop, clip.top + gap));
5771
6221
  return { top: pinnedTop + approxH, transform: "translateX(-50%) translateY(-100%)" };
5772
6222
  }
5773
- function calcToolbarPos(rect, parentScroll, approxW = 330) {
6223
+ function calcToolbarPos(rect, parentScroll, approxW = 306) {
5774
6224
  const GAP = 8;
5775
- const APPROX_H = 36;
6225
+ const APPROX_H = 32;
5776
6226
  const APPROX_W = approxW;
5777
6227
  const clip = getIframeVisibleClip(parentScroll);
5778
6228
  const clipTop = clip?.top ?? 0;
@@ -5806,119 +6256,24 @@ function calcToolbarPos(rect, parentScroll, approxW = 330) {
5806
6256
  const left = Math.max(GAP + APPROX_W / 2, Math.min(rawLeft, window.innerWidth - GAP - APPROX_W / 2));
5807
6257
  return { top, left, transform };
5808
6258
  }
5809
- var EDIT_LINK_ICON = /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
5810
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
5811
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
5812
- ] });
6259
+ function resolveItemInteractionState(rect, parentScroll) {
6260
+ const { transform } = calcToolbarPos(rect, parentScroll, 120);
6261
+ return transform.includes("translateY(-100%)") ? "active-top" : "active-bottom";
6262
+ }
5813
6263
  function FloatingToolbar({
5814
6264
  rect,
5815
6265
  parentScroll,
5816
6266
  elRef,
5817
- variant = "rich-text",
5818
6267
  onCommand,
5819
6268
  activeCommands,
5820
6269
  showEditLink,
5821
6270
  onEditLink
5822
6271
  }) {
5823
- const approxW = variant === "link-action" ? 120 : 330;
5824
- const { top, left, transform } = calcToolbarPos(rect, parentScroll, approxW);
5825
- if (variant === "link-action") {
5826
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
5827
- "div",
5828
- {
5829
- ref: elRef,
5830
- "data-ohw-toolbar": "",
5831
- style: {
5832
- position: "fixed",
5833
- top,
5834
- left,
5835
- transform,
5836
- zIndex: 2147483647,
5837
- background: "#fff",
5838
- border: "1px solid #E7E5E4",
5839
- borderRadius: 6,
5840
- boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
5841
- display: "flex",
5842
- alignItems: "center",
5843
- padding: 4,
5844
- gap: 6,
5845
- fontFamily: "sans-serif",
5846
- pointerEvents: "auto",
5847
- whiteSpace: "nowrap"
5848
- },
5849
- onMouseDown: (e) => e.stopPropagation(),
5850
- children: [
5851
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5852
- "button",
5853
- {
5854
- type: "button",
5855
- title: "Edit link",
5856
- onMouseDown: (e) => {
5857
- e.preventDefault();
5858
- e.stopPropagation();
5859
- onEditLink?.();
5860
- },
5861
- onClick: (e) => {
5862
- e.preventDefault();
5863
- e.stopPropagation();
5864
- },
5865
- onMouseEnter: (e) => {
5866
- e.currentTarget.style.background = "#F5F5F4";
5867
- },
5868
- onMouseLeave: (e) => {
5869
- e.currentTarget.style.background = "transparent";
5870
- },
5871
- style: {
5872
- display: "flex",
5873
- alignItems: "center",
5874
- justifyContent: "center",
5875
- border: "none",
5876
- background: "transparent",
5877
- borderRadius: 4,
5878
- cursor: "pointer",
5879
- color: "#1C1917",
5880
- flexShrink: 0,
5881
- padding: 6
5882
- },
5883
- children: EDIT_LINK_ICON
5884
- }
5885
- ),
5886
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { display: "block", width: 1, height: 24, background: "#E7E5E4", flexShrink: 0 } }),
5887
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5888
- "button",
5889
- {
5890
- type: "button",
5891
- title: "Coming soon",
5892
- disabled: true,
5893
- style: {
5894
- display: "flex",
5895
- alignItems: "center",
5896
- justifyContent: "center",
5897
- border: "none",
5898
- background: "transparent",
5899
- borderRadius: 4,
5900
- cursor: "not-allowed",
5901
- color: "#A8A29E",
5902
- flexShrink: 0,
5903
- padding: 6,
5904
- opacity: 0.6
5905
- },
5906
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: [
5907
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "5", cy: "12", r: "1.5" }),
5908
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "12", cy: "12", r: "1.5" }),
5909
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "19", cy: "12", r: "1.5" })
5910
- ] })
5911
- }
5912
- )
5913
- ]
5914
- }
5915
- );
5916
- }
5917
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
6272
+ const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
6273
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5918
6274
  "div",
5919
6275
  {
5920
6276
  ref: elRef,
5921
- "data-ohw-toolbar": "",
5922
6277
  style: {
5923
6278
  position: "fixed",
5924
6279
  top,
@@ -5931,57 +6286,39 @@ function FloatingToolbar({
5931
6286
  boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
5932
6287
  display: "flex",
5933
6288
  alignItems: "center",
5934
- padding: 4,
5935
- gap: 6,
6289
+ padding: TOOLBAR_PILL_PADDING,
6290
+ gap: TOOLBAR_TOGGLE_GAP,
5936
6291
  fontFamily: "sans-serif",
5937
- pointerEvents: "auto",
5938
- whiteSpace: "nowrap"
6292
+ pointerEvents: "auto"
5939
6293
  },
5940
- onMouseDown: (e) => e.stopPropagation(),
5941
- children: [
5942
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react6.default.Fragment, { children: [
5943
- gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { display: "block", width: 1, height: 24, background: "#E7E5E4", flexShrink: 0 } }),
6294
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(CustomToolbar, { children: [
6295
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react6.default.Fragment, { children: [
6296
+ gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CustomToolbarDivider, {}),
5944
6297
  btns.map((btn) => {
5945
6298
  const isActive = activeCommands.has(btn.cmd);
5946
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5947
- "button",
6299
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6300
+ CustomToolbarButton,
5948
6301
  {
5949
6302
  title: btn.title,
6303
+ active: isActive,
5950
6304
  onMouseDown: (e) => {
5951
6305
  e.preventDefault();
5952
6306
  onCommand(btn.cmd);
5953
6307
  },
5954
- onMouseEnter: (e) => {
5955
- if (!isActive) e.currentTarget.style.background = "#F5F5F4";
5956
- },
5957
- onMouseLeave: (e) => {
5958
- if (!isActive) e.currentTarget.style.background = "transparent";
5959
- },
5960
- style: {
5961
- display: "flex",
5962
- alignItems: "center",
5963
- justifyContent: "center",
5964
- border: "none",
5965
- background: isActive ? PRIMARY : "transparent",
5966
- borderRadius: 4,
5967
- cursor: "pointer",
5968
- color: isActive ? "#FFFFFF" : "#1C1917",
5969
- flexShrink: 0,
5970
- padding: 6
5971
- },
5972
- children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6308
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5973
6309
  "svg",
5974
6310
  {
5975
6311
  width: "16",
5976
6312
  height: "16",
5977
6313
  viewBox: "0 0 24 24",
5978
6314
  fill: "none",
5979
- stroke: isActive ? "#FFFFFF" : "#1C1917",
6315
+ stroke: "currentColor",
5980
6316
  strokeWidth: "2.5",
5981
6317
  strokeLinecap: "round",
5982
6318
  strokeLinejoin: "round",
5983
- style: isActive && gi > 0 ? { filter: "drop-shadow(0 0 0.5px #fff)" } : void 0,
5984
- dangerouslySetInnerHTML: { __html: ICONS[btn.cmd] }
6319
+ style: isActive && gi > 0 ? { filter: "drop-shadow(0 0 0.5px currentColor)" } : void 0,
6320
+ dangerouslySetInnerHTML: { __html: ICONS[btn.cmd] },
6321
+ "aria-hidden": true
5985
6322
  }
5986
6323
  )
5987
6324
  },
@@ -5989,8 +6326,8 @@ function FloatingToolbar({
5989
6326
  );
5990
6327
  })
5991
6328
  ] }, gi)),
5992
- showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5993
- "button",
6329
+ showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6330
+ CustomToolbarButton,
5994
6331
  {
5995
6332
  type: "button",
5996
6333
  title: "Edit link",
@@ -6003,28 +6340,10 @@ function FloatingToolbar({
6003
6340
  e.preventDefault();
6004
6341
  e.stopPropagation();
6005
6342
  },
6006
- onMouseEnter: (e) => {
6007
- e.currentTarget.style.background = "#F5F5F4";
6008
- },
6009
- onMouseLeave: (e) => {
6010
- e.currentTarget.style.background = "transparent";
6011
- },
6012
- style: {
6013
- display: "flex",
6014
- alignItems: "center",
6015
- justifyContent: "center",
6016
- border: "none",
6017
- background: "transparent",
6018
- borderRadius: 4,
6019
- cursor: "pointer",
6020
- color: "#1C1917",
6021
- flexShrink: 0,
6022
- padding: 6
6023
- },
6024
- children: EDIT_LINK_ICON
6343
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react3.Link, { className: "size-4 shrink-0", "aria-hidden": true })
6025
6344
  }
6026
6345
  ) : null
6027
- ]
6346
+ ] })
6028
6347
  }
6029
6348
  );
6030
6349
  }
@@ -6038,7 +6357,7 @@ function StateToggle({
6038
6357
  states,
6039
6358
  onStateChange
6040
6359
  }) {
6041
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
6360
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6042
6361
  ToggleGroup,
6043
6362
  {
6044
6363
  "data-ohw-state-toggle": "",
@@ -6052,7 +6371,7 @@ function StateToggle({
6052
6371
  left: rect.right - 8,
6053
6372
  transform: "translateX(-100%)"
6054
6373
  },
6055
- children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
6374
+ children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
6056
6375
  }
6057
6376
  );
6058
6377
  }
@@ -6140,6 +6459,10 @@ function OhhwellsBridge() {
6140
6459
  });
6141
6460
  const deselectRef = (0, import_react6.useRef)(() => {
6142
6461
  });
6462
+ const reselectNavigationItemRef = (0, import_react6.useRef)(() => {
6463
+ });
6464
+ const commitNavigationTextEditRef = (0, import_react6.useRef)(() => {
6465
+ });
6143
6466
  const refreshActiveCommandsRef = (0, import_react6.useRef)(() => {
6144
6467
  });
6145
6468
  const postToParentRef = (0, import_react6.useRef)(postToParent);
@@ -6150,11 +6473,18 @@ function OhhwellsBridge() {
6150
6473
  const [toolbarVariant, setToolbarVariant] = (0, import_react6.useState)("none");
6151
6474
  const toolbarVariantRef = (0, import_react6.useRef)("none");
6152
6475
  toolbarVariantRef.current = toolbarVariant;
6476
+ const [reorderHrefKey, setReorderHrefKey] = (0, import_react6.useState)(null);
6477
+ const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react6.useState)(false);
6153
6478
  const [toggleState, setToggleState] = (0, import_react6.useState)(null);
6154
6479
  const [maxBadge, setMaxBadge] = (0, import_react6.useState)(null);
6155
6480
  const [activeCommands, setActiveCommands] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
6156
6481
  const [sectionGap, setSectionGap] = (0, import_react6.useState)(null);
6157
6482
  const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react6.useState)(false);
6483
+ const hoveredItemElRef = (0, import_react6.useRef)(null);
6484
+ const [hoveredItemRect, setHoveredItemRect] = (0, import_react6.useState)(null);
6485
+ const siblingHintElRef = (0, import_react6.useRef)(null);
6486
+ const [siblingHintRect, setSiblingHintRect] = (0, import_react6.useState)(null);
6487
+ const [isItemDragging, setIsItemDragging] = (0, import_react6.useState)(false);
6158
6488
  const [linkPopover, setLinkPopover] = (0, import_react6.useState)(null);
6159
6489
  const [sitePages, setSitePages] = (0, import_react6.useState)([]);
6160
6490
  const [sectionsByPath, setSectionsByPath] = (0, import_react6.useState)({});
@@ -6256,7 +6586,7 @@ function OhhwellsBridge() {
6256
6586
  (0, import_react6.useEffect)(() => {
6257
6587
  const update = () => {
6258
6588
  const el = activeElRef.current ?? selectedElRef.current;
6259
- if (el) setToolbarRect(el.getBoundingClientRect());
6589
+ if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
6260
6590
  setToggleState((prev) => {
6261
6591
  if (!prev || !activeStateElRef.current) return prev;
6262
6592
  return { ...prev, rect: activeStateElRef.current.getBoundingClientRect() };
@@ -6323,6 +6653,8 @@ function OhhwellsBridge() {
6323
6653
  }
6324
6654
  el.removeAttribute("contenteditable");
6325
6655
  activeElRef.current = null;
6656
+ setReorderHrefKey(null);
6657
+ setReorderDragDisabled(false);
6326
6658
  if (!selectedElRef.current) {
6327
6659
  setToolbarRect(null);
6328
6660
  setToolbarVariant("none");
@@ -6334,16 +6666,82 @@ function OhhwellsBridge() {
6334
6666
  }, [postToParent]);
6335
6667
  const deselect = (0, import_react6.useCallback)(() => {
6336
6668
  selectedElRef.current = null;
6669
+ setReorderHrefKey(null);
6670
+ setReorderDragDisabled(false);
6671
+ siblingHintElRef.current = null;
6672
+ setSiblingHintRect(null);
6673
+ setIsItemDragging(false);
6337
6674
  if (!activeElRef.current) {
6338
6675
  setToolbarRect(null);
6339
6676
  setToolbarVariant("none");
6340
6677
  }
6341
6678
  }, []);
6679
+ const reselectNavigationItem = (0, import_react6.useCallback)((navAnchor) => {
6680
+ selectedElRef.current = navAnchor;
6681
+ const { key, disabled } = getNavigationItemReorderState(navAnchor);
6682
+ setReorderHrefKey(key);
6683
+ setReorderDragDisabled(disabled);
6684
+ setToolbarVariant("link-action");
6685
+ setToolbarRect(navAnchor.getBoundingClientRect());
6686
+ setToolbarShowEditLink(false);
6687
+ setActiveCommands(/* @__PURE__ */ new Set());
6688
+ }, []);
6689
+ const commitNavigationTextEdit = (0, import_react6.useCallback)((navAnchor) => {
6690
+ const el = activeElRef.current;
6691
+ if (!el) return;
6692
+ const key = el.dataset.ohwKey;
6693
+ if (key) {
6694
+ const timer = autoSaveTimers.current.get(key);
6695
+ if (timer !== void 0) {
6696
+ clearTimeout(timer);
6697
+ autoSaveTimers.current.delete(key);
6698
+ }
6699
+ const html = sanitizeHtml(el.innerHTML);
6700
+ const original = originalContentRef.current ?? "";
6701
+ if (html !== sanitizeHtml(original)) {
6702
+ postToParent({ type: "ow:change", nodes: [{ key, text: html }] });
6703
+ const h = document.documentElement.scrollHeight;
6704
+ if (h > 50) postToParent({ type: "ow:height", height: h });
6705
+ }
6706
+ }
6707
+ el.removeAttribute("contenteditable");
6708
+ activeElRef.current = null;
6709
+ setMaxBadge(null);
6710
+ setActiveCommands(/* @__PURE__ */ new Set());
6711
+ setToolbarShowEditLink(false);
6712
+ postToParent({ type: "ow:exit-edit" });
6713
+ reselectNavigationItem(navAnchor);
6714
+ }, [postToParent, reselectNavigationItem]);
6715
+ const handleAddNavigationItem = (0, import_react6.useCallback)(() => {
6716
+ const selected = selectedElRef.current;
6717
+ if (!selected) return;
6718
+ const target = getNavigationItemAddHintTarget(selected);
6719
+ siblingHintElRef.current = target;
6720
+ setSiblingHintRect(target.getBoundingClientRect());
6721
+ }, []);
6722
+ const handleItemDragStart = (0, import_react6.useCallback)(() => {
6723
+ siblingHintElRef.current = null;
6724
+ setSiblingHintRect(null);
6725
+ setIsItemDragging(true);
6726
+ }, []);
6727
+ const handleItemDragEnd = (0, import_react6.useCallback)(() => {
6728
+ setIsItemDragging(false);
6729
+ }, []);
6730
+ reselectNavigationItemRef.current = reselectNavigationItem;
6731
+ commitNavigationTextEditRef.current = commitNavigationTextEdit;
6342
6732
  const select = (0, import_react6.useCallback)((anchor) => {
6343
- if (!isNavbarButton(anchor)) return;
6733
+ if (!isNavigationItem(anchor)) return;
6344
6734
  if (activeElRef.current) deactivate();
6345
6735
  selectedElRef.current = anchor;
6346
6736
  clearHrefKeyHover(anchor);
6737
+ setHoveredItemRect(null);
6738
+ hoveredItemElRef.current = null;
6739
+ siblingHintElRef.current = null;
6740
+ setSiblingHintRect(null);
6741
+ setIsItemDragging(false);
6742
+ const { key, disabled } = getNavigationItemReorderState(anchor);
6743
+ setReorderHrefKey(key);
6744
+ setReorderDragDisabled(disabled);
6347
6745
  setToolbarVariant("link-action");
6348
6746
  setToolbarRect(anchor.getBoundingClientRect());
6349
6747
  setToolbarShowEditLink(false);
@@ -6358,13 +6756,26 @@ function OhhwellsBridge() {
6358
6756
  postToParentRef.current({ type: "ow:image-unhover" });
6359
6757
  }
6360
6758
  setToolbarVariant("rich-text");
6759
+ siblingHintElRef.current = null;
6760
+ setSiblingHintRect(null);
6761
+ setIsItemDragging(false);
6361
6762
  el.setAttribute("contenteditable", "true");
6362
6763
  el.removeAttribute("data-ohw-hovered");
6764
+ el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
6363
6765
  activeElRef.current = el;
6364
6766
  originalContentRef.current = el.innerHTML;
6365
6767
  el.focus();
6366
- setToolbarRect(el.getBoundingClientRect());
6367
6768
  setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
6769
+ const navAnchor = getNavigationItemAnchor(el);
6770
+ if (navAnchor) {
6771
+ setReorderHrefKey(null);
6772
+ setReorderDragDisabled(false);
6773
+ } else {
6774
+ const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
6775
+ setReorderHrefKey(reorderKey);
6776
+ setReorderDragDisabled(reorderDisabled);
6777
+ }
6778
+ setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
6368
6779
  postToParent({ type: "ow:enter-edit", key: el.dataset.ohwKey });
6369
6780
  requestAnimationFrame(() => refreshActiveCommandsRef.current());
6370
6781
  }, [deactivate, postToParent]);
@@ -6429,7 +6840,7 @@ function OhhwellsBridge() {
6429
6840
  return () => {
6430
6841
  cancelled = true;
6431
6842
  };
6432
- }, [subdomain, isEditMode, pathname]);
6843
+ }, [subdomain, isEditMode]);
6433
6844
  (0, import_react6.useEffect)(() => {
6434
6845
  if (!subdomain || isEditMode) return;
6435
6846
  let debounceTimer = null;
@@ -6466,7 +6877,7 @@ function OhhwellsBridge() {
6466
6877
  if (debounceTimer) clearTimeout(debounceTimer);
6467
6878
  debounceTimer = setTimeout(applyFromCache, 150);
6468
6879
  };
6469
- scheduleApply();
6880
+ applyFromCache();
6470
6881
  observer = new MutationObserver(scheduleApply);
6471
6882
  observer.observe(document.body, { childList: true, subtree: true });
6472
6883
  return () => {
@@ -6556,18 +6967,25 @@ function OhhwellsBridge() {
6556
6967
  [data-ohw-editable="image"], [data-ohw-editable="image"] *,
6557
6968
  [data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
6558
6969
  [data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
6559
- [data-ohw-hovered]:not([contenteditable]) {
6560
- outline: 2px dashed ${PRIMARY} !important;
6970
+ [data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
6971
+ outline: 2px dashed ${PRIMARY2} !important;
6561
6972
  outline-offset: 4px;
6562
6973
  border-radius: 2px;
6563
6974
  }
6975
+ [data-ohw-href-key] [data-ohw-hovered],
6976
+ [data-ohw-href-key][data-ohw-hovered],
6977
+ nav [data-ohw-href-key] [data-ohw-hovered],
6978
+ footer [data-ohw-href-key] [data-ohw-hovered] {
6979
+ outline: none !important;
6980
+ outline-offset: 0 !important;
6981
+ }
6564
6982
  [data-ohw-editable][contenteditable] {
6565
6983
  outline: none !important;
6566
- caret-color: ${PRIMARY};
6984
+ caret-color: ${PRIMARY2};
6567
6985
  cursor: text !important;
6568
6986
  }
6569
6987
  [data-ohw-editable][contenteditable]::selection,
6570
- [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY}59 !important; }
6988
+ [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY2}59 !important; }
6571
6989
  [data-ohw-editable-state], [data-ohw-editable-state] * { pointer-events: none !important; }
6572
6990
  [data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
6573
6991
  [data-ohw-editable-state][data-ohw-active-state][data-ohw-editable] { pointer-events: auto !important; }
@@ -6579,7 +6997,7 @@ function OhhwellsBridge() {
6579
6997
  stateViews.textContent = `
6580
6998
  [data-ohw-state-view]:not([data-ohw-state-view="default"]) { display: none; }
6581
6999
  [data-ohw-state-view="default"] [data-ohw-editable] { pointer-events: auto !important; }
6582
- [data-ohw-state-hovered] { outline: 2px dashed ${PRIMARY} !important; outline-offset: 4px; border-radius: 2px; }
7000
+ [data-ohw-state-hovered] { outline: 2px dashed ${PRIMARY2} !important; outline-offset: 4px; border-radius: 2px; }
6583
7001
  [data-ohw-state-hovered]:has([data-ohw-hovered]) { outline: none !important; }
6584
7002
  `;
6585
7003
  document.head.appendChild(base);
@@ -6594,6 +7012,11 @@ function OhhwellsBridge() {
6594
7012
  if (target.closest("[data-ohw-state-toggle]")) return;
6595
7013
  if (target.closest("[data-ohw-max-badge]")) return;
6596
7014
  if (isInsideLinkEditor(target)) return;
7015
+ if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
7016
+ e.preventDefault();
7017
+ e.stopPropagation();
7018
+ return;
7019
+ }
6597
7020
  const editable = target.closest("[data-ohw-editable]");
6598
7021
  if (editable) {
6599
7022
  if (editable.dataset.ohwEditable === "link") {
@@ -6615,15 +7038,15 @@ function OhhwellsBridge() {
6615
7038
  return;
6616
7039
  }
6617
7040
  const hrefCtx = getHrefKeyFromElement(editable);
6618
- if (hrefCtx && isNavbarButton(hrefCtx.anchor)) {
7041
+ const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
7042
+ if (navAnchor) {
6619
7043
  e.preventDefault();
6620
7044
  e.stopPropagation();
6621
- const { anchor: anchor2 } = hrefCtx;
6622
- if (selectedElRef.current === anchor2) {
7045
+ if (selectedElRef.current === navAnchor) {
6623
7046
  activateRef.current(editable);
6624
7047
  return;
6625
7048
  }
6626
- selectRef.current(anchor2);
7049
+ selectRef.current(navAnchor);
6627
7050
  return;
6628
7051
  }
6629
7052
  e.preventDefault();
@@ -6631,8 +7054,8 @@ function OhhwellsBridge() {
6631
7054
  activateRef.current(editable);
6632
7055
  return;
6633
7056
  }
6634
- const hrefAnchor = target.closest("[data-ohw-href-key]");
6635
- if (hrefAnchor && isNavbarButton(hrefAnchor)) {
7057
+ const hrefAnchor = getNavigationItemAnchor(target);
7058
+ if (hrefAnchor) {
6636
7059
  e.preventDefault();
6637
7060
  e.stopPropagation();
6638
7061
  if (selectedElRef.current === hrefAnchor) return;
@@ -6665,19 +7088,58 @@ function OhhwellsBridge() {
6665
7088
  deactivateRef.current();
6666
7089
  };
6667
7090
  const handleMouseOver = (e) => {
6668
- const editable = e.target.closest("[data-ohw-editable]");
7091
+ const target = e.target;
7092
+ const navAnchor = getNavigationItemAnchor(target);
7093
+ if (navAnchor) {
7094
+ const selected2 = selectedElRef.current;
7095
+ if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
7096
+ clearHrefKeyHover(navAnchor);
7097
+ hoveredItemElRef.current = navAnchor;
7098
+ setHoveredItemRect(navAnchor.getBoundingClientRect());
7099
+ return;
7100
+ }
7101
+ const editable = target.closest("[data-ohw-editable]");
6669
7102
  if (!editable) return;
6670
7103
  const selected = selectedElRef.current;
6671
7104
  if (selected && (selected === editable || selected.contains(editable))) return;
6672
7105
  if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image" && !editable.hasAttribute("contenteditable")) {
6673
- editable.setAttribute("data-ohw-hovered", "");
7106
+ const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
7107
+ if (hoverTarget.hasAttribute("data-ohw-href-key")) {
7108
+ clearHrefKeyHover(hoverTarget);
7109
+ hoveredItemElRef.current = hoverTarget;
7110
+ setHoveredItemRect(hoverTarget.getBoundingClientRect());
7111
+ } else if (!isInsideNavigationItem(editable)) {
7112
+ hoverTarget.setAttribute("data-ohw-hovered", "");
7113
+ }
6674
7114
  }
6675
7115
  };
6676
7116
  const handleMouseOut = (e) => {
6677
- const editable = e.target.closest("[data-ohw-editable]");
7117
+ const target = e.target;
7118
+ const navAnchor = getNavigationItemAnchor(target);
7119
+ if (navAnchor) {
7120
+ const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
7121
+ if (related2?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
7122
+ if (related2 && navAnchor.contains(related2)) return;
7123
+ if (hoveredItemElRef.current === navAnchor) {
7124
+ hoveredItemElRef.current = null;
7125
+ setHoveredItemRect(null);
7126
+ }
7127
+ return;
7128
+ }
7129
+ const editable = target.closest("[data-ohw-editable]");
6678
7130
  if (!editable) return;
7131
+ const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
7132
+ if (related?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
6679
7133
  if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image") {
6680
- editable.removeAttribute("data-ohw-hovered");
7134
+ const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
7135
+ if (hoverTarget.hasAttribute("data-ohw-href-key")) {
7136
+ if (!related?.closest("[data-ohw-href-key]")) {
7137
+ hoveredItemElRef.current = null;
7138
+ setHoveredItemRect(null);
7139
+ }
7140
+ } else {
7141
+ hoverTarget.removeAttribute("data-ohw-hovered");
7142
+ }
6681
7143
  }
6682
7144
  };
6683
7145
  const toProbeCoords = (clientX, clientY, fromParentViewport) => {
@@ -6792,11 +7254,20 @@ function OhhwellsBridge() {
6792
7254
  return;
6793
7255
  }
6794
7256
  }
7257
+ if (activeElRef.current) {
7258
+ if (hoveredImageRef.current) {
7259
+ hoveredImageRef.current = null;
7260
+ hoveredImageHasTextOverlapRef.current = false;
7261
+ resumeAnimTracks();
7262
+ postToParentRef.current({ type: "ow:image-unhover" });
7263
+ }
7264
+ return;
7265
+ }
6795
7266
  const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
6796
7267
  if (imgEl) {
6797
7268
  const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
6798
7269
  const topEl = document.elementFromPoint(x, y);
6799
- if (topEl?.closest("[data-ohw-toolbar]")) {
7270
+ if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
6800
7271
  if (hoveredImageRef.current) {
6801
7272
  hoveredImageRef.current = null;
6802
7273
  resumeAnimTracks();
@@ -6844,7 +7315,9 @@ function OhhwellsBridge() {
6844
7315
  postImageHover(imgEl, isDragOver, true);
6845
7316
  }
6846
7317
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
6847
- textEditable.setAttribute("data-ohw-hovered", "");
7318
+ if (textEditable && !isInsideNavigationItem(textEditable)) {
7319
+ textEditable.setAttribute("data-ohw-hovered", "");
7320
+ }
6848
7321
  return;
6849
7322
  }
6850
7323
  if (hoveredImageRef.current) {
@@ -6854,7 +7327,9 @@ function OhhwellsBridge() {
6854
7327
  postToParentRef.current({ type: "ow:image-unhover" });
6855
7328
  }
6856
7329
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
6857
- textEditable.setAttribute("data-ohw-hovered", "");
7330
+ if (textEditable && !isInsideNavigationItem(textEditable)) {
7331
+ textEditable.setAttribute("data-ohw-hovered", "");
7332
+ }
6858
7333
  return;
6859
7334
  }
6860
7335
  if (hoveredGapRef.current) {
@@ -6898,7 +7373,24 @@ function OhhwellsBridge() {
6898
7373
  return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
6899
7374
  });
6900
7375
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
6901
- if (textEl && !textEl.hasAttribute("contenteditable")) textEl.setAttribute("data-ohw-hovered", "");
7376
+ if (textEl && !textEl.hasAttribute("contenteditable")) {
7377
+ const navAnchor = getNavigationItemAnchor(textEl);
7378
+ if (navAnchor) {
7379
+ const selected = selectedElRef.current;
7380
+ if (selected !== navAnchor && !selected?.contains(navAnchor)) {
7381
+ clearHrefKeyHover(navAnchor);
7382
+ hoveredItemElRef.current = navAnchor;
7383
+ setHoveredItemRect(navAnchor.getBoundingClientRect());
7384
+ }
7385
+ } else {
7386
+ hoveredItemElRef.current = null;
7387
+ setHoveredItemRect(null);
7388
+ textEl.setAttribute("data-ohw-hovered", "");
7389
+ }
7390
+ } else {
7391
+ hoveredItemElRef.current = null;
7392
+ setHoveredItemRect(null);
7393
+ }
6902
7394
  }
6903
7395
  };
6904
7396
  const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
@@ -7089,7 +7581,7 @@ function OhhwellsBridge() {
7089
7581
  const el = e.target;
7090
7582
  const key = el.dataset.ohwKey;
7091
7583
  if (!key) return;
7092
- if (el === activeElRef.current) setToolbarRect(el.getBoundingClientRect());
7584
+ if (el === activeElRef.current) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
7093
7585
  const maxLen = el.dataset.ohwMaxLength ? parseInt(el.dataset.ohwMaxLength, 10) : null;
7094
7586
  if (maxLen) {
7095
7587
  const current = el.innerText.replace(/\n$/, "").length;
@@ -7176,6 +7668,33 @@ function OhhwellsBridge() {
7176
7668
  deselectRef.current();
7177
7669
  return;
7178
7670
  }
7671
+ if (e.key === "Escape" && activeElRef.current) {
7672
+ const hrefCtx = getHrefKeyFromElement(activeElRef.current);
7673
+ const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
7674
+ if (navAnchor) {
7675
+ e.preventDefault();
7676
+ const el2 = activeElRef.current;
7677
+ if (originalContentRef.current !== null) {
7678
+ el2.innerHTML = originalContentRef.current;
7679
+ }
7680
+ el2.removeAttribute("contenteditable");
7681
+ activeElRef.current = null;
7682
+ setMaxBadge(null);
7683
+ setActiveCommands(/* @__PURE__ */ new Set());
7684
+ setToolbarShowEditLink(false);
7685
+ postToParentRef.current({ type: "ow:exit-edit" });
7686
+ reselectNavigationItemRef.current(navAnchor);
7687
+ return;
7688
+ }
7689
+ }
7690
+ if (e.key === "Enter" && !e.shiftKey && activeElRef.current) {
7691
+ const navAnchor = getNavigationItemAnchor(activeElRef.current);
7692
+ if (navAnchor) {
7693
+ e.preventDefault();
7694
+ commitNavigationTextEditRef.current(navAnchor);
7695
+ return;
7696
+ }
7697
+ }
7179
7698
  if (e.key !== "Escape") return;
7180
7699
  const el = activeElRef.current;
7181
7700
  if (el && originalContentRef.current !== null) {
@@ -7191,7 +7710,8 @@ function OhhwellsBridge() {
7191
7710
  const handleScroll = () => {
7192
7711
  const focusEl = activeElRef.current ?? selectedElRef.current;
7193
7712
  if (focusEl) {
7194
- const r2 = focusEl.getBoundingClientRect();
7713
+ const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
7714
+ const r2 = measureEl.getBoundingClientRect();
7195
7715
  applyToolbarPos(r2);
7196
7716
  setToolbarRect(r2);
7197
7717
  setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
@@ -7200,6 +7720,12 @@ function OhhwellsBridge() {
7200
7720
  const rect = activeStateElRef.current.getBoundingClientRect();
7201
7721
  setToggleState((prev) => prev ? { ...prev, rect } : null);
7202
7722
  }
7723
+ if (hoveredItemElRef.current) {
7724
+ setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
7725
+ }
7726
+ if (siblingHintElRef.current) {
7727
+ setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
7728
+ }
7203
7729
  if (hoveredImageRef.current) {
7204
7730
  const el = hoveredImageRef.current;
7205
7731
  const r2 = el.getBoundingClientRect();
@@ -7319,7 +7845,7 @@ function OhhwellsBridge() {
7319
7845
  };
7320
7846
  const applyToolbarPos = (rect) => {
7321
7847
  const ps = parentScrollRef.current;
7322
- const approxW = toolbarVariantRef.current === "link-action" ? 120 : 330;
7848
+ const approxW = 330;
7323
7849
  if (toolbarElRef.current) {
7324
7850
  const { top, left, transform } = calcToolbarPos(rect, ps, approxW);
7325
7851
  toolbarElRef.current.style.top = `${top}px`;
@@ -7330,6 +7856,8 @@ function OhhwellsBridge() {
7330
7856
  const GAP = 6;
7331
7857
  glowElRef.current.style.top = `${rect.top - GAP}px`;
7332
7858
  glowElRef.current.style.left = `${rect.left - GAP}px`;
7859
+ glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
7860
+ glowElRef.current.style.height = `${rect.height + GAP * 2}px`;
7333
7861
  }
7334
7862
  };
7335
7863
  const handleParentScroll = (e) => {
@@ -7340,7 +7868,10 @@ function OhhwellsBridge() {
7340
7868
  applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
7341
7869
  }
7342
7870
  const focusEl = activeElRef.current ?? selectedElRef.current;
7343
- if (focusEl) applyToolbarPos(focusEl.getBoundingClientRect());
7871
+ if (focusEl) {
7872
+ const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
7873
+ applyToolbarPos(measureEl.getBoundingClientRect());
7874
+ }
7344
7875
  };
7345
7876
  const handleClickAt = (e) => {
7346
7877
  if (e.data?.type !== "ow:click-at") return;
@@ -7498,7 +8029,7 @@ function OhhwellsBridge() {
7498
8029
  const handleCommand = (0, import_react6.useCallback)((cmd) => {
7499
8030
  document.execCommand(cmd, false);
7500
8031
  activeElRef.current?.focus();
7501
- if (activeElRef.current) setToolbarRect(activeElRef.current.getBoundingClientRect());
8032
+ if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
7502
8033
  refreshActiveCommandsRef.current();
7503
8034
  }, []);
7504
8035
  const handleStateChange = (0, import_react6.useCallback)((state) => {
@@ -7551,37 +8082,55 @@ function OhhwellsBridge() {
7551
8082
  const currentSections = sectionsByPath[pathname] ?? [];
7552
8083
  linkPopoverOpenRef.current = linkPopover !== null;
7553
8084
  return bridgeRoot ? (0, import_react_dom2.createPortal)(
7554
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
7555
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
7556
- toolbarRect && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
7557
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(GlowFrame, { rect: toolbarRect, elRef: glowElRef }),
7558
- toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
7559
- FloatingToolbar,
8085
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
8086
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
8087
+ siblingHintRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
8088
+ hoveredItemRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
8089
+ toolbarRect && toolbarVariant === "link-action" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
8090
+ ItemInteractionLayer,
8091
+ {
8092
+ rect: toolbarRect,
8093
+ elRef: glowElRef,
8094
+ state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
8095
+ showHandle: Boolean(reorderHrefKey),
8096
+ dragDisabled: reorderDragDisabled,
8097
+ dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
8098
+ onDragHandleDragStart: handleItemDragStart,
8099
+ onDragHandleDragEnd: handleItemDragEnd,
8100
+ toolbar: isItemDragging ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
8101
+ ItemActionToolbar,
8102
+ {
8103
+ onEditLink: openLinkPopoverForSelected,
8104
+ onAddItem: handleAddNavigationItem,
8105
+ addItemDisabled: false
8106
+ }
8107
+ )
8108
+ }
8109
+ ),
8110
+ toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
8111
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
8112
+ EditGlowChrome,
7560
8113
  {
7561
- variant: "rich-text",
7562
8114
  rect: toolbarRect,
7563
- parentScroll: parentScrollRef.current,
7564
- elRef: toolbarElRef,
7565
- onCommand: handleCommand,
7566
- activeCommands,
7567
- showEditLink,
7568
- onEditLink: openLinkPopoverForActive
8115
+ elRef: glowElRef,
8116
+ reorderHrefKey,
8117
+ dragDisabled: reorderDragDisabled
7569
8118
  }
7570
8119
  ),
7571
- toolbarVariant === "link-action" && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8120
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7572
8121
  FloatingToolbar,
7573
8122
  {
7574
- variant: "link-action",
7575
8123
  rect: toolbarRect,
7576
8124
  parentScroll: parentScrollRef.current,
7577
8125
  elRef: toolbarElRef,
7578
8126
  onCommand: handleCommand,
7579
8127
  activeCommands,
7580
- onEditLink: openLinkPopoverForSelected
8128
+ showEditLink,
8129
+ onEditLink: openLinkPopoverForActive
7581
8130
  }
7582
8131
  )
7583
8132
  ] }),
7584
- maxBadge && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8133
+ maxBadge && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
7585
8134
  "div",
7586
8135
  {
7587
8136
  "data-ohw-max-badge": "",
@@ -7607,7 +8156,7 @@ function OhhwellsBridge() {
7607
8156
  ]
7608
8157
  }
7609
8158
  ),
7610
- toggleState && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8159
+ toggleState && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7611
8160
  StateToggle,
7612
8161
  {
7613
8162
  rect: toggleState.rect,
@@ -7616,15 +8165,15 @@ function OhhwellsBridge() {
7616
8165
  onStateChange: handleStateChange
7617
8166
  }
7618
8167
  ),
7619
- sectionGap && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
8168
+ sectionGap && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
7620
8169
  "div",
7621
8170
  {
7622
8171
  "data-ohw-section-insert-line": "",
7623
8172
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
7624
8173
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
7625
8174
  children: [
7626
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
7627
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8175
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
8176
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7628
8177
  Badge,
7629
8178
  {
7630
8179
  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",
@@ -7637,11 +8186,11 @@ function OhhwellsBridge() {
7637
8186
  children: "Add Section"
7638
8187
  }
7639
8188
  ),
7640
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
8189
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
7641
8190
  ]
7642
8191
  }
7643
8192
  ),
7644
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
8193
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7645
8194
  LinkPopover,
7646
8195
  {
7647
8196
  panelRef: linkPopoverPanelRef,
@@ -7656,13 +8205,44 @@ function OhhwellsBridge() {
7656
8205
  onSubmit: handleLinkPopoverSubmit
7657
8206
  },
7658
8207
  `${linkPopover.key}-${pathname}`
7659
- ) : null
8208
+ ) : null,
8209
+ sectionGap && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
8210
+ "div",
8211
+ {
8212
+ "data-ohw-section-insert-line": "",
8213
+ className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
8214
+ style: { top: sectionGap.y, transform: "translateY(-50%)" },
8215
+ children: [
8216
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
8217
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
8218
+ Badge,
8219
+ {
8220
+ 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",
8221
+ onClick: () => {
8222
+ window.parent.postMessage(
8223
+ { type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
8224
+ "*"
8225
+ );
8226
+ },
8227
+ children: "Add Section"
8228
+ }
8229
+ ),
8230
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
8231
+ ]
8232
+ }
8233
+ )
7660
8234
  ] }),
7661
8235
  bridgeRoot
7662
8236
  ) : null;
7663
8237
  }
7664
8238
  // Annotate the CommonJS export names for ESM import in node:
7665
8239
  0 && (module.exports = {
8240
+ CustomToolbar,
8241
+ CustomToolbarButton,
8242
+ CustomToolbarDivider,
8243
+ DragHandle,
8244
+ ItemActionToolbar,
8245
+ ItemInteractionLayer,
7666
8246
  LinkEditorPanel,
7667
8247
  LinkPopover,
7668
8248
  OhhwellsBridge,
@@ -7670,9 +8250,14 @@ function OhhwellsBridge() {
7670
8250
  Toggle,
7671
8251
  ToggleGroup,
7672
8252
  ToggleGroupItem,
8253
+ Tooltip,
8254
+ TooltipContent,
8255
+ TooltipProvider,
8256
+ TooltipTrigger,
7673
8257
  buildTarget,
7674
8258
  filterAvailablePages,
7675
8259
  getEditModeInitialState,
8260
+ isEditSessionActive,
7676
8261
  isValidUrl,
7677
8262
  parseTarget,
7678
8263
  toggleVariants,