@ohhwells/bridge 0.1.33-next.39 → 0.1.34-next.40

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,7 +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,
34
37
  DragHandle: () => DragHandle,
38
+ ItemActionToolbar: () => ItemActionToolbar,
39
+ ItemInteractionLayer: () => ItemInteractionLayer,
35
40
  LinkEditorPanel: () => LinkEditorPanel,
36
41
  LinkPopover: () => LinkPopover,
37
42
  OhhwellsBridge: () => OhhwellsBridge,
@@ -39,6 +44,10 @@ __export(index_exports, {
39
44
  Toggle: () => Toggle,
40
45
  ToggleGroup: () => ToggleGroup,
41
46
  ToggleGroupItem: () => ToggleGroupItem,
47
+ Tooltip: () => Tooltip,
48
+ TooltipContent: () => TooltipContent,
49
+ TooltipProvider: () => TooltipProvider,
50
+ TooltipTrigger: () => TooltipTrigger,
42
51
  buildTarget: () => buildTarget,
43
52
  filterAvailablePages: () => filterAvailablePages,
44
53
  getEditModeInitialState: () => getEditModeInitialState,
@@ -4295,6 +4304,308 @@ var DragHandle = React3.forwardRef(
4295
4304
  );
4296
4305
  DragHandle.displayName = "DragHandle";
4297
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
+
4298
4609
  // src/OhhwellsBridge.tsx
4299
4610
  var import_react_dom2 = require("react-dom");
4300
4611
  var import_navigation = require("next/navigation");
@@ -4574,61 +4885,61 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
4574
4885
  }
4575
4886
 
4576
4887
  // src/ui/dialog.tsx
4577
- var React4 = __toESM(require("react"), 1);
4578
- var import_radix_ui3 = require("radix-ui");
4888
+ var React5 = __toESM(require("react"), 1);
4889
+ var import_radix_ui4 = require("radix-ui");
4579
4890
 
4580
4891
  // src/ui/icons.tsx
4581
- var import_jsx_runtime6 = require("react/jsx-runtime");
4892
+ var import_jsx_runtime10 = require("react/jsx-runtime");
4582
4893
  function IconX({ className, ...props }) {
4583
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4584
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M18 6 6 18" }),
4585
- /* @__PURE__ */ (0, import_jsx_runtime6.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" })
4586
4897
  ] });
4587
4898
  }
4588
4899
  function IconChevronDown({ className, ...props }) {
4589
- return /* @__PURE__ */ (0, import_jsx_runtime6.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_runtime6.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" }) });
4590
4901
  }
4591
4902
  function IconFile({ className, ...props }) {
4592
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4593
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
4594
- /* @__PURE__ */ (0, import_jsx_runtime6.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" })
4595
4906
  ] });
4596
4907
  }
4597
4908
  function IconInfo({ className, ...props }) {
4598
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4599
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
4600
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M12 16v-4" }),
4601
- /* @__PURE__ */ (0, import_jsx_runtime6.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" })
4602
4913
  ] });
4603
4914
  }
4604
4915
  function IconArrowRight({ className, ...props }) {
4605
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4606
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M5 12h14" }),
4607
- /* @__PURE__ */ (0, import_jsx_runtime6.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" })
4608
4919
  ] });
4609
4920
  }
4610
4921
  function IconSection({ className, ...props }) {
4611
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
4612
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
4613
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
4614
- /* @__PURE__ */ (0, import_jsx_runtime6.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" })
4615
4926
  ] });
4616
4927
  }
4617
4928
 
4618
4929
  // src/ui/dialog.tsx
4619
- var import_jsx_runtime7 = require("react/jsx-runtime");
4930
+ var import_jsx_runtime11 = require("react/jsx-runtime");
4620
4931
  function Dialog2({ ...props }) {
4621
- return /* @__PURE__ */ (0, import_jsx_runtime7.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 });
4622
4933
  }
4623
4934
  function DialogPortal({ ...props }) {
4624
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Dialog.Portal, { ...props });
4935
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_radix_ui4.Dialog.Portal, { ...props });
4625
4936
  }
4626
4937
  function DialogOverlay({
4627
4938
  className,
4628
4939
  ...props
4629
4940
  }) {
4630
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4631
- import_radix_ui3.Dialog.Overlay,
4941
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4942
+ import_radix_ui4.Dialog.Overlay,
4632
4943
  {
4633
4944
  "data-slot": "dialog-overlay",
4634
4945
  "data-ohw-link-modal-root": "",
@@ -4637,12 +4948,12 @@ function DialogOverlay({
4637
4948
  }
4638
4949
  );
4639
4950
  }
4640
- var DialogContent = React4.forwardRef(({ className, children, showCloseButton = true, container, ...props }, ref) => {
4951
+ var DialogContent = React5.forwardRef(({ className, children, showCloseButton = true, container, ...props }, ref) => {
4641
4952
  const positionMode = container ? "absolute" : "fixed";
4642
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(DialogPortal, { container: container ?? void 0, children: [
4643
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
4644
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4645
- 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,
4646
4957
  {
4647
4958
  ref,
4648
4959
  "data-slot": "dialog-content",
@@ -4657,13 +4968,13 @@ var DialogContent = React4.forwardRef(({ className, children, showCloseButton =
4657
4968
  ...props,
4658
4969
  children: [
4659
4970
  children,
4660
- showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4661
- import_radix_ui3.Dialog.Close,
4971
+ showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4972
+ import_radix_ui4.Dialog.Close,
4662
4973
  {
4663
4974
  type: "button",
4664
4975
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
4665
4976
  "aria-label": "Close",
4666
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IconX, { "aria-hidden": true })
4977
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(IconX, { "aria-hidden": true })
4667
4978
  }
4668
4979
  ) : null
4669
4980
  ]
@@ -4671,37 +4982,37 @@ var DialogContent = React4.forwardRef(({ className, children, showCloseButton =
4671
4982
  )
4672
4983
  ] });
4673
4984
  });
4674
- DialogContent.displayName = import_radix_ui3.Dialog.Content.displayName;
4985
+ DialogContent.displayName = import_radix_ui4.Dialog.Content.displayName;
4675
4986
  function DialogHeader({ className, ...props }) {
4676
- return /* @__PURE__ */ (0, import_jsx_runtime7.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 });
4677
4988
  }
4678
4989
  function DialogFooter({ className, ...props }) {
4679
- return /* @__PURE__ */ (0, import_jsx_runtime7.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 });
4680
4991
  }
4681
- var DialogTitle = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4682
- 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,
4683
4994
  {
4684
4995
  ref,
4685
4996
  className: cn("text-lg font-semibold leading-none tracking-tight text-card-foreground", className),
4686
4997
  ...props
4687
4998
  }
4688
4999
  ));
4689
- DialogTitle.displayName = import_radix_ui3.Dialog.Title.displayName;
4690
- var DialogDescription = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4691
- 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,
4692
5003
  {
4693
5004
  ref,
4694
5005
  className: cn("text-sm text-muted-foreground", className),
4695
5006
  ...props
4696
5007
  }
4697
5008
  ));
4698
- DialogDescription.displayName = import_radix_ui3.Dialog.Description.displayName;
4699
- var DialogClose = import_radix_ui3.Dialog.Close;
5009
+ DialogDescription.displayName = import_radix_ui4.Dialog.Description.displayName;
5010
+ var DialogClose = import_radix_ui4.Dialog.Close;
4700
5011
 
4701
5012
  // src/ui/button.tsx
4702
- var React5 = __toESM(require("react"), 1);
4703
- var import_radix_ui4 = require("radix-ui");
4704
- var import_jsx_runtime8 = 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");
4705
5016
  var buttonVariants = cva(
4706
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",
4707
5018
  {
@@ -4722,10 +5033,10 @@ var buttonVariants = cva(
4722
5033
  }
4723
5034
  }
4724
5035
  );
4725
- var Button = React5.forwardRef(
5036
+ var Button = React6.forwardRef(
4726
5037
  ({ className, variant, size, asChild = false, ...props }, ref) => {
4727
- const Comp = asChild ? import_radix_ui4.Slot.Root : "button";
4728
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5038
+ const Comp = asChild ? import_radix_ui5.Slot.Root : "button";
5039
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4729
5040
  Comp,
4730
5041
  {
4731
5042
  ref,
@@ -4739,37 +5050,37 @@ var Button = React5.forwardRef(
4739
5050
  Button.displayName = "Button";
4740
5051
 
4741
5052
  // src/ui/link-modal/DestinationBreadcrumb.tsx
4742
- var import_jsx_runtime9 = require("react/jsx-runtime");
5053
+ var import_jsx_runtime13 = require("react/jsx-runtime");
4743
5054
  function DestinationBreadcrumb({ pageTitle, sectionLabel }) {
4744
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
4745
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
4746
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-3", children: [
4747
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center gap-2", children: [
4748
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconFile, { className: "shrink-0 text-foreground", "aria-hidden": true }),
4749
- /* @__PURE__ */ (0, import_jsx_runtime9.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 })
4750
5061
  ] }),
4751
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconArrowRight, { className: "shrink-0 text-muted-foreground", "aria-hidden": true }),
4752
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
4753
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
4754
- /* @__PURE__ */ (0, import_jsx_runtime9.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 })
4755
5066
  ] })
4756
5067
  ] })
4757
5068
  ] });
4758
5069
  }
4759
5070
 
4760
5071
  // src/ui/link-modal/SectionTreeItem.tsx
4761
- var import_jsx_runtime10 = require("react/jsx-runtime");
5072
+ var import_jsx_runtime14 = require("react/jsx-runtime");
4762
5073
  function SectionTreeItem({ section, onSelect, selected }) {
4763
5074
  const interactive = Boolean(onSelect);
4764
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
4765
- /* @__PURE__ */ (0, import_jsx_runtime10.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)(
4766
5077
  "div",
4767
5078
  {
4768
5079
  className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
4769
5080
  "aria-hidden": true
4770
5081
  }
4771
5082
  ),
4772
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
5083
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
4773
5084
  "div",
4774
5085
  {
4775
5086
  role: interactive ? "button" : void 0,
@@ -4787,8 +5098,8 @@ function SectionTreeItem({ section, onSelect, selected }) {
4787
5098
  interactive && selected && "border-primary"
4788
5099
  ),
4789
5100
  children: [
4790
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
4791
- /* @__PURE__ */ (0, import_jsx_runtime10.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 })
4792
5103
  ]
4793
5104
  }
4794
5105
  )
@@ -4796,11 +5107,11 @@ function SectionTreeItem({ section, onSelect, selected }) {
4796
5107
  }
4797
5108
  function SectionPickerList({ sections, onSelect }) {
4798
5109
  if (sections.length === 0) {
4799
- return /* @__PURE__ */ (0, import_jsx_runtime10.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." });
4800
5111
  }
4801
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col gap-1", children: [
4802
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
4803
- sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime10.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))
4804
5115
  ] });
4805
5116
  }
4806
5117
 
@@ -4808,11 +5119,11 @@ function SectionPickerList({ sections, onSelect }) {
4808
5119
  var import_react4 = require("react");
4809
5120
 
4810
5121
  // src/ui/input.tsx
4811
- var React6 = __toESM(require("react"), 1);
4812
- var import_jsx_runtime11 = require("react/jsx-runtime");
4813
- var Input = React6.forwardRef(
5122
+ var React7 = __toESM(require("react"), 1);
5123
+ var import_jsx_runtime15 = require("react/jsx-runtime");
5124
+ var Input = React7.forwardRef(
4814
5125
  ({ className, type, ...props }, ref) => {
4815
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
5126
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
4816
5127
  "input",
4817
5128
  {
4818
5129
  type,
@@ -4830,11 +5141,11 @@ var Input = React6.forwardRef(
4830
5141
  Input.displayName = "Input";
4831
5142
 
4832
5143
  // src/ui/label.tsx
4833
- var import_radix_ui5 = require("radix-ui");
4834
- var import_jsx_runtime12 = require("react/jsx-runtime");
5144
+ var import_radix_ui6 = require("radix-ui");
5145
+ var import_jsx_runtime16 = require("react/jsx-runtime");
4835
5146
  function Label({ className, ...props }) {
4836
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4837
- import_radix_ui5.Label.Root,
5147
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5148
+ import_radix_ui6.Label.Root,
4838
5149
  {
4839
5150
  "data-slot": "label",
4840
5151
  className: cn("text-sm font-medium leading-5 text-foreground", className),
@@ -4844,9 +5155,9 @@ function Label({ className, ...props }) {
4844
5155
  }
4845
5156
 
4846
5157
  // src/ui/link-modal/UrlOrPageInput.tsx
4847
- var import_jsx_runtime13 = require("react/jsx-runtime");
5158
+ var import_jsx_runtime17 = require("react/jsx-runtime");
4848
5159
  function FieldChevron({ onClick }) {
4849
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5160
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4850
5161
  "button",
4851
5162
  {
4852
5163
  type: "button",
@@ -4854,7 +5165,7 @@ function FieldChevron({ onClick }) {
4854
5165
  onClick,
4855
5166
  "aria-label": "Open page list",
4856
5167
  tabIndex: -1,
4857
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconChevronDown, {})
5168
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconChevronDown, {})
4858
5169
  }
4859
5170
  );
4860
5171
  }
@@ -4893,12 +5204,12 @@ function UrlOrPageInput({
4893
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]",
4894
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"
4895
5206
  );
4896
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
4897
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
4898
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "relative w-full", children: [
4899
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
4900
- selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconFile, { className: "text-foreground", "aria-hidden": true }) }) : null,
4901
- readOnly ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime13.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)(
4902
5213
  Input,
4903
5214
  {
4904
5215
  ref: inputRef,
@@ -4917,7 +5228,7 @@ function UrlOrPageInput({
4917
5228
  )
4918
5229
  }
4919
5230
  ),
4920
- selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5231
+ selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4921
5232
  "button",
4922
5233
  {
4923
5234
  type: "button",
@@ -4925,26 +5236,26 @@ function UrlOrPageInput({
4925
5236
  onMouseDown: clearSelection,
4926
5237
  "aria-label": "Clear selected page",
4927
5238
  tabIndex: -1,
4928
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconX, { "aria-hidden": true })
5239
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconX, { "aria-hidden": true })
4929
5240
  }
4930
5241
  ) : null,
4931
- !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
5242
+ !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
4932
5243
  ] }),
4933
- dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5244
+ dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
4934
5245
  "div",
4935
5246
  {
4936
5247
  "data-ohw-link-page-dropdown": "",
4937
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",
4938
5249
  onMouseDown: (e) => e.preventDefault(),
4939
- children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
5250
+ children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
4940
5251
  "button",
4941
5252
  {
4942
5253
  type: "button",
4943
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",
4944
5255
  onClick: () => onPageSelect(page),
4945
5256
  children: [
4946
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconFile, { className: "shrink-0", "aria-hidden": true }),
4947
- /* @__PURE__ */ (0, import_jsx_runtime13.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 })
4948
5259
  ]
4949
5260
  },
4950
5261
  page.path
@@ -4952,7 +5263,7 @@ function UrlOrPageInput({
4952
5263
  }
4953
5264
  ) : null
4954
5265
  ] }),
4955
- urlError ? /* @__PURE__ */ (0, import_jsx_runtime13.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
4956
5267
  ] });
4957
5268
  }
4958
5269
 
@@ -5120,7 +5431,7 @@ function useLinkModalState({
5120
5431
  }
5121
5432
 
5122
5433
  // src/ui/link-modal/LinkEditorPanel.tsx
5123
- var import_jsx_runtime14 = require("react/jsx-runtime");
5434
+ var import_jsx_runtime18 = require("react/jsx-runtime");
5124
5435
  function LinkEditorPanel({
5125
5436
  open = true,
5126
5437
  mode = "create",
@@ -5144,25 +5455,25 @@ function LinkEditorPanel({
5144
5455
  onSubmit
5145
5456
  });
5146
5457
  const isCancel = state.secondaryLabel === "Cancel";
5147
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
5148
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime14.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)(
5149
5460
  "button",
5150
5461
  {
5151
5462
  type: "button",
5152
5463
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
5153
5464
  "aria-label": "Close",
5154
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconX, { "aria-hidden": true })
5465
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconX, { "aria-hidden": true })
5155
5466
  }
5156
5467
  ) }),
5157
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
5158
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
5159
- state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime14.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)(
5160
5471
  DestinationBreadcrumb,
5161
5472
  {
5162
5473
  pageTitle: state.selectedPage.title,
5163
5474
  sectionLabel: state.selectedSection.label
5164
5475
  }
5165
- ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5476
+ ) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5166
5477
  UrlOrPageInput,
5167
5478
  {
5168
5479
  value: state.searchValue,
@@ -5175,18 +5486,18 @@ function LinkEditorPanel({
5175
5486
  urlError: state.urlError
5176
5487
  }
5177
5488
  ),
5178
- state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
5179
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
5180
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
5181
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconInfo, { className: "shrink-0", "aria-hidden": true }),
5182
- /* @__PURE__ */ (0, import_jsx_runtime14.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." })
5183
5494
  ] })
5184
5495
  ] }) : null,
5185
- state.showSectionPicker ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
5186
- state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime14.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
5187
5498
  ] }),
5188
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
5189
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5499
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
5500
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5190
5501
  Button,
5191
5502
  {
5192
5503
  type: "button",
@@ -5201,7 +5512,7 @@ function LinkEditorPanel({
5201
5512
  children: state.secondaryLabel
5202
5513
  }
5203
5514
  ),
5204
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5515
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5205
5516
  Button,
5206
5517
  {
5207
5518
  type: "button",
@@ -5220,7 +5531,7 @@ function LinkEditorPanel({
5220
5531
  }
5221
5532
 
5222
5533
  // src/ui/link-modal/LinkPopover.tsx
5223
- var import_jsx_runtime15 = require("react/jsx-runtime");
5534
+ var import_jsx_runtime19 = require("react/jsx-runtime");
5224
5535
  function LinkPopover({
5225
5536
  open = true,
5226
5537
  panelRef,
@@ -5228,14 +5539,14 @@ function LinkPopover({
5228
5539
  onClose,
5229
5540
  ...editorProps
5230
5541
  }) {
5231
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5542
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5232
5543
  Dialog2,
5233
5544
  {
5234
5545
  open,
5235
5546
  onOpenChange: (next) => {
5236
5547
  if (!next) onClose?.();
5237
5548
  },
5238
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5549
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5239
5550
  DialogContent,
5240
5551
  {
5241
5552
  ref: panelRef,
@@ -5245,7 +5556,7 @@ function LinkPopover({
5245
5556
  "data-ohw-bridge": "",
5246
5557
  showCloseButton: false,
5247
5558
  className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
5248
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(LinkEditorPanel, { ...editorProps, open, onClose })
5559
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LinkEditorPanel, { ...editorProps, open, onClose })
5249
5560
  }
5250
5561
  )
5251
5562
  }
@@ -5311,7 +5622,7 @@ function shouldUseDevFixtures() {
5311
5622
  }
5312
5623
 
5313
5624
  // src/ui/badge.tsx
5314
- var import_jsx_runtime16 = require("react/jsx-runtime");
5625
+ var import_jsx_runtime20 = require("react/jsx-runtime");
5315
5626
  var badgeVariants = cva(
5316
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",
5317
5628
  {
@@ -5329,12 +5640,13 @@ var badgeVariants = cva(
5329
5640
  }
5330
5641
  );
5331
5642
  function Badge({ className, variant, ...props }) {
5332
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
5643
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
5333
5644
  }
5334
5645
 
5335
5646
  // src/OhhwellsBridge.tsx
5336
- var import_jsx_runtime17 = require("react/jsx-runtime");
5337
- var PRIMARY = "#0885FE";
5647
+ var import_lucide_react3 = require("lucide-react");
5648
+ var import_jsx_runtime21 = require("react/jsx-runtime");
5649
+ var PRIMARY2 = "#0885FE";
5338
5650
  var IMAGE_FADE_MS = 300;
5339
5651
  function runOpacityFade(el, onDone) {
5340
5652
  const anim = el.animate([{ opacity: 0 }, { opacity: 1 }], {
@@ -5507,7 +5819,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
5507
5819
  const root = (0, import_client.createRoot)(container);
5508
5820
  (0, import_react_dom.flushSync)(() => {
5509
5821
  root.render(
5510
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5822
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5511
5823
  SchedulingWidget,
5512
5824
  {
5513
5825
  notifyOnConnect,
@@ -5622,13 +5934,39 @@ function getHrefKeyFromElement(el) {
5622
5934
  function isNavbarButton(el) {
5623
5935
  return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
5624
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
+ }
5625
5961
  function getReorderHandleState(el) {
5626
5962
  const linkEl = el.closest("[data-ohw-href-key]");
5627
- if (!linkEl || isNavbarButton(el)) return { key: null, disabled: false };
5628
- return {
5629
- key: linkEl.dataset.ohwHrefKey ?? null,
5630
- disabled: isDragHandleDisabled(el)
5631
- };
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) };
5632
5970
  }
5633
5971
  function clearHrefKeyHover(anchor) {
5634
5972
  anchor.removeAttribute("data-ohw-hovered");
@@ -5636,6 +5974,9 @@ function clearHrefKeyHover(anchor) {
5636
5974
  el.removeAttribute("data-ohw-hovered");
5637
5975
  });
5638
5976
  }
5977
+ function isInsideNavigationItem(el) {
5978
+ return getNavigationItemAnchor(el) !== null;
5979
+ }
5639
5980
  function collectSections() {
5640
5981
  return collectSectionsFromDom();
5641
5982
  }
@@ -5785,7 +6126,7 @@ function EditGlowChrome({
5785
6126
  dragDisabled = false
5786
6127
  }) {
5787
6128
  const GAP = 6;
5788
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
6129
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
5789
6130
  "div",
5790
6131
  {
5791
6132
  ref: elRef,
@@ -5800,20 +6141,20 @@ function EditGlowChrome({
5800
6141
  zIndex: 2147483646
5801
6142
  },
5802
6143
  children: [
5803
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6144
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5804
6145
  "div",
5805
6146
  {
5806
6147
  style: {
5807
6148
  position: "absolute",
5808
6149
  inset: 0,
5809
- border: "2px solid #0885FE",
6150
+ border: "2px solid var(--ohw-primary, #0885FE)",
5810
6151
  borderRadius: 8,
5811
6152
  boxShadow: "0 0 0 4px rgba(8, 133, 254, 0.12)",
5812
6153
  pointerEvents: "none"
5813
6154
  }
5814
6155
  }
5815
6156
  ),
5816
- reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6157
+ reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5817
6158
  "div",
5818
6159
  {
5819
6160
  "data-ohw-drag-handle-container": "",
@@ -5825,7 +6166,7 @@ function EditGlowChrome({
5825
6166
  transform: "translate(calc(-100% - 7px), -50%)",
5826
6167
  pointerEvents: dragDisabled ? "none" : "auto"
5827
6168
  },
5828
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6169
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5829
6170
  DragHandle,
5830
6171
  {
5831
6172
  "aria-label": `Reorder ${reorderHrefKey}`,
@@ -5915,119 +6256,24 @@ function calcToolbarPos(rect, parentScroll, approxW = 306) {
5915
6256
  const left = Math.max(GAP + APPROX_W / 2, Math.min(rawLeft, window.innerWidth - GAP - APPROX_W / 2));
5916
6257
  return { top, left, transform };
5917
6258
  }
5918
- var EDIT_LINK_ICON = /* @__PURE__ */ (0, import_jsx_runtime17.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: [
5919
- /* @__PURE__ */ (0, import_jsx_runtime17.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" }),
5920
- /* @__PURE__ */ (0, import_jsx_runtime17.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" })
5921
- ] });
6259
+ function resolveItemInteractionState(rect, parentScroll) {
6260
+ const { transform } = calcToolbarPos(rect, parentScroll, 120);
6261
+ return transform.includes("translateY(-100%)") ? "active-top" : "active-bottom";
6262
+ }
5922
6263
  function FloatingToolbar({
5923
6264
  rect,
5924
6265
  parentScroll,
5925
6266
  elRef,
5926
- variant = "rich-text",
5927
6267
  onCommand,
5928
6268
  activeCommands,
5929
6269
  showEditLink,
5930
6270
  onEditLink
5931
6271
  }) {
5932
- const approxW = variant === "link-action" ? 112 : 306;
5933
- const { top, left, transform } = calcToolbarPos(rect, parentScroll, approxW);
5934
- if (variant === "link-action") {
5935
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
5936
- "div",
5937
- {
5938
- ref: elRef,
5939
- "data-ohw-toolbar": "",
5940
- style: {
5941
- position: "fixed",
5942
- top,
5943
- left,
5944
- transform,
5945
- zIndex: 2147483647,
5946
- background: "#fff",
5947
- border: "1px solid #E7E5E4",
5948
- borderRadius: 6,
5949
- boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
5950
- display: "flex",
5951
- alignItems: "center",
5952
- padding: TOOLBAR_PILL_PADDING,
5953
- gap: TOOLBAR_TOGGLE_GAP,
5954
- fontFamily: "sans-serif",
5955
- pointerEvents: "auto",
5956
- whiteSpace: "nowrap"
5957
- },
5958
- onMouseDown: (e) => e.stopPropagation(),
5959
- children: [
5960
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5961
- "button",
5962
- {
5963
- type: "button",
5964
- title: "Edit link",
5965
- onMouseDown: (e) => {
5966
- e.preventDefault();
5967
- e.stopPropagation();
5968
- onEditLink?.();
5969
- },
5970
- onClick: (e) => {
5971
- e.preventDefault();
5972
- e.stopPropagation();
5973
- },
5974
- onMouseEnter: (e) => {
5975
- e.currentTarget.style.background = "#F5F5F4";
5976
- },
5977
- onMouseLeave: (e) => {
5978
- e.currentTarget.style.background = "transparent";
5979
- },
5980
- style: {
5981
- display: "flex",
5982
- alignItems: "center",
5983
- justifyContent: "center",
5984
- border: "none",
5985
- background: "transparent",
5986
- borderRadius: 4,
5987
- cursor: "pointer",
5988
- color: "#1C1917",
5989
- flexShrink: 0,
5990
- padding: 6
5991
- },
5992
- children: EDIT_LINK_ICON
5993
- }
5994
- ),
5995
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { display: "block", width: 1, height: 24, background: "#E7E5E4", flexShrink: 0 } }),
5996
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5997
- "button",
5998
- {
5999
- type: "button",
6000
- title: "Coming soon",
6001
- disabled: true,
6002
- style: {
6003
- display: "flex",
6004
- alignItems: "center",
6005
- justifyContent: "center",
6006
- border: "none",
6007
- background: "transparent",
6008
- borderRadius: 4,
6009
- cursor: "not-allowed",
6010
- color: "#A8A29E",
6011
- flexShrink: 0,
6012
- padding: 6,
6013
- opacity: 0.6
6014
- },
6015
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: [
6016
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "5", cy: "12", r: "1.5" }),
6017
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "12", cy: "12", r: "1.5" }),
6018
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "19", cy: "12", r: "1.5" })
6019
- ] })
6020
- }
6021
- )
6022
- ]
6023
- }
6024
- );
6025
- }
6026
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
6272
+ const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
6273
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6027
6274
  "div",
6028
6275
  {
6029
6276
  ref: elRef,
6030
- "data-ohw-toolbar": "",
6031
6277
  style: {
6032
6278
  position: "fixed",
6033
6279
  top,
@@ -6043,54 +6289,36 @@ function FloatingToolbar({
6043
6289
  padding: TOOLBAR_PILL_PADDING,
6044
6290
  gap: TOOLBAR_TOGGLE_GAP,
6045
6291
  fontFamily: "sans-serif",
6046
- pointerEvents: "auto",
6047
- whiteSpace: "nowrap"
6292
+ pointerEvents: "auto"
6048
6293
  },
6049
- onMouseDown: (e) => e.stopPropagation(),
6050
- children: [
6051
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react6.default.Fragment, { children: [
6052
- gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime17.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, {}),
6053
6297
  btns.map((btn) => {
6054
6298
  const isActive = activeCommands.has(btn.cmd);
6055
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6056
- "button",
6299
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6300
+ CustomToolbarButton,
6057
6301
  {
6058
6302
  title: btn.title,
6303
+ active: isActive,
6059
6304
  onMouseDown: (e) => {
6060
6305
  e.preventDefault();
6061
6306
  onCommand(btn.cmd);
6062
6307
  },
6063
- onMouseEnter: (e) => {
6064
- if (!isActive) e.currentTarget.style.background = "#F5F5F4";
6065
- },
6066
- onMouseLeave: (e) => {
6067
- if (!isActive) e.currentTarget.style.background = "transparent";
6068
- },
6069
- style: {
6070
- display: "flex",
6071
- alignItems: "center",
6072
- justifyContent: "center",
6073
- border: "none",
6074
- background: isActive ? PRIMARY : "transparent",
6075
- borderRadius: 4,
6076
- cursor: "pointer",
6077
- color: isActive ? "#FFFFFF" : "#1C1917",
6078
- flexShrink: 0,
6079
- padding: 6
6080
- },
6081
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6308
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6082
6309
  "svg",
6083
6310
  {
6084
6311
  width: "16",
6085
6312
  height: "16",
6086
6313
  viewBox: "0 0 24 24",
6087
6314
  fill: "none",
6088
- stroke: isActive ? "#FFFFFF" : "#1C1917",
6315
+ stroke: "currentColor",
6089
6316
  strokeWidth: "2.5",
6090
6317
  strokeLinecap: "round",
6091
6318
  strokeLinejoin: "round",
6092
- style: isActive && gi > 0 ? { filter: "drop-shadow(0 0 0.5px #fff)" } : void 0,
6093
- 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
6094
6322
  }
6095
6323
  )
6096
6324
  },
@@ -6098,8 +6326,8 @@ function FloatingToolbar({
6098
6326
  );
6099
6327
  })
6100
6328
  ] }, gi)),
6101
- showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6102
- "button",
6329
+ showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6330
+ CustomToolbarButton,
6103
6331
  {
6104
6332
  type: "button",
6105
6333
  title: "Edit link",
@@ -6112,28 +6340,10 @@ function FloatingToolbar({
6112
6340
  e.preventDefault();
6113
6341
  e.stopPropagation();
6114
6342
  },
6115
- onMouseEnter: (e) => {
6116
- e.currentTarget.style.background = "#F5F5F4";
6117
- },
6118
- onMouseLeave: (e) => {
6119
- e.currentTarget.style.background = "transparent";
6120
- },
6121
- style: {
6122
- display: "flex",
6123
- alignItems: "center",
6124
- justifyContent: "center",
6125
- border: "none",
6126
- background: "transparent",
6127
- borderRadius: 4,
6128
- cursor: "pointer",
6129
- color: "#1C1917",
6130
- flexShrink: 0,
6131
- padding: 6
6132
- },
6133
- children: EDIT_LINK_ICON
6343
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react3.Link, { className: "size-4 shrink-0", "aria-hidden": true })
6134
6344
  }
6135
6345
  ) : null
6136
- ]
6346
+ ] })
6137
6347
  }
6138
6348
  );
6139
6349
  }
@@ -6147,7 +6357,7 @@ function StateToggle({
6147
6357
  states,
6148
6358
  onStateChange
6149
6359
  }) {
6150
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
6360
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6151
6361
  ToggleGroup,
6152
6362
  {
6153
6363
  "data-ohw-state-toggle": "",
@@ -6161,7 +6371,7 @@ function StateToggle({
6161
6371
  left: rect.right - 8,
6162
6372
  transform: "translateX(-100%)"
6163
6373
  },
6164
- children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime17.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))
6165
6375
  }
6166
6376
  );
6167
6377
  }
@@ -6249,6 +6459,10 @@ function OhhwellsBridge() {
6249
6459
  });
6250
6460
  const deselectRef = (0, import_react6.useRef)(() => {
6251
6461
  });
6462
+ const reselectNavigationItemRef = (0, import_react6.useRef)(() => {
6463
+ });
6464
+ const commitNavigationTextEditRef = (0, import_react6.useRef)(() => {
6465
+ });
6252
6466
  const refreshActiveCommandsRef = (0, import_react6.useRef)(() => {
6253
6467
  });
6254
6468
  const postToParentRef = (0, import_react6.useRef)(postToParent);
@@ -6266,6 +6480,11 @@ function OhhwellsBridge() {
6266
6480
  const [activeCommands, setActiveCommands] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
6267
6481
  const [sectionGap, setSectionGap] = (0, import_react6.useState)(null);
6268
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);
6269
6488
  const [linkPopover, setLinkPopover] = (0, import_react6.useState)(null);
6270
6489
  const [sitePages, setSitePages] = (0, import_react6.useState)([]);
6271
6490
  const [sectionsByPath, setSectionsByPath] = (0, import_react6.useState)({});
@@ -6447,16 +6666,82 @@ function OhhwellsBridge() {
6447
6666
  }, [postToParent]);
6448
6667
  const deselect = (0, import_react6.useCallback)(() => {
6449
6668
  selectedElRef.current = null;
6669
+ setReorderHrefKey(null);
6670
+ setReorderDragDisabled(false);
6671
+ siblingHintElRef.current = null;
6672
+ setSiblingHintRect(null);
6673
+ setIsItemDragging(false);
6450
6674
  if (!activeElRef.current) {
6451
6675
  setToolbarRect(null);
6452
6676
  setToolbarVariant("none");
6453
6677
  }
6454
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;
6455
6732
  const select = (0, import_react6.useCallback)((anchor) => {
6456
- if (!isNavbarButton(anchor)) return;
6733
+ if (!isNavigationItem(anchor)) return;
6457
6734
  if (activeElRef.current) deactivate();
6458
6735
  selectedElRef.current = anchor;
6459
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);
6460
6745
  setToolbarVariant("link-action");
6461
6746
  setToolbarRect(anchor.getBoundingClientRect());
6462
6747
  setToolbarShowEditLink(false);
@@ -6471,6 +6756,9 @@ function OhhwellsBridge() {
6471
6756
  postToParentRef.current({ type: "ow:image-unhover" });
6472
6757
  }
6473
6758
  setToolbarVariant("rich-text");
6759
+ siblingHintElRef.current = null;
6760
+ setSiblingHintRect(null);
6761
+ setIsItemDragging(false);
6474
6762
  el.setAttribute("contenteditable", "true");
6475
6763
  el.removeAttribute("data-ohw-hovered");
6476
6764
  el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
@@ -6478,9 +6766,15 @@ function OhhwellsBridge() {
6478
6766
  originalContentRef.current = el.innerHTML;
6479
6767
  el.focus();
6480
6768
  setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
6481
- const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
6482
- setReorderHrefKey(reorderKey);
6483
- setReorderDragDisabled(reorderDisabled);
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
+ }
6484
6778
  setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
6485
6779
  postToParent({ type: "ow:enter-edit", key: el.dataset.ohwKey });
6486
6780
  requestAnimationFrame(() => refreshActiveCommandsRef.current());
@@ -6673,18 +6967,25 @@ function OhhwellsBridge() {
6673
6967
  [data-ohw-editable="image"], [data-ohw-editable="image"] *,
6674
6968
  [data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
6675
6969
  [data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
6676
- [data-ohw-hovered]:not([contenteditable]) {
6677
- outline: 2px dashed ${PRIMARY} !important;
6970
+ [data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
6971
+ outline: 2px dashed ${PRIMARY2} !important;
6678
6972
  outline-offset: 4px;
6679
6973
  border-radius: 2px;
6680
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
+ }
6681
6982
  [data-ohw-editable][contenteditable] {
6682
6983
  outline: none !important;
6683
- caret-color: ${PRIMARY};
6984
+ caret-color: ${PRIMARY2};
6684
6985
  cursor: text !important;
6685
6986
  }
6686
6987
  [data-ohw-editable][contenteditable]::selection,
6687
- [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY}59 !important; }
6988
+ [data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY2}59 !important; }
6688
6989
  [data-ohw-editable-state], [data-ohw-editable-state] * { pointer-events: none !important; }
6689
6990
  [data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
6690
6991
  [data-ohw-editable-state][data-ohw-active-state][data-ohw-editable] { pointer-events: auto !important; }
@@ -6696,7 +6997,7 @@ function OhhwellsBridge() {
6696
6997
  stateViews.textContent = `
6697
6998
  [data-ohw-state-view]:not([data-ohw-state-view="default"]) { display: none; }
6698
6999
  [data-ohw-state-view="default"] [data-ohw-editable] { pointer-events: auto !important; }
6699
- [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; }
6700
7001
  [data-ohw-state-hovered]:has([data-ohw-hovered]) { outline: none !important; }
6701
7002
  `;
6702
7003
  document.head.appendChild(base);
@@ -6711,7 +7012,7 @@ function OhhwellsBridge() {
6711
7012
  if (target.closest("[data-ohw-state-toggle]")) return;
6712
7013
  if (target.closest("[data-ohw-max-badge]")) return;
6713
7014
  if (isInsideLinkEditor(target)) return;
6714
- if (target.closest('[data-ohw-edit-chrome], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
7015
+ if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
6715
7016
  e.preventDefault();
6716
7017
  e.stopPropagation();
6717
7018
  return;
@@ -6737,15 +7038,15 @@ function OhhwellsBridge() {
6737
7038
  return;
6738
7039
  }
6739
7040
  const hrefCtx = getHrefKeyFromElement(editable);
6740
- if (hrefCtx && isNavbarButton(hrefCtx.anchor)) {
7041
+ const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
7042
+ if (navAnchor) {
6741
7043
  e.preventDefault();
6742
7044
  e.stopPropagation();
6743
- const { anchor: anchor2 } = hrefCtx;
6744
- if (selectedElRef.current === anchor2) {
7045
+ if (selectedElRef.current === navAnchor) {
6745
7046
  activateRef.current(editable);
6746
7047
  return;
6747
7048
  }
6748
- selectRef.current(anchor2);
7049
+ selectRef.current(navAnchor);
6749
7050
  return;
6750
7051
  }
6751
7052
  e.preventDefault();
@@ -6753,8 +7054,8 @@ function OhhwellsBridge() {
6753
7054
  activateRef.current(editable);
6754
7055
  return;
6755
7056
  }
6756
- const hrefAnchor = target.closest("[data-ohw-href-key]");
6757
- if (hrefAnchor && isNavbarButton(hrefAnchor)) {
7057
+ const hrefAnchor = getNavigationItemAnchor(target);
7058
+ if (hrefAnchor) {
6758
7059
  e.preventDefault();
6759
7060
  e.stopPropagation();
6760
7061
  if (selectedElRef.current === hrefAnchor) return;
@@ -6787,23 +7088,58 @@ function OhhwellsBridge() {
6787
7088
  deactivateRef.current();
6788
7089
  };
6789
7090
  const handleMouseOver = (e) => {
6790
- 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]");
6791
7102
  if (!editable) return;
6792
7103
  const selected = selectedElRef.current;
6793
7104
  if (selected && (selected === editable || selected.contains(editable))) return;
6794
7105
  if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image" && !editable.hasAttribute("contenteditable")) {
6795
7106
  const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
6796
- hoverTarget.setAttribute("data-ohw-hovered", "");
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
+ }
6797
7114
  }
6798
7115
  };
6799
7116
  const handleMouseOut = (e) => {
6800
- 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]");
6801
7130
  if (!editable) return;
6802
7131
  const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
6803
- if (related?.closest("[data-ohw-drag-handle-container]")) return;
7132
+ if (related?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
6804
7133
  if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image") {
6805
7134
  const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
6806
- hoverTarget.removeAttribute("data-ohw-hovered");
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
+ }
6807
7143
  }
6808
7144
  };
6809
7145
  const toProbeCoords = (clientX, clientY, fromParentViewport) => {
@@ -6931,7 +7267,7 @@ function OhhwellsBridge() {
6931
7267
  if (imgEl) {
6932
7268
  const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
6933
7269
  const topEl = document.elementFromPoint(x, y);
6934
- if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
7270
+ if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
6935
7271
  if (hoveredImageRef.current) {
6936
7272
  hoveredImageRef.current = null;
6937
7273
  resumeAnimTracks();
@@ -6979,7 +7315,9 @@ function OhhwellsBridge() {
6979
7315
  postImageHover(imgEl, isDragOver, true);
6980
7316
  }
6981
7317
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
6982
- textEditable.setAttribute("data-ohw-hovered", "");
7318
+ if (textEditable && !isInsideNavigationItem(textEditable)) {
7319
+ textEditable.setAttribute("data-ohw-hovered", "");
7320
+ }
6983
7321
  return;
6984
7322
  }
6985
7323
  if (hoveredImageRef.current) {
@@ -6989,7 +7327,9 @@ function OhhwellsBridge() {
6989
7327
  postToParentRef.current({ type: "ow:image-unhover" });
6990
7328
  }
6991
7329
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
6992
- textEditable.setAttribute("data-ohw-hovered", "");
7330
+ if (textEditable && !isInsideNavigationItem(textEditable)) {
7331
+ textEditable.setAttribute("data-ohw-hovered", "");
7332
+ }
6993
7333
  return;
6994
7334
  }
6995
7335
  if (hoveredGapRef.current) {
@@ -7033,7 +7373,24 @@ function OhhwellsBridge() {
7033
7373
  return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
7034
7374
  });
7035
7375
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
7036
- 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
+ }
7037
7394
  }
7038
7395
  };
7039
7396
  const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
@@ -7311,6 +7668,33 @@ function OhhwellsBridge() {
7311
7668
  deselectRef.current();
7312
7669
  return;
7313
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
+ }
7314
7698
  if (e.key !== "Escape") return;
7315
7699
  const el = activeElRef.current;
7316
7700
  if (el && originalContentRef.current !== null) {
@@ -7326,7 +7710,8 @@ function OhhwellsBridge() {
7326
7710
  const handleScroll = () => {
7327
7711
  const focusEl = activeElRef.current ?? selectedElRef.current;
7328
7712
  if (focusEl) {
7329
- const r2 = focusEl.getBoundingClientRect();
7713
+ const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
7714
+ const r2 = measureEl.getBoundingClientRect();
7330
7715
  applyToolbarPos(r2);
7331
7716
  setToolbarRect(r2);
7332
7717
  setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
@@ -7335,6 +7720,12 @@ function OhhwellsBridge() {
7335
7720
  const rect = activeStateElRef.current.getBoundingClientRect();
7336
7721
  setToggleState((prev) => prev ? { ...prev, rect } : null);
7337
7722
  }
7723
+ if (hoveredItemElRef.current) {
7724
+ setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
7725
+ }
7726
+ if (siblingHintElRef.current) {
7727
+ setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
7728
+ }
7338
7729
  if (hoveredImageRef.current) {
7339
7730
  const el = hoveredImageRef.current;
7340
7731
  const r2 = el.getBoundingClientRect();
@@ -7454,7 +7845,7 @@ function OhhwellsBridge() {
7454
7845
  };
7455
7846
  const applyToolbarPos = (rect) => {
7456
7847
  const ps = parentScrollRef.current;
7457
- const approxW = toolbarVariantRef.current === "link-action" ? 112 : 306;
7848
+ const approxW = 330;
7458
7849
  if (toolbarElRef.current) {
7459
7850
  const { top, left, transform } = calcToolbarPos(rect, ps, approxW);
7460
7851
  toolbarElRef.current.style.top = `${top}px`;
@@ -7465,6 +7856,8 @@ function OhhwellsBridge() {
7465
7856
  const GAP = 6;
7466
7857
  glowElRef.current.style.top = `${rect.top - GAP}px`;
7467
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`;
7468
7861
  }
7469
7862
  };
7470
7863
  const handleParentScroll = (e) => {
@@ -7475,7 +7868,10 @@ function OhhwellsBridge() {
7475
7868
  applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
7476
7869
  }
7477
7870
  const focusEl = activeElRef.current ?? selectedElRef.current;
7478
- if (focusEl) applyToolbarPos(focusEl.getBoundingClientRect());
7871
+ if (focusEl) {
7872
+ const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
7873
+ applyToolbarPos(measureEl.getBoundingClientRect());
7874
+ }
7479
7875
  };
7480
7876
  const handleClickAt = (e) => {
7481
7877
  if (e.data?.type !== "ow:click-at") return;
@@ -7686,10 +8082,33 @@ function OhhwellsBridge() {
7686
8082
  const currentSections = sectionsByPath[pathname] ?? [];
7687
8083
  linkPopoverOpenRef.current = linkPopover !== null;
7688
8084
  return bridgeRoot ? (0, import_react_dom2.createPortal)(
7689
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
7690
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
7691
- toolbarRect && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
7692
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
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)(
7693
8112
  EditGlowChrome,
7694
8113
  {
7695
8114
  rect: toolbarRect,
@@ -7698,10 +8117,9 @@ function OhhwellsBridge() {
7698
8117
  dragDisabled: reorderDragDisabled
7699
8118
  }
7700
8119
  ),
7701
- toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
8120
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7702
8121
  FloatingToolbar,
7703
8122
  {
7704
- variant: "rich-text",
7705
8123
  rect: toolbarRect,
7706
8124
  parentScroll: parentScrollRef.current,
7707
8125
  elRef: toolbarElRef,
@@ -7710,21 +8128,9 @@ function OhhwellsBridge() {
7710
8128
  showEditLink,
7711
8129
  onEditLink: openLinkPopoverForActive
7712
8130
  }
7713
- ),
7714
- toolbarVariant === "link-action" && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
7715
- FloatingToolbar,
7716
- {
7717
- variant: "link-action",
7718
- rect: toolbarRect,
7719
- parentScroll: parentScrollRef.current,
7720
- elRef: toolbarElRef,
7721
- onCommand: handleCommand,
7722
- activeCommands,
7723
- onEditLink: openLinkPopoverForSelected
7724
- }
7725
8131
  )
7726
8132
  ] }),
7727
- maxBadge && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
8133
+ maxBadge && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
7728
8134
  "div",
7729
8135
  {
7730
8136
  "data-ohw-max-badge": "",
@@ -7750,7 +8156,7 @@ function OhhwellsBridge() {
7750
8156
  ]
7751
8157
  }
7752
8158
  ),
7753
- toggleState && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
8159
+ toggleState && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7754
8160
  StateToggle,
7755
8161
  {
7756
8162
  rect: toggleState.rect,
@@ -7759,15 +8165,15 @@ function OhhwellsBridge() {
7759
8165
  onStateChange: handleStateChange
7760
8166
  }
7761
8167
  ),
7762
- sectionGap && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
8168
+ sectionGap && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
7763
8169
  "div",
7764
8170
  {
7765
8171
  "data-ohw-section-insert-line": "",
7766
8172
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
7767
8173
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
7768
8174
  children: [
7769
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
7770
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
8175
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
8176
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7771
8177
  Badge,
7772
8178
  {
7773
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",
@@ -7780,11 +8186,11 @@ function OhhwellsBridge() {
7780
8186
  children: "Add Section"
7781
8187
  }
7782
8188
  ),
7783
- /* @__PURE__ */ (0, import_jsx_runtime17.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 } })
7784
8190
  ]
7785
8191
  }
7786
8192
  ),
7787
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
8193
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7788
8194
  LinkPopover,
7789
8195
  {
7790
8196
  panelRef: linkPopoverPanelRef,
@@ -7800,15 +8206,15 @@ function OhhwellsBridge() {
7800
8206
  },
7801
8207
  `${linkPopover.key}-${pathname}`
7802
8208
  ) : null,
7803
- sectionGap && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
8209
+ sectionGap && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
7804
8210
  "div",
7805
8211
  {
7806
8212
  "data-ohw-section-insert-line": "",
7807
8213
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
7808
8214
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
7809
8215
  children: [
7810
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
7811
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
8216
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
8217
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
7812
8218
  Badge,
7813
8219
  {
7814
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",
@@ -7821,7 +8227,7 @@ function OhhwellsBridge() {
7821
8227
  children: "Add Section"
7822
8228
  }
7823
8229
  ),
7824
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
8230
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
7825
8231
  ]
7826
8232
  }
7827
8233
  )
@@ -7831,7 +8237,12 @@ function OhhwellsBridge() {
7831
8237
  }
7832
8238
  // Annotate the CommonJS export names for ESM import in node:
7833
8239
  0 && (module.exports = {
8240
+ CustomToolbar,
8241
+ CustomToolbarButton,
8242
+ CustomToolbarDivider,
7834
8243
  DragHandle,
8244
+ ItemActionToolbar,
8245
+ ItemInteractionLayer,
7835
8246
  LinkEditorPanel,
7836
8247
  LinkPopover,
7837
8248
  OhhwellsBridge,
@@ -7839,6 +8250,10 @@ function OhhwellsBridge() {
7839
8250
  Toggle,
7840
8251
  ToggleGroup,
7841
8252
  ToggleGroupItem,
8253
+ Tooltip,
8254
+ TooltipContent,
8255
+ TooltipProvider,
8256
+ TooltipTrigger,
7842
8257
  buildTarget,
7843
8258
  filterAvailablePages,
7844
8259
  getEditModeInitialState,