@ohhwells/bridge 0.1.39 → 0.1.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 +1705 -555
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -3
- package/dist/index.d.ts +50 -3
- package/dist/index.js +1716 -566
- package/dist/index.js.map +1 -1
- package/dist/styles.css +127 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import React9, { useCallback as
|
|
4
|
+
import React9, { useCallback as useCallback3, useEffect as useEffect7, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState6 } from "react";
|
|
5
5
|
import { createRoot } from "react-dom/client";
|
|
6
6
|
import { flushSync } from "react-dom";
|
|
7
7
|
|
|
@@ -10,6 +10,9 @@ var linkHrefStore = /* @__PURE__ */ new Map();
|
|
|
10
10
|
function setStoredLinkHref(key, href) {
|
|
11
11
|
linkHrefStore.set(key, href);
|
|
12
12
|
}
|
|
13
|
+
function getStoredLinkHref(key) {
|
|
14
|
+
return linkHrefStore.get(key);
|
|
15
|
+
}
|
|
13
16
|
function enforceLinkHrefs() {
|
|
14
17
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
15
18
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
@@ -4349,6 +4352,7 @@ function ItemActionToolbar({
|
|
|
4349
4352
|
onEditLink,
|
|
4350
4353
|
onAddItem,
|
|
4351
4354
|
onMore,
|
|
4355
|
+
editLinkDisabled = false,
|
|
4352
4356
|
addItemDisabled = true,
|
|
4353
4357
|
moreDisabled = true,
|
|
4354
4358
|
tooltipSide = "bottom"
|
|
@@ -4357,10 +4361,12 @@ function ItemActionToolbar({
|
|
|
4357
4361
|
/* @__PURE__ */ jsx8(
|
|
4358
4362
|
ToolbarActionTooltip,
|
|
4359
4363
|
{
|
|
4360
|
-
label: "
|
|
4364
|
+
label: "Edit link",
|
|
4361
4365
|
side: tooltipSide,
|
|
4366
|
+
disabled: editLinkDisabled,
|
|
4362
4367
|
buttonProps: {
|
|
4363
4368
|
onMouseDown: (e) => {
|
|
4369
|
+
if (editLinkDisabled) return;
|
|
4364
4370
|
e.preventDefault();
|
|
4365
4371
|
e.stopPropagation();
|
|
4366
4372
|
onEditLink?.();
|
|
@@ -4747,8 +4753,8 @@ function MediaOverlay({
|
|
|
4747
4753
|
}
|
|
4748
4754
|
|
|
4749
4755
|
// src/OhhwellsBridge.tsx
|
|
4750
|
-
import { createPortal } from "react-dom";
|
|
4751
|
-
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
|
4756
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
4757
|
+
import { usePathname as usePathname2, useRouter as useRouter2, useSearchParams } from "next/navigation";
|
|
4752
4758
|
|
|
4753
4759
|
// src/lib/session-search.ts
|
|
4754
4760
|
var STORAGE_KEY = "ohw-preserved-search";
|
|
@@ -4778,6 +4784,7 @@ function parseSectionsFromRoot(root) {
|
|
|
4778
4784
|
for (const el of root.querySelectorAll("[data-ohw-section]")) {
|
|
4779
4785
|
const id = el.getAttribute("data-ohw-section") ?? "";
|
|
4780
4786
|
if (!id || seen.has(id)) continue;
|
|
4787
|
+
if (el.parentElement?.closest("[data-ohw-section]")) continue;
|
|
4781
4788
|
seen.add(id);
|
|
4782
4789
|
const label = el.getAttribute("data-ohw-section-label") ?? titleCaseSectionId(id);
|
|
4783
4790
|
sections.push({ id, label });
|
|
@@ -5024,61 +5031,29 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
5024
5031
|
tick();
|
|
5025
5032
|
}
|
|
5026
5033
|
|
|
5034
|
+
// src/ui/link-modal/LinkPopover.tsx
|
|
5035
|
+
import { useEffect as useEffect6 } from "react";
|
|
5036
|
+
|
|
5027
5037
|
// src/ui/dialog.tsx
|
|
5028
5038
|
import * as React7 from "react";
|
|
5029
5039
|
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
5030
|
-
|
|
5031
|
-
// src/ui/icons.tsx
|
|
5040
|
+
import { X } from "lucide-react";
|
|
5032
5041
|
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
5033
|
-
function
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
] });
|
|
5038
|
-
}
|
|
5039
|
-
function IconChevronDown({ className, ...props }) {
|
|
5040
|
-
return /* @__PURE__ */ jsx12("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ jsx12("path", { d: "m6 9 6 6 6-6" }) });
|
|
5041
|
-
}
|
|
5042
|
-
function IconFile({ className, ...props }) {
|
|
5043
|
-
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5044
|
-
/* @__PURE__ */ jsx12("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
5045
|
-
/* @__PURE__ */ jsx12("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
5046
|
-
] });
|
|
5047
|
-
}
|
|
5048
|
-
function IconInfo({ className, ...props }) {
|
|
5049
|
-
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5050
|
-
/* @__PURE__ */ jsx12("circle", { cx: "12", cy: "12", r: "10" }),
|
|
5051
|
-
/* @__PURE__ */ jsx12("path", { d: "M12 16v-4" }),
|
|
5052
|
-
/* @__PURE__ */ jsx12("path", { d: "M12 8h.01" })
|
|
5053
|
-
] });
|
|
5054
|
-
}
|
|
5055
|
-
function IconArrowRight({ className, ...props }) {
|
|
5056
|
-
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5057
|
-
/* @__PURE__ */ jsx12("path", { d: "M5 12h14" }),
|
|
5058
|
-
/* @__PURE__ */ jsx12("path", { d: "m12 5 7 7-7 7" })
|
|
5059
|
-
] });
|
|
5060
|
-
}
|
|
5061
|
-
function IconSection({ className, ...props }) {
|
|
5062
|
-
return /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5063
|
-
/* @__PURE__ */ jsx12("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
5064
|
-
/* @__PURE__ */ jsx12("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
5065
|
-
/* @__PURE__ */ jsx12("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
5066
|
-
] });
|
|
5067
|
-
}
|
|
5068
|
-
|
|
5069
|
-
// src/ui/dialog.tsx
|
|
5070
|
-
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5071
|
-
function Dialog2({ ...props }) {
|
|
5072
|
-
return /* @__PURE__ */ jsx13(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
5042
|
+
function Dialog2({
|
|
5043
|
+
...props
|
|
5044
|
+
}) {
|
|
5045
|
+
return /* @__PURE__ */ jsx12(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
5073
5046
|
}
|
|
5074
|
-
function DialogPortal({
|
|
5075
|
-
|
|
5047
|
+
function DialogPortal({
|
|
5048
|
+
...props
|
|
5049
|
+
}) {
|
|
5050
|
+
return /* @__PURE__ */ jsx12(DialogPrimitive.Portal, { ...props });
|
|
5076
5051
|
}
|
|
5077
5052
|
function DialogOverlay({
|
|
5078
5053
|
className,
|
|
5079
5054
|
...props
|
|
5080
5055
|
}) {
|
|
5081
|
-
return /* @__PURE__ */
|
|
5056
|
+
return /* @__PURE__ */ jsx12(
|
|
5082
5057
|
DialogPrimitive.Overlay,
|
|
5083
5058
|
{
|
|
5084
5059
|
"data-slot": "dialog-overlay",
|
|
@@ -5088,57 +5063,74 @@ function DialogOverlay({
|
|
|
5088
5063
|
}
|
|
5089
5064
|
);
|
|
5090
5065
|
}
|
|
5091
|
-
var DialogContent = React7.forwardRef(
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
/* @__PURE__ */
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
children
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
});
|
|
5066
|
+
var DialogContent = React7.forwardRef(
|
|
5067
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5068
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
5069
|
+
return /* @__PURE__ */ jsxs6(DialogPortal, { container: container ?? void 0, children: [
|
|
5070
|
+
/* @__PURE__ */ jsx12(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
5071
|
+
/* @__PURE__ */ jsxs6(
|
|
5072
|
+
DialogPrimitive.Content,
|
|
5073
|
+
{
|
|
5074
|
+
ref,
|
|
5075
|
+
"data-slot": "dialog-content",
|
|
5076
|
+
className: cn(
|
|
5077
|
+
positionMode,
|
|
5078
|
+
"left-1/2 top-1/2 z-[2147483647] flex w-full max-w-[448px] -translate-x-1/2 -translate-y-1/2 flex-col overflow-visible",
|
|
5079
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
5080
|
+
container ? "max-h-[calc(100%-32px)]" : "max-h-[calc(100vh-32px)]",
|
|
5081
|
+
className
|
|
5082
|
+
),
|
|
5083
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
5084
|
+
...props,
|
|
5085
|
+
children: [
|
|
5086
|
+
children,
|
|
5087
|
+
showCloseButton ? /* @__PURE__ */ jsx12(
|
|
5088
|
+
DialogPrimitive.Close,
|
|
5089
|
+
{
|
|
5090
|
+
type: "button",
|
|
5091
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5092
|
+
"aria-label": "Close",
|
|
5093
|
+
children: /* @__PURE__ */ jsx12(X, { size: 16, "aria-hidden": true })
|
|
5094
|
+
}
|
|
5095
|
+
) : null
|
|
5096
|
+
]
|
|
5097
|
+
}
|
|
5098
|
+
)
|
|
5099
|
+
] });
|
|
5100
|
+
}
|
|
5101
|
+
);
|
|
5125
5102
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
5126
|
-
function DialogHeader({
|
|
5127
|
-
|
|
5103
|
+
function DialogHeader({
|
|
5104
|
+
className,
|
|
5105
|
+
...props
|
|
5106
|
+
}) {
|
|
5107
|
+
return /* @__PURE__ */ jsx12("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
5128
5108
|
}
|
|
5129
|
-
function DialogFooter({
|
|
5130
|
-
|
|
5109
|
+
function DialogFooter({
|
|
5110
|
+
className,
|
|
5111
|
+
...props
|
|
5112
|
+
}) {
|
|
5113
|
+
return /* @__PURE__ */ jsx12(
|
|
5114
|
+
"div",
|
|
5115
|
+
{
|
|
5116
|
+
className: cn("flex items-center justify-end gap-2", className),
|
|
5117
|
+
...props
|
|
5118
|
+
}
|
|
5119
|
+
);
|
|
5131
5120
|
}
|
|
5132
|
-
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5121
|
+
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx12(
|
|
5133
5122
|
DialogPrimitive.Title,
|
|
5134
5123
|
{
|
|
5135
5124
|
ref,
|
|
5136
|
-
className: cn(
|
|
5125
|
+
className: cn(
|
|
5126
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
5127
|
+
className
|
|
5128
|
+
),
|
|
5137
5129
|
...props
|
|
5138
5130
|
}
|
|
5139
5131
|
));
|
|
5140
5132
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
5141
|
-
var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5133
|
+
var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx12(
|
|
5142
5134
|
DialogPrimitive.Description,
|
|
5143
5135
|
{
|
|
5144
5136
|
ref,
|
|
@@ -5149,38 +5141,64 @@ var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
5149
5141
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
5150
5142
|
var DialogClose = DialogPrimitive.Close;
|
|
5151
5143
|
|
|
5144
|
+
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5145
|
+
import { Info, X as X3 } from "lucide-react";
|
|
5146
|
+
|
|
5152
5147
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5153
|
-
import {
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5148
|
+
import { ArrowRight, File, GalleryVertical } from "lucide-react";
|
|
5149
|
+
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5150
|
+
function DestinationBreadcrumb({
|
|
5151
|
+
pageTitle,
|
|
5152
|
+
sectionLabel
|
|
5153
|
+
}) {
|
|
5154
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5155
|
+
/* @__PURE__ */ jsx13("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
|
|
5156
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3", children: [
|
|
5157
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
5158
|
+
/* @__PURE__ */ jsx13(File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5159
|
+
/* @__PURE__ */ jsx13("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
5161
5160
|
] }),
|
|
5162
|
-
/* @__PURE__ */
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5161
|
+
/* @__PURE__ */ jsx13(
|
|
5162
|
+
ArrowRight,
|
|
5163
|
+
{
|
|
5164
|
+
size: 16,
|
|
5165
|
+
className: "shrink-0 text-muted-foreground",
|
|
5166
|
+
"aria-hidden": true
|
|
5167
|
+
}
|
|
5168
|
+
),
|
|
5169
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5170
|
+
/* @__PURE__ */ jsx13(
|
|
5171
|
+
GalleryVertical,
|
|
5172
|
+
{
|
|
5173
|
+
size: 16,
|
|
5174
|
+
className: "shrink-0 text-foreground",
|
|
5175
|
+
"aria-hidden": true
|
|
5176
|
+
}
|
|
5177
|
+
),
|
|
5178
|
+
/* @__PURE__ */ jsx13("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
5166
5179
|
] })
|
|
5167
5180
|
] })
|
|
5168
5181
|
] });
|
|
5169
5182
|
}
|
|
5170
5183
|
|
|
5171
5184
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5172
|
-
import {
|
|
5173
|
-
|
|
5185
|
+
import { GalleryVertical as GalleryVertical2 } from "lucide-react";
|
|
5186
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5187
|
+
function SectionTreeItem({
|
|
5188
|
+
section,
|
|
5189
|
+
onSelect,
|
|
5190
|
+
selected
|
|
5191
|
+
}) {
|
|
5174
5192
|
const interactive = Boolean(onSelect);
|
|
5175
|
-
return /* @__PURE__ */
|
|
5176
|
-
/* @__PURE__ */
|
|
5193
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5194
|
+
/* @__PURE__ */ jsx14(
|
|
5177
5195
|
"div",
|
|
5178
5196
|
{
|
|
5179
5197
|
className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
5180
5198
|
"aria-hidden": true
|
|
5181
5199
|
}
|
|
5182
5200
|
),
|
|
5183
|
-
/* @__PURE__ */
|
|
5201
|
+
/* @__PURE__ */ jsxs8(
|
|
5184
5202
|
"div",
|
|
5185
5203
|
{
|
|
5186
5204
|
role: interactive ? "button" : void 0,
|
|
@@ -5198,32 +5216,30 @@ function SectionTreeItem({ section, onSelect, selected }) {
|
|
|
5198
5216
|
interactive && selected && "border-primary"
|
|
5199
5217
|
),
|
|
5200
5218
|
children: [
|
|
5201
|
-
/* @__PURE__ */
|
|
5202
|
-
|
|
5219
|
+
/* @__PURE__ */ jsx14(
|
|
5220
|
+
GalleryVertical2,
|
|
5221
|
+
{
|
|
5222
|
+
size: 16,
|
|
5223
|
+
className: "shrink-0 text-foreground",
|
|
5224
|
+
"aria-hidden": true
|
|
5225
|
+
}
|
|
5226
|
+
),
|
|
5227
|
+
/* @__PURE__ */ jsx14("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
5203
5228
|
]
|
|
5204
5229
|
}
|
|
5205
5230
|
)
|
|
5206
5231
|
] });
|
|
5207
5232
|
}
|
|
5208
|
-
function SectionPickerList({ sections, onSelect }) {
|
|
5209
|
-
if (sections.length === 0) {
|
|
5210
|
-
return /* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
|
|
5211
|
-
}
|
|
5212
|
-
return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-1", children: [
|
|
5213
|
-
/* @__PURE__ */ jsx15("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
|
|
5214
|
-
sections.map((section) => /* @__PURE__ */ jsx15(SectionTreeItem, { section, onSelect }, section.id))
|
|
5215
|
-
] });
|
|
5216
|
-
}
|
|
5217
5233
|
|
|
5218
5234
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5219
|
-
import { useId as useId2, useRef as useRef3, useState as useState3 } from "react";
|
|
5235
|
+
import { useEffect as useEffect3, useId as useId2, useRef as useRef3, useState as useState3 } from "react";
|
|
5220
5236
|
|
|
5221
5237
|
// src/ui/input.tsx
|
|
5222
5238
|
import * as React8 from "react";
|
|
5223
|
-
import { jsx as
|
|
5239
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
5224
5240
|
var Input = React8.forwardRef(
|
|
5225
5241
|
({ className, type, ...props }, ref) => {
|
|
5226
|
-
return /* @__PURE__ */
|
|
5242
|
+
return /* @__PURE__ */ jsx15(
|
|
5227
5243
|
"input",
|
|
5228
5244
|
{
|
|
5229
5245
|
type,
|
|
@@ -5242,9 +5258,9 @@ Input.displayName = "Input";
|
|
|
5242
5258
|
|
|
5243
5259
|
// src/ui/label.tsx
|
|
5244
5260
|
import { Label as LabelPrimitive } from "radix-ui";
|
|
5245
|
-
import { jsx as
|
|
5261
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
5246
5262
|
function Label({ className, ...props }) {
|
|
5247
|
-
return /* @__PURE__ */
|
|
5263
|
+
return /* @__PURE__ */ jsx16(
|
|
5248
5264
|
LabelPrimitive.Root,
|
|
5249
5265
|
{
|
|
5250
5266
|
"data-slot": "label",
|
|
@@ -5255,9 +5271,12 @@ function Label({ className, ...props }) {
|
|
|
5255
5271
|
}
|
|
5256
5272
|
|
|
5257
5273
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5258
|
-
import {
|
|
5259
|
-
|
|
5260
|
-
|
|
5274
|
+
import { ChevronDown, File as File2, X as X2 } from "lucide-react";
|
|
5275
|
+
import { jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
5276
|
+
function FieldChevron({
|
|
5277
|
+
onClick
|
|
5278
|
+
}) {
|
|
5279
|
+
return /* @__PURE__ */ jsx17(
|
|
5261
5280
|
"button",
|
|
5262
5281
|
{
|
|
5263
5282
|
type: "button",
|
|
@@ -5265,7 +5284,7 @@ function FieldChevron({ onClick }) {
|
|
|
5265
5284
|
onClick,
|
|
5266
5285
|
"aria-label": "Open page list",
|
|
5267
5286
|
tabIndex: -1,
|
|
5268
|
-
children: /* @__PURE__ */
|
|
5287
|
+
children: /* @__PURE__ */ jsx17(ChevronDown, { size: 16 })
|
|
5269
5288
|
}
|
|
5270
5289
|
);
|
|
5271
5290
|
}
|
|
@@ -5283,7 +5302,29 @@ function UrlOrPageInput({
|
|
|
5283
5302
|
}) {
|
|
5284
5303
|
const inputId = useId2();
|
|
5285
5304
|
const inputRef = useRef3(null);
|
|
5305
|
+
const rootRef = useRef3(null);
|
|
5286
5306
|
const [isFocused, setIsFocused] = useState3(false);
|
|
5307
|
+
useEffect3(() => {
|
|
5308
|
+
if (!dropdownOpen) return;
|
|
5309
|
+
const isOutside = (e) => {
|
|
5310
|
+
const root = rootRef.current;
|
|
5311
|
+
if (!root) return true;
|
|
5312
|
+
const path = typeof e.composedPath === "function" ? e.composedPath() : [];
|
|
5313
|
+
if (path.includes(root)) return false;
|
|
5314
|
+
const target = e.target;
|
|
5315
|
+
return !(target instanceof Node && root.contains(target));
|
|
5316
|
+
};
|
|
5317
|
+
const closeIfOutside = (e) => {
|
|
5318
|
+
if (!isOutside(e)) return;
|
|
5319
|
+
onDropdownOpenChange(false);
|
|
5320
|
+
};
|
|
5321
|
+
document.addEventListener("pointerdown", closeIfOutside, true);
|
|
5322
|
+
document.addEventListener("mousedown", closeIfOutside, true);
|
|
5323
|
+
return () => {
|
|
5324
|
+
document.removeEventListener("pointerdown", closeIfOutside, true);
|
|
5325
|
+
document.removeEventListener("mousedown", closeIfOutside, true);
|
|
5326
|
+
};
|
|
5327
|
+
}, [dropdownOpen, onDropdownOpenChange]);
|
|
5287
5328
|
const openDropdown = () => {
|
|
5288
5329
|
if (readOnly || filteredPages.length === 0) return;
|
|
5289
5330
|
onDropdownOpenChange(true);
|
|
@@ -5301,15 +5342,22 @@ function UrlOrPageInput({
|
|
|
5301
5342
|
requestAnimationFrame(() => inputRef.current?.focus());
|
|
5302
5343
|
};
|
|
5303
5344
|
const fieldClassName = cn(
|
|
5304
|
-
"data-ohw-link-field flex h-
|
|
5345
|
+
"data-ohw-link-field flex h-[36px] w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
|
|
5305
5346
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
5306
5347
|
);
|
|
5307
|
-
return /* @__PURE__ */
|
|
5308
|
-
/* @__PURE__ */
|
|
5309
|
-
/* @__PURE__ */
|
|
5310
|
-
/* @__PURE__ */
|
|
5311
|
-
selectedPage ? /* @__PURE__ */
|
|
5312
|
-
|
|
5348
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5349
|
+
/* @__PURE__ */ jsx17(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5350
|
+
/* @__PURE__ */ jsxs9("div", { ref: rootRef, className: "relative w-full", children: [
|
|
5351
|
+
/* @__PURE__ */ jsxs9("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5352
|
+
selectedPage ? /* @__PURE__ */ jsx17("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx17(
|
|
5353
|
+
File2,
|
|
5354
|
+
{
|
|
5355
|
+
size: 16,
|
|
5356
|
+
className: "shrink-0 text-foreground",
|
|
5357
|
+
"aria-hidden": true
|
|
5358
|
+
}
|
|
5359
|
+
) }) : null,
|
|
5360
|
+
readOnly ? /* @__PURE__ */ jsx17("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ jsx17(
|
|
5313
5361
|
Input,
|
|
5314
5362
|
{
|
|
5315
5363
|
ref: inputRef,
|
|
@@ -5320,7 +5368,14 @@ function UrlOrPageInput({
|
|
|
5320
5368
|
setIsFocused(true);
|
|
5321
5369
|
if (!selectedPage) openDropdown();
|
|
5322
5370
|
},
|
|
5323
|
-
onBlur: () =>
|
|
5371
|
+
onBlur: () => {
|
|
5372
|
+
setIsFocused(false);
|
|
5373
|
+
requestAnimationFrame(() => {
|
|
5374
|
+
if (!rootRef.current?.contains(document.activeElement)) {
|
|
5375
|
+
onDropdownOpenChange(false);
|
|
5376
|
+
}
|
|
5377
|
+
});
|
|
5378
|
+
},
|
|
5324
5379
|
placeholder,
|
|
5325
5380
|
className: cn(
|
|
5326
5381
|
"min-w-0 flex-1 truncate border-0 bg-transparent p-0 text-sm font-normal leading-5 shadow-none outline-none ring-0 caret-foreground",
|
|
@@ -5328,7 +5383,7 @@ function UrlOrPageInput({
|
|
|
5328
5383
|
)
|
|
5329
5384
|
}
|
|
5330
5385
|
),
|
|
5331
|
-
selectedPage && !readOnly ? /* @__PURE__ */
|
|
5386
|
+
selectedPage && !readOnly ? /* @__PURE__ */ jsx17(
|
|
5332
5387
|
"button",
|
|
5333
5388
|
{
|
|
5334
5389
|
type: "button",
|
|
@@ -5336,26 +5391,26 @@ function UrlOrPageInput({
|
|
|
5336
5391
|
onMouseDown: clearSelection,
|
|
5337
5392
|
"aria-label": "Clear selected page",
|
|
5338
5393
|
tabIndex: -1,
|
|
5339
|
-
children: /* @__PURE__ */
|
|
5394
|
+
children: /* @__PURE__ */ jsx17(X2, { size: 16, "aria-hidden": true })
|
|
5340
5395
|
}
|
|
5341
5396
|
) : null,
|
|
5342
|
-
!readOnly ? /* @__PURE__ */
|
|
5397
|
+
!readOnly ? /* @__PURE__ */ jsx17(FieldChevron, { onClick: toggleDropdown }) : null
|
|
5343
5398
|
] }),
|
|
5344
|
-
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */
|
|
5399
|
+
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ jsx17(
|
|
5345
5400
|
"div",
|
|
5346
5401
|
{
|
|
5347
5402
|
"data-ohw-link-page-dropdown": "",
|
|
5348
|
-
className: "absolute left-0 right-0
|
|
5403
|
+
className: "absolute left-0 right-0 top-[calc(100%+4px)] z-50 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
|
|
5349
5404
|
onMouseDown: (e) => e.preventDefault(),
|
|
5350
|
-
children: filteredPages.map((page) => /* @__PURE__ */
|
|
5405
|
+
children: filteredPages.map((page) => /* @__PURE__ */ jsxs9(
|
|
5351
5406
|
"button",
|
|
5352
5407
|
{
|
|
5353
5408
|
type: "button",
|
|
5354
5409
|
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",
|
|
5355
5410
|
onClick: () => onPageSelect(page),
|
|
5356
5411
|
children: [
|
|
5357
|
-
/* @__PURE__ */
|
|
5358
|
-
/* @__PURE__ */
|
|
5412
|
+
/* @__PURE__ */ jsx17(File2, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5413
|
+
/* @__PURE__ */ jsx17("span", { className: "truncate", children: page.title })
|
|
5359
5414
|
]
|
|
5360
5415
|
},
|
|
5361
5416
|
page.path
|
|
@@ -5363,111 +5418,542 @@ function UrlOrPageInput({
|
|
|
5363
5418
|
}
|
|
5364
5419
|
) : null
|
|
5365
5420
|
] }),
|
|
5366
|
-
urlError ? /* @__PURE__ */
|
|
5421
|
+
urlError ? /* @__PURE__ */ jsx17("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
|
|
5367
5422
|
] });
|
|
5368
5423
|
}
|
|
5369
5424
|
|
|
5370
|
-
// src/ui/link-modal/
|
|
5371
|
-
import {
|
|
5372
|
-
function
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
})
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5425
|
+
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5426
|
+
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
5427
|
+
function LinkEditorPanel({ state, onClose }) {
|
|
5428
|
+
const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
|
|
5429
|
+
return /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
5430
|
+
/* @__PURE__ */ jsx18(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx18(
|
|
5431
|
+
"button",
|
|
5432
|
+
{
|
|
5433
|
+
type: "button",
|
|
5434
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
|
|
5435
|
+
"aria-label": "Close",
|
|
5436
|
+
onClick: onClose,
|
|
5437
|
+
children: /* @__PURE__ */ jsx18(X3, { size: 16, "aria-hidden": true })
|
|
5438
|
+
}
|
|
5439
|
+
) }),
|
|
5440
|
+
/* @__PURE__ */ jsx18(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ jsx18(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5441
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5442
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx18(
|
|
5443
|
+
DestinationBreadcrumb,
|
|
5444
|
+
{
|
|
5445
|
+
pageTitle: state.selectedPage.title,
|
|
5446
|
+
sectionLabel: state.selectedSection.label
|
|
5447
|
+
}
|
|
5448
|
+
) : /* @__PURE__ */ jsx18(
|
|
5449
|
+
UrlOrPageInput,
|
|
5450
|
+
{
|
|
5451
|
+
value: state.searchValue,
|
|
5452
|
+
selectedPage: state.selectedPage,
|
|
5453
|
+
dropdownOpen: state.dropdownOpen,
|
|
5454
|
+
onDropdownOpenChange: state.setDropdownOpen,
|
|
5455
|
+
filteredPages: state.filteredPages,
|
|
5456
|
+
onInputChange: state.handleInputChange,
|
|
5457
|
+
onPageSelect: state.handlePageSelect,
|
|
5458
|
+
urlError: state.urlError
|
|
5459
|
+
}
|
|
5460
|
+
),
|
|
5461
|
+
state.showChooseSection ? /* @__PURE__ */ jsxs10("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5462
|
+
/* @__PURE__ */ jsx18(
|
|
5463
|
+
Button,
|
|
5464
|
+
{
|
|
5465
|
+
type: "button",
|
|
5466
|
+
variant: "outline",
|
|
5467
|
+
className: "w-fit cursor-pointer",
|
|
5468
|
+
size: "sm",
|
|
5469
|
+
onClick: state.handleChooseSection,
|
|
5470
|
+
children: "Choose a section"
|
|
5471
|
+
}
|
|
5472
|
+
),
|
|
5473
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5474
|
+
/* @__PURE__ */ jsx18(Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5475
|
+
/* @__PURE__ */ jsx18("span", { children: "Pick a section this link should scroll to." })
|
|
5476
|
+
] })
|
|
5477
|
+
] }) : null,
|
|
5478
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx18(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5479
|
+
] }),
|
|
5480
|
+
/* @__PURE__ */ jsxs10(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5481
|
+
/* @__PURE__ */ jsx18(
|
|
5482
|
+
Button,
|
|
5483
|
+
{
|
|
5484
|
+
type: "button",
|
|
5485
|
+
variant: isCancel ? "outline" : "ghost",
|
|
5486
|
+
className: "leading-6 shadow-none cursor-pointer",
|
|
5487
|
+
style: isCancel ? {
|
|
5488
|
+
backgroundColor: "var(--ohw-background)",
|
|
5489
|
+
borderColor: "var(--ohw-border)",
|
|
5490
|
+
color: "var(--ohw-foreground)"
|
|
5491
|
+
} : void 0,
|
|
5492
|
+
onClick: state.handleSecondary,
|
|
5493
|
+
children: state.secondaryLabel
|
|
5494
|
+
}
|
|
5495
|
+
),
|
|
5496
|
+
/* @__PURE__ */ jsx18(
|
|
5497
|
+
Button,
|
|
5498
|
+
{
|
|
5499
|
+
type: "button",
|
|
5500
|
+
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5501
|
+
style: {
|
|
5502
|
+
backgroundColor: "var(--ohw-primary)",
|
|
5503
|
+
color: "var(--ohw-primary-foreground)"
|
|
5504
|
+
},
|
|
5505
|
+
disabled: !state.isValid,
|
|
5506
|
+
onClick: state.handleSubmit,
|
|
5507
|
+
children: state.submitLabel
|
|
5508
|
+
}
|
|
5509
|
+
)
|
|
5510
|
+
] })
|
|
5511
|
+
] });
|
|
5512
|
+
}
|
|
5513
|
+
|
|
5514
|
+
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
5515
|
+
import { useCallback, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef4, useState as useState4 } from "react";
|
|
5516
|
+
import { createPortal } from "react-dom";
|
|
5517
|
+
import { ArrowLeft, Check } from "lucide-react";
|
|
5518
|
+
import { usePathname, useRouter } from "next/navigation";
|
|
5519
|
+
import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
5520
|
+
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
5521
|
+
function rectsEqual(a, b) {
|
|
5522
|
+
if (a.size !== b.size) return false;
|
|
5523
|
+
for (const [id, rect] of a) {
|
|
5524
|
+
const other = b.get(id);
|
|
5525
|
+
if (!other || rect.top !== other.top || rect.left !== other.left || rect.width !== other.width || rect.height !== other.height) {
|
|
5526
|
+
return false;
|
|
5413
5527
|
}
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
}
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
const
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
setStep("input");
|
|
5434
|
-
setUrlError("");
|
|
5435
|
-
const filtered = value.trim() ? availablePages.filter((p) => p.title.toLowerCase().startsWith(value.toLowerCase())) : availablePages;
|
|
5436
|
-
setDropdownOpen(filtered.length > 0);
|
|
5437
|
-
if (value.trim()) {
|
|
5438
|
-
setUrlError(validateUrlInput(value, availablePages, pages));
|
|
5528
|
+
}
|
|
5529
|
+
return true;
|
|
5530
|
+
}
|
|
5531
|
+
function readSectionRects(sectionIds) {
|
|
5532
|
+
const next = /* @__PURE__ */ new Map();
|
|
5533
|
+
for (const id of sectionIds) {
|
|
5534
|
+
const el = document.querySelector(
|
|
5535
|
+
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5536
|
+
);
|
|
5537
|
+
if (el) next.set(id, el.getBoundingClientRect());
|
|
5538
|
+
}
|
|
5539
|
+
return next;
|
|
5540
|
+
}
|
|
5541
|
+
function hitTestSectionId(x, y, sectionIds, rects) {
|
|
5542
|
+
for (const id of sectionIds) {
|
|
5543
|
+
const rect = rects.get(id);
|
|
5544
|
+
if (!rect || rect.width <= 0 || rect.height <= 0) continue;
|
|
5545
|
+
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
|
|
5546
|
+
return id;
|
|
5439
5547
|
}
|
|
5440
|
-
}
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
setSelectedSection({ id: section.id, label: section.label });
|
|
5454
|
-
if (mode === "create") {
|
|
5455
|
-
setStep("confirmed");
|
|
5456
|
-
} else {
|
|
5457
|
-
setStep("input");
|
|
5548
|
+
}
|
|
5549
|
+
return null;
|
|
5550
|
+
}
|
|
5551
|
+
function useSectionRects(sectionIdsKey, enabled) {
|
|
5552
|
+
const [rects, setRects] = useState4(/* @__PURE__ */ new Map());
|
|
5553
|
+
const sectionIds = useMemo2(
|
|
5554
|
+
() => sectionIdsKey ? sectionIdsKey.split("\0") : [],
|
|
5555
|
+
[sectionIdsKey]
|
|
5556
|
+
);
|
|
5557
|
+
useEffect4(() => {
|
|
5558
|
+
if (!enabled || sectionIds.length === 0) {
|
|
5559
|
+
setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
|
|
5560
|
+
return;
|
|
5458
5561
|
}
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5562
|
+
const update = () => {
|
|
5563
|
+
const next = readSectionRects(sectionIds);
|
|
5564
|
+
setRects((prev) => rectsEqual(prev, next) ? prev : next);
|
|
5565
|
+
};
|
|
5566
|
+
update();
|
|
5567
|
+
const opts = { capture: true, passive: true };
|
|
5568
|
+
window.addEventListener("scroll", update, opts);
|
|
5569
|
+
window.addEventListener("resize", update);
|
|
5570
|
+
const vv = window.visualViewport;
|
|
5571
|
+
vv?.addEventListener("resize", update);
|
|
5572
|
+
vv?.addEventListener("scroll", update);
|
|
5573
|
+
const ro = new ResizeObserver(update);
|
|
5574
|
+
for (const id of sectionIds) {
|
|
5575
|
+
const el = document.querySelector(
|
|
5576
|
+
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5577
|
+
);
|
|
5578
|
+
if (el) ro.observe(el);
|
|
5579
|
+
}
|
|
5580
|
+
return () => {
|
|
5581
|
+
window.removeEventListener("scroll", update, opts);
|
|
5582
|
+
window.removeEventListener("resize", update);
|
|
5583
|
+
vv?.removeEventListener("resize", update);
|
|
5584
|
+
vv?.removeEventListener("scroll", update);
|
|
5585
|
+
ro.disconnect();
|
|
5586
|
+
};
|
|
5587
|
+
}, [sectionIds, enabled]);
|
|
5588
|
+
return rects;
|
|
5589
|
+
}
|
|
5590
|
+
function SectionPickerOverlay({
|
|
5591
|
+
pagePath,
|
|
5592
|
+
sections,
|
|
5593
|
+
onBack,
|
|
5594
|
+
onSelect
|
|
5595
|
+
}) {
|
|
5596
|
+
const router = useRouter();
|
|
5597
|
+
const pathname = usePathname();
|
|
5598
|
+
const [selectedId, setSelectedId] = useState4(null);
|
|
5599
|
+
const [hoveredId, setHoveredId] = useState4(null);
|
|
5600
|
+
const pointerRef = useRef4(null);
|
|
5601
|
+
const pointerScreenRef = useRef4(null);
|
|
5602
|
+
const iframeOffsetTopRef = useRef4(null);
|
|
5603
|
+
const sectionIdsRef = useRef4([]);
|
|
5604
|
+
const [chromeClip, setChromeClip] = useState4(
|
|
5605
|
+
() => ({
|
|
5606
|
+
top: 0,
|
|
5607
|
+
bottom: typeof window !== "undefined" ? window.innerHeight : 0
|
|
5608
|
+
})
|
|
5609
|
+
);
|
|
5610
|
+
const normalizedTarget = normalizePath(pagePath);
|
|
5611
|
+
const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
|
|
5612
|
+
useEffect4(() => {
|
|
5613
|
+
if (isOnTargetPage) return;
|
|
5614
|
+
const search = readPreservedSearch();
|
|
5615
|
+
router.push(`${normalizedTarget}${search}`);
|
|
5616
|
+
}, [isOnTargetPage, normalizedTarget, router]);
|
|
5617
|
+
useEffect4(() => {
|
|
5618
|
+
document.documentElement.setAttribute("data-ohw-section-picking", "");
|
|
5619
|
+
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
|
|
5620
|
+
el.removeAttribute("data-ohw-hovered");
|
|
5621
|
+
});
|
|
5622
|
+
document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => {
|
|
5623
|
+
el.removeAttribute("data-ohw-state-hovered");
|
|
5624
|
+
});
|
|
5625
|
+
return () => {
|
|
5626
|
+
document.documentElement.removeAttribute("data-ohw-section-picking");
|
|
5627
|
+
};
|
|
5628
|
+
}, []);
|
|
5629
|
+
const liveSections = useMemo2(() => {
|
|
5630
|
+
if (!isOnTargetPage) return sections;
|
|
5631
|
+
const live = collectSectionsFromDom();
|
|
5632
|
+
if (live.length === 0) return sections;
|
|
5633
|
+
const labels = new Map(sections.map((s) => [s.id, s.label]));
|
|
5634
|
+
return live.map((s) => ({ id: s.id, label: labels.get(s.id) ?? s.label }));
|
|
5635
|
+
}, [isOnTargetPage, sections, pathname]);
|
|
5636
|
+
const sectionIdsKey = useMemo2(
|
|
5637
|
+
() => liveSections.map((s) => s.id).join("\0"),
|
|
5638
|
+
[liveSections]
|
|
5639
|
+
);
|
|
5640
|
+
const sectionIds = useMemo2(
|
|
5641
|
+
() => liveSections.map((s) => s.id),
|
|
5642
|
+
[liveSections]
|
|
5643
|
+
);
|
|
5644
|
+
sectionIdsRef.current = sectionIds;
|
|
5645
|
+
const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
|
|
5646
|
+
const applyHoverAt = useCallback(
|
|
5647
|
+
(x, y, liveRects) => {
|
|
5648
|
+
const ids = sectionIdsRef.current;
|
|
5649
|
+
const map = liveRects ?? readSectionRects(ids);
|
|
5650
|
+
const next = hitTestSectionId(x, y, ids, map);
|
|
5651
|
+
setHoveredId((prev) => prev === next ? prev : next);
|
|
5652
|
+
},
|
|
5653
|
+
[]
|
|
5654
|
+
);
|
|
5655
|
+
useEffect4(() => {
|
|
5656
|
+
const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH) => {
|
|
5657
|
+
const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
5658
|
+
const bottom = Math.min(
|
|
5659
|
+
window.innerHeight,
|
|
5660
|
+
visibleCanvasTop + canvasH - iframeOffsetTop
|
|
5661
|
+
);
|
|
5662
|
+
setChromeClip(
|
|
5663
|
+
(prev) => prev.top === top && prev.bottom === bottom ? prev : { top, bottom: Math.max(top, bottom) }
|
|
5664
|
+
);
|
|
5665
|
+
};
|
|
5666
|
+
const onParentScroll = (e) => {
|
|
5667
|
+
if (e.data?.type !== "ow:parent-scroll") return;
|
|
5668
|
+
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
5669
|
+
applyClip(iframeOffsetTop, headerH, canvasH);
|
|
5670
|
+
iframeOffsetTopRef.current = iframeOffsetTop;
|
|
5671
|
+
if (!pointerScreenRef.current && pointerRef.current) {
|
|
5672
|
+
pointerScreenRef.current = {
|
|
5673
|
+
x: pointerRef.current.x,
|
|
5674
|
+
y: pointerRef.current.y + iframeOffsetTop
|
|
5675
|
+
};
|
|
5676
|
+
}
|
|
5677
|
+
const screen = pointerScreenRef.current;
|
|
5678
|
+
if (screen) {
|
|
5679
|
+
const next = { x: screen.x, y: screen.y - iframeOffsetTop };
|
|
5680
|
+
pointerRef.current = next;
|
|
5681
|
+
applyHoverAt(next.x, next.y);
|
|
5682
|
+
}
|
|
5683
|
+
};
|
|
5684
|
+
const onResize = () => {
|
|
5685
|
+
setChromeClip((prev) => {
|
|
5686
|
+
const bottom = Math.max(prev.top, window.innerHeight);
|
|
5687
|
+
return prev.bottom === bottom ? prev : { ...prev, bottom };
|
|
5688
|
+
});
|
|
5689
|
+
};
|
|
5690
|
+
window.addEventListener("message", onParentScroll);
|
|
5691
|
+
window.addEventListener("resize", onResize);
|
|
5692
|
+
return () => {
|
|
5693
|
+
window.removeEventListener("message", onParentScroll);
|
|
5694
|
+
window.removeEventListener("resize", onResize);
|
|
5695
|
+
};
|
|
5696
|
+
}, [applyHoverAt]);
|
|
5697
|
+
useEffect4(() => {
|
|
5698
|
+
const ptr = pointerRef.current;
|
|
5699
|
+
if (!ptr) return;
|
|
5700
|
+
applyHoverAt(ptr.x, ptr.y, rects);
|
|
5701
|
+
}, [rects, applyHoverAt]);
|
|
5702
|
+
useEffect4(() => {
|
|
5703
|
+
const rememberPointer = (clientX, clientY) => {
|
|
5704
|
+
pointerRef.current = { x: clientX, y: clientY };
|
|
5705
|
+
const top = iframeOffsetTopRef.current;
|
|
5706
|
+
if (top != null) {
|
|
5707
|
+
pointerScreenRef.current = { x: clientX, y: clientY + top };
|
|
5708
|
+
}
|
|
5709
|
+
applyHoverAt(clientX, clientY, rects);
|
|
5710
|
+
};
|
|
5711
|
+
const onPointerMove = (e) => {
|
|
5712
|
+
rememberPointer(e.clientX, e.clientY);
|
|
5713
|
+
};
|
|
5714
|
+
const onPointerSync = (e) => {
|
|
5715
|
+
if (e.data?.type !== "ow:pointer-sync") return;
|
|
5716
|
+
const { clientX, clientY } = e.data;
|
|
5717
|
+
rememberPointer(clientX, clientY);
|
|
5718
|
+
};
|
|
5719
|
+
window.addEventListener("pointermove", onPointerMove, { passive: true });
|
|
5720
|
+
window.addEventListener("message", onPointerSync);
|
|
5721
|
+
return () => {
|
|
5722
|
+
window.removeEventListener("pointermove", onPointerMove);
|
|
5723
|
+
window.removeEventListener("message", onPointerSync);
|
|
5724
|
+
};
|
|
5725
|
+
}, [rects, applyHoverAt]);
|
|
5726
|
+
const handleSelect = useCallback(
|
|
5727
|
+
(section) => {
|
|
5728
|
+
if (selectedId) return;
|
|
5729
|
+
setSelectedId(section.id);
|
|
5730
|
+
onSelect(section);
|
|
5731
|
+
},
|
|
5732
|
+
[selectedId, onSelect]
|
|
5733
|
+
);
|
|
5734
|
+
useEffect4(() => {
|
|
5735
|
+
const onKeyDown = (e) => {
|
|
5736
|
+
if (e.key === "Escape") {
|
|
5737
|
+
e.preventDefault();
|
|
5738
|
+
e.stopPropagation();
|
|
5739
|
+
onBack();
|
|
5740
|
+
}
|
|
5741
|
+
};
|
|
5742
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
5743
|
+
return () => window.removeEventListener("keydown", onKeyDown, true);
|
|
5744
|
+
}, [onBack]);
|
|
5745
|
+
const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
|
|
5746
|
+
if (!portalRoot) return null;
|
|
5747
|
+
return createPortal(
|
|
5748
|
+
/* @__PURE__ */ jsxs11(
|
|
5749
|
+
"div",
|
|
5750
|
+
{
|
|
5751
|
+
"data-ohw-section-picker": "",
|
|
5752
|
+
"data-ohw-bridge": "",
|
|
5753
|
+
className: `pointer-events-none fixed inset-0 z-[2147483647] transition-opacity duration-200 ${"opacity-100"}`,
|
|
5754
|
+
"aria-modal": true,
|
|
5755
|
+
role: "dialog",
|
|
5756
|
+
"aria-label": "Choose a section",
|
|
5757
|
+
children: [
|
|
5758
|
+
/* @__PURE__ */ jsx19(
|
|
5759
|
+
"div",
|
|
5760
|
+
{
|
|
5761
|
+
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
5762
|
+
style: { top: chromeClip.top + 20 },
|
|
5763
|
+
children: /* @__PURE__ */ jsxs11(
|
|
5764
|
+
Button,
|
|
5765
|
+
{
|
|
5766
|
+
type: "button",
|
|
5767
|
+
variant: "outline",
|
|
5768
|
+
size: "sm",
|
|
5769
|
+
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
5770
|
+
onClick: onBack,
|
|
5771
|
+
children: [
|
|
5772
|
+
/* @__PURE__ */ jsx19(ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
5773
|
+
"Back"
|
|
5774
|
+
]
|
|
5775
|
+
}
|
|
5776
|
+
)
|
|
5777
|
+
}
|
|
5778
|
+
),
|
|
5779
|
+
/* @__PURE__ */ jsx19(
|
|
5780
|
+
"div",
|
|
5781
|
+
{
|
|
5782
|
+
className: "pointer-events-none fixed left-1/2 z-[2] rounded-lg px-4 py-3 text-xs leading-4 tracking-[0.18px] text-white shadow-md",
|
|
5783
|
+
style: {
|
|
5784
|
+
top: chromeClip.bottom - 20,
|
|
5785
|
+
transform: "translate(-50%, -100%)",
|
|
5786
|
+
backgroundColor: "var(--ohw-popover-foreground, #0c0a09)"
|
|
5787
|
+
},
|
|
5788
|
+
"data-ohw-section-picker-hint": "",
|
|
5789
|
+
children: "Click on section to select"
|
|
5790
|
+
}
|
|
5791
|
+
),
|
|
5792
|
+
!isOnTargetPage ? /* @__PURE__ */ jsx19(
|
|
5793
|
+
"div",
|
|
5794
|
+
{
|
|
5795
|
+
className: "pointer-events-none fixed left-1/2 z-[1] -translate-x-1/2 rounded-md bg-background/90 px-3 py-2 text-sm text-muted-foreground shadow-sm",
|
|
5796
|
+
style: { top: chromeClip.top + 64 },
|
|
5797
|
+
children: "Loading page preview\u2026"
|
|
5798
|
+
}
|
|
5799
|
+
) : null,
|
|
5800
|
+
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ jsx19("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ jsx19("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
|
|
5801
|
+
isOnTargetPage ? liveSections.map((section) => {
|
|
5802
|
+
const rect = rects.get(section.id);
|
|
5803
|
+
if (!rect || rect.width <= 0 || rect.height <= 0) return null;
|
|
5804
|
+
const isSelected = selectedId === section.id;
|
|
5805
|
+
const isHovered = hoveredId === section.id;
|
|
5806
|
+
const isLit = isSelected || isHovered;
|
|
5807
|
+
return /* @__PURE__ */ jsxs11(
|
|
5808
|
+
"button",
|
|
5809
|
+
{
|
|
5810
|
+
type: "button",
|
|
5811
|
+
className: "pointer-events-auto fixed z-[1] cursor-pointer border-0 bg-transparent p-0 transition-[background-color] duration-150",
|
|
5812
|
+
style: {
|
|
5813
|
+
top: rect.top,
|
|
5814
|
+
left: rect.left,
|
|
5815
|
+
width: rect.width,
|
|
5816
|
+
height: rect.height,
|
|
5817
|
+
backgroundColor: isLit ? "transparent" : DIM_OVERLAY
|
|
5818
|
+
},
|
|
5819
|
+
"aria-label": `Select section ${section.label}`,
|
|
5820
|
+
onClick: () => handleSelect(section),
|
|
5821
|
+
children: [
|
|
5822
|
+
isLit ? /* @__PURE__ */ jsx19(
|
|
5823
|
+
"span",
|
|
5824
|
+
{
|
|
5825
|
+
className: "pointer-events-none absolute",
|
|
5826
|
+
style: {
|
|
5827
|
+
inset: 4,
|
|
5828
|
+
borderRadius: "var(--radius, 6px)",
|
|
5829
|
+
border: "1.5px dashed var(--primary, #0885FE)",
|
|
5830
|
+
boxSizing: "border-box"
|
|
5831
|
+
},
|
|
5832
|
+
"aria-hidden": true
|
|
5833
|
+
}
|
|
5834
|
+
) : null,
|
|
5835
|
+
isSelected ? /* @__PURE__ */ jsx19(
|
|
5836
|
+
"span",
|
|
5837
|
+
{
|
|
5838
|
+
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
5839
|
+
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
5840
|
+
"aria-hidden": true,
|
|
5841
|
+
children: /* @__PURE__ */ jsx19(Check, { className: "size-5" })
|
|
5842
|
+
}
|
|
5843
|
+
) : null
|
|
5844
|
+
]
|
|
5845
|
+
},
|
|
5846
|
+
section.id
|
|
5847
|
+
);
|
|
5848
|
+
}) : null
|
|
5849
|
+
]
|
|
5850
|
+
}
|
|
5851
|
+
),
|
|
5852
|
+
portalRoot
|
|
5853
|
+
);
|
|
5854
|
+
}
|
|
5855
|
+
|
|
5856
|
+
// src/ui/link-modal/useLinkModalState.ts
|
|
5857
|
+
import { useCallback as useCallback2, useEffect as useEffect5, useMemo as useMemo3, useState as useState5 } from "react";
|
|
5858
|
+
function useLinkModalState({
|
|
5859
|
+
open,
|
|
5860
|
+
mode,
|
|
5861
|
+
pages,
|
|
5862
|
+
sections: _sections,
|
|
5863
|
+
sectionsByPath,
|
|
5864
|
+
initialTarget,
|
|
5865
|
+
existingTargets: _existingTargets,
|
|
5866
|
+
onClose,
|
|
5867
|
+
onSubmit
|
|
5868
|
+
}) {
|
|
5869
|
+
const availablePages = useMemo3(() => pages, [pages]);
|
|
5870
|
+
const [searchValue, setSearchValue] = useState5("");
|
|
5871
|
+
const [selectedPage, setSelectedPage] = useState5(null);
|
|
5872
|
+
const [selectedSection, setSelectedSection] = useState5(null);
|
|
5873
|
+
const [step, setStep] = useState5("input");
|
|
5874
|
+
const [dropdownOpen, setDropdownOpen] = useState5(false);
|
|
5875
|
+
const [urlError, setUrlError] = useState5("");
|
|
5876
|
+
const reset = useCallback2(() => {
|
|
5877
|
+
setSearchValue("");
|
|
5878
|
+
setSelectedPage(null);
|
|
5879
|
+
setSelectedSection(null);
|
|
5880
|
+
setStep("input");
|
|
5881
|
+
setDropdownOpen(false);
|
|
5882
|
+
setUrlError("");
|
|
5883
|
+
}, []);
|
|
5884
|
+
useEffect5(() => {
|
|
5885
|
+
if (!open) return;
|
|
5886
|
+
if (mode === "edit" && initialTarget) {
|
|
5887
|
+
const { pageRoute } = parseTarget(initialTarget);
|
|
5888
|
+
const targetSections = getSectionsForPath(sectionsByPath, pageRoute);
|
|
5889
|
+
const init = getEditModeInitialState(initialTarget, pages, targetSections);
|
|
5890
|
+
setSearchValue(init.searchValue);
|
|
5891
|
+
setSelectedPage(init.selectedPage);
|
|
5892
|
+
setSelectedSection(init.selectedSection);
|
|
5893
|
+
setStep(init.step);
|
|
5894
|
+
} else {
|
|
5895
|
+
reset();
|
|
5896
|
+
}
|
|
5897
|
+
setDropdownOpen(false);
|
|
5898
|
+
setUrlError("");
|
|
5899
|
+
}, [open, mode, initialTarget, reset]);
|
|
5900
|
+
const filteredPages = useMemo3(() => {
|
|
5901
|
+
if (!searchValue.trim()) return availablePages;
|
|
5902
|
+
return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
|
|
5903
|
+
}, [availablePages, searchValue]);
|
|
5904
|
+
const activeSections = useMemo3(() => {
|
|
5905
|
+
if (!selectedPage) return [];
|
|
5906
|
+
return getSectionsForPath(sectionsByPath, selectedPage.path);
|
|
5907
|
+
}, [selectedPage, sectionsByPath]);
|
|
5908
|
+
const showBreadcrumb = step === "confirmed" && selectedPage && selectedSection;
|
|
5909
|
+
const showSectionPicker = step === "sectionPicker" && selectedPage;
|
|
5910
|
+
const showSectionRow = mode === "edit" && selectedPage && selectedSection && step === "input";
|
|
5911
|
+
const showChooseSection = step === "input" && selectedPage && !selectedSection && !showSectionRow && activeSections.length > 0;
|
|
5912
|
+
const handleInputChange = (value) => {
|
|
5913
|
+
setSearchValue(value);
|
|
5914
|
+
setSelectedPage(null);
|
|
5915
|
+
setSelectedSection(null);
|
|
5916
|
+
setStep("input");
|
|
5917
|
+
setUrlError("");
|
|
5918
|
+
const filtered = value.trim() ? availablePages.filter((p) => p.title.toLowerCase().startsWith(value.toLowerCase())) : availablePages;
|
|
5919
|
+
setDropdownOpen(filtered.length > 0);
|
|
5920
|
+
if (value.trim()) {
|
|
5921
|
+
setUrlError(validateUrlInput(value, availablePages, pages));
|
|
5922
|
+
}
|
|
5923
|
+
};
|
|
5924
|
+
const handlePageSelect = (page) => {
|
|
5925
|
+
setSelectedPage({ path: page.path, title: page.title });
|
|
5926
|
+
setSelectedSection(null);
|
|
5927
|
+
setSearchValue(page.title);
|
|
5928
|
+
setStep("input");
|
|
5929
|
+
setDropdownOpen(false);
|
|
5930
|
+
setUrlError("");
|
|
5931
|
+
};
|
|
5932
|
+
const handleChooseSection = () => {
|
|
5933
|
+
setStep("sectionPicker");
|
|
5934
|
+
};
|
|
5935
|
+
const handleSectionSelect = (section) => {
|
|
5936
|
+
setSelectedSection({ id: section.id, label: section.label });
|
|
5937
|
+
if (mode === "create") {
|
|
5938
|
+
setStep("confirmed");
|
|
5939
|
+
} else {
|
|
5940
|
+
setStep("input");
|
|
5941
|
+
}
|
|
5942
|
+
};
|
|
5943
|
+
const handleBackToSections = () => {
|
|
5944
|
+
setStep("sectionPicker");
|
|
5945
|
+
};
|
|
5946
|
+
const handleSectionPickerBack = () => {
|
|
5947
|
+
setStep("input");
|
|
5948
|
+
};
|
|
5949
|
+
const handleClose = () => {
|
|
5950
|
+
reset();
|
|
5951
|
+
onClose();
|
|
5952
|
+
};
|
|
5953
|
+
const isValid = useMemo3(() => {
|
|
5954
|
+
if (urlError) return false;
|
|
5955
|
+
if (showBreadcrumb) return true;
|
|
5956
|
+
if (selectedPage) return true;
|
|
5471
5957
|
if (!searchValue.trim()) return false;
|
|
5472
5958
|
return validateUrlInput(searchValue, availablePages, pages) === "";
|
|
5473
5959
|
}, [urlError, showBreadcrumb, selectedPage, searchValue, availablePages, pages]);
|
|
@@ -5497,7 +5983,7 @@ function useLinkModalState({
|
|
|
5497
5983
|
onSubmit(normalizeUrl(searchValue));
|
|
5498
5984
|
handleClose();
|
|
5499
5985
|
};
|
|
5500
|
-
const submitLabel = mode === "edit" ? "Save" : "Create";
|
|
5986
|
+
const submitLabel = showBreadcrumb ? "Save" : mode === "edit" ? "Save" : "Create";
|
|
5501
5987
|
const title = mode === "edit" ? "Edit navigation item" : "Create navigation item";
|
|
5502
5988
|
const secondaryLabel = showBreadcrumb ? "Back to sections" : "Cancel";
|
|
5503
5989
|
const handleSecondary = showBreadcrumb ? handleBackToSections : handleClose;
|
|
@@ -5524,23 +6010,29 @@ function useLinkModalState({
|
|
|
5524
6010
|
handleChooseSection,
|
|
5525
6011
|
handleSectionSelect,
|
|
5526
6012
|
handleBackToSections,
|
|
6013
|
+
handleSectionPickerBack,
|
|
5527
6014
|
handleClose,
|
|
5528
6015
|
handleSecondary,
|
|
5529
6016
|
handleSubmit
|
|
5530
6017
|
};
|
|
5531
6018
|
}
|
|
5532
6019
|
|
|
5533
|
-
// src/ui/link-modal/
|
|
5534
|
-
import { Fragment as
|
|
5535
|
-
function
|
|
6020
|
+
// src/ui/link-modal/LinkPopover.tsx
|
|
6021
|
+
import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
6022
|
+
function postToParent(data) {
|
|
6023
|
+
window.parent?.postMessage(data, "*");
|
|
6024
|
+
}
|
|
6025
|
+
function LinkPopover({
|
|
5536
6026
|
open = true,
|
|
6027
|
+
panelRef,
|
|
6028
|
+
portalContainer,
|
|
6029
|
+
onClose,
|
|
5537
6030
|
mode = "create",
|
|
5538
6031
|
pages,
|
|
5539
6032
|
sections = [],
|
|
5540
6033
|
sectionsByPath,
|
|
5541
6034
|
initialTarget,
|
|
5542
6035
|
existingTargets = [],
|
|
5543
|
-
onClose,
|
|
5544
6036
|
onSubmit
|
|
5545
6037
|
}) {
|
|
5546
6038
|
const state = useLinkModalState({
|
|
@@ -5554,115 +6046,109 @@ function LinkEditorPanel({
|
|
|
5554
6046
|
onClose,
|
|
5555
6047
|
onSubmit
|
|
5556
6048
|
});
|
|
5557
|
-
const
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
6049
|
+
const sectionPickerActive = state.showSectionPicker && Boolean(state.selectedPage);
|
|
6050
|
+
useEffect6(() => {
|
|
6051
|
+
if (!open) return;
|
|
6052
|
+
if (sectionPickerActive) {
|
|
6053
|
+
postToParent({ type: "ui:unlock" });
|
|
6054
|
+
postToParent({ type: "ow:section-picker", active: true });
|
|
6055
|
+
document.documentElement.style.overflow = "";
|
|
6056
|
+
document.body.style.overflow = "";
|
|
6057
|
+
return () => {
|
|
6058
|
+
postToParent({ type: "ow:section-picker", active: false });
|
|
6059
|
+
};
|
|
6060
|
+
}
|
|
6061
|
+
postToParent({ type: "ow:section-picker", active: false });
|
|
6062
|
+
postToParent({ type: "ui:lock" });
|
|
6063
|
+
const html = document.documentElement;
|
|
6064
|
+
const body = document.body;
|
|
6065
|
+
const prevHtmlOverflow = html.style.overflow;
|
|
6066
|
+
const prevBodyOverflow = body.style.overflow;
|
|
6067
|
+
const prevHtmlOverscroll = html.style.overscrollBehavior;
|
|
6068
|
+
const prevBodyOverscroll = body.style.overscrollBehavior;
|
|
6069
|
+
html.style.overflow = "hidden";
|
|
6070
|
+
body.style.overflow = "hidden";
|
|
6071
|
+
html.style.overscrollBehavior = "none";
|
|
6072
|
+
body.style.overscrollBehavior = "none";
|
|
6073
|
+
const canScrollElement = (el, deltaY) => {
|
|
6074
|
+
const { overflowY } = getComputedStyle(el);
|
|
6075
|
+
if (overflowY !== "auto" && overflowY !== "scroll") return false;
|
|
6076
|
+
if (el.scrollHeight <= el.clientHeight + 1) return false;
|
|
6077
|
+
if (deltaY < 0) return el.scrollTop > 0;
|
|
6078
|
+
if (deltaY > 0)
|
|
6079
|
+
return el.scrollTop + el.clientHeight < el.scrollHeight - 1;
|
|
6080
|
+
return true;
|
|
6081
|
+
};
|
|
6082
|
+
const allowsInternalScroll = (e) => {
|
|
6083
|
+
const target = e.target;
|
|
6084
|
+
if (!(target instanceof Element)) return false;
|
|
6085
|
+
const scrollRoot = target.closest(
|
|
6086
|
+
"[data-ohw-link-page-dropdown], [data-ohw-allow-scroll]"
|
|
6087
|
+
);
|
|
6088
|
+
if (!scrollRoot) return false;
|
|
6089
|
+
const deltaY = e instanceof WheelEvent ? e.deltaY : 0;
|
|
6090
|
+
return canScrollElement(scrollRoot, deltaY);
|
|
6091
|
+
};
|
|
6092
|
+
const preventBackgroundScroll = (e) => {
|
|
6093
|
+
if (allowsInternalScroll(e)) return;
|
|
6094
|
+
e.preventDefault();
|
|
6095
|
+
};
|
|
6096
|
+
const scrollOpts = { passive: false, capture: true };
|
|
6097
|
+
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6098
|
+
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6099
|
+
return () => {
|
|
6100
|
+
postToParent({ type: "ui:unlock" });
|
|
6101
|
+
html.style.overflow = prevHtmlOverflow;
|
|
6102
|
+
body.style.overflow = prevBodyOverflow;
|
|
6103
|
+
html.style.overscrollBehavior = prevHtmlOverscroll;
|
|
6104
|
+
body.style.overscrollBehavior = prevBodyOverscroll;
|
|
6105
|
+
document.removeEventListener(
|
|
6106
|
+
"wheel",
|
|
6107
|
+
preventBackgroundScroll,
|
|
6108
|
+
scrollOpts
|
|
6109
|
+
);
|
|
6110
|
+
document.removeEventListener(
|
|
6111
|
+
"touchmove",
|
|
6112
|
+
preventBackgroundScroll,
|
|
6113
|
+
scrollOpts
|
|
6114
|
+
);
|
|
6115
|
+
};
|
|
6116
|
+
}, [open, sectionPickerActive]);
|
|
6117
|
+
return /* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
6118
|
+
/* @__PURE__ */ jsx20(
|
|
6119
|
+
Dialog2,
|
|
5561
6120
|
{
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
/* @__PURE__ */ jsx19(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
|
|
5591
|
-
/* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5592
|
-
/* @__PURE__ */ jsx19(IconInfo, { className: "shrink-0", "aria-hidden": true }),
|
|
5593
|
-
/* @__PURE__ */ jsx19("span", { children: "Pick a section this link should scroll to." })
|
|
5594
|
-
] })
|
|
5595
|
-
] }) : null,
|
|
5596
|
-
state.showSectionPicker ? /* @__PURE__ */ jsx19(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5597
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx19(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5598
|
-
] }),
|
|
5599
|
-
/* @__PURE__ */ jsxs11(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5600
|
-
/* @__PURE__ */ jsx19(
|
|
5601
|
-
Button,
|
|
5602
|
-
{
|
|
5603
|
-
type: "button",
|
|
5604
|
-
variant: isCancel ? "outline" : "ghost",
|
|
5605
|
-
className: "leading-6 shadow-none cursor-pointer",
|
|
5606
|
-
style: isCancel ? {
|
|
5607
|
-
backgroundColor: "var(--ohw-background)",
|
|
5608
|
-
borderColor: "var(--ohw-border)",
|
|
5609
|
-
color: "var(--ohw-foreground)"
|
|
5610
|
-
} : void 0,
|
|
5611
|
-
onClick: state.handleSecondary,
|
|
5612
|
-
children: state.secondaryLabel
|
|
5613
|
-
}
|
|
5614
|
-
),
|
|
5615
|
-
/* @__PURE__ */ jsx19(
|
|
5616
|
-
Button,
|
|
5617
|
-
{
|
|
5618
|
-
type: "button",
|
|
5619
|
-
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5620
|
-
style: {
|
|
5621
|
-
backgroundColor: "var(--ohw-primary)",
|
|
5622
|
-
color: "var(--ohw-primary-foreground)"
|
|
5623
|
-
},
|
|
5624
|
-
disabled: !state.isValid,
|
|
5625
|
-
onClick: state.handleSubmit,
|
|
5626
|
-
children: state.submitLabel
|
|
5627
|
-
}
|
|
5628
|
-
)
|
|
5629
|
-
] })
|
|
6121
|
+
open: open && !sectionPickerActive,
|
|
6122
|
+
onOpenChange: (next) => {
|
|
6123
|
+
if (!next) onClose?.();
|
|
6124
|
+
},
|
|
6125
|
+
children: /* @__PURE__ */ jsx20(
|
|
6126
|
+
DialogContent,
|
|
6127
|
+
{
|
|
6128
|
+
ref: panelRef,
|
|
6129
|
+
container: portalContainer,
|
|
6130
|
+
"data-ohw-link-popover-root": "",
|
|
6131
|
+
"data-ohw-link-modal-root": "",
|
|
6132
|
+
"data-ohw-bridge": "",
|
|
6133
|
+
showCloseButton: false,
|
|
6134
|
+
className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
|
|
6135
|
+
children: /* @__PURE__ */ jsx20(LinkEditorPanel, { state, onClose })
|
|
6136
|
+
}
|
|
6137
|
+
)
|
|
6138
|
+
}
|
|
6139
|
+
),
|
|
6140
|
+
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ jsx20(
|
|
6141
|
+
SectionPickerOverlay,
|
|
6142
|
+
{
|
|
6143
|
+
pagePath: state.selectedPage.path,
|
|
6144
|
+
sections: state.activeSections,
|
|
6145
|
+
onBack: state.handleSectionPickerBack,
|
|
6146
|
+
onSelect: state.handleSectionSelect
|
|
6147
|
+
}
|
|
6148
|
+
) : null
|
|
5630
6149
|
] });
|
|
5631
6150
|
}
|
|
5632
6151
|
|
|
5633
|
-
// src/ui/link-modal/LinkPopover.tsx
|
|
5634
|
-
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
5635
|
-
function LinkPopover({
|
|
5636
|
-
open = true,
|
|
5637
|
-
panelRef,
|
|
5638
|
-
portalContainer,
|
|
5639
|
-
onClose,
|
|
5640
|
-
...editorProps
|
|
5641
|
-
}) {
|
|
5642
|
-
return /* @__PURE__ */ jsx20(
|
|
5643
|
-
Dialog2,
|
|
5644
|
-
{
|
|
5645
|
-
open,
|
|
5646
|
-
onOpenChange: (next) => {
|
|
5647
|
-
if (!next) onClose?.();
|
|
5648
|
-
},
|
|
5649
|
-
children: /* @__PURE__ */ jsx20(
|
|
5650
|
-
DialogContent,
|
|
5651
|
-
{
|
|
5652
|
-
ref: panelRef,
|
|
5653
|
-
container: portalContainer,
|
|
5654
|
-
"data-ohw-link-popover-root": "",
|
|
5655
|
-
"data-ohw-link-modal-root": "",
|
|
5656
|
-
"data-ohw-bridge": "",
|
|
5657
|
-
showCloseButton: false,
|
|
5658
|
-
className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
|
|
5659
|
-
children: /* @__PURE__ */ jsx20(LinkEditorPanel, { ...editorProps, open, onClose })
|
|
5660
|
-
}
|
|
5661
|
-
)
|
|
5662
|
-
}
|
|
5663
|
-
);
|
|
5664
|
-
}
|
|
5665
|
-
|
|
5666
6152
|
// src/ui/link-modal/devFixtures.ts
|
|
5667
6153
|
var DEV_SITE_PAGES = [
|
|
5668
6154
|
{ path: "/", title: "Home" },
|
|
@@ -5682,16 +6168,21 @@ var DEV_SECTIONS_BY_PATH = {
|
|
|
5682
6168
|
{ id: "founder-teaser", label: "Founder" },
|
|
5683
6169
|
{ id: "plan-form", label: "Plan Form" },
|
|
5684
6170
|
{ id: "testimonials", label: "Testimonials" },
|
|
5685
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
6171
|
+
{ id: "wordmark", label: "Wordmark" },
|
|
6172
|
+
{ id: "footer", label: "Footer" }
|
|
5686
6173
|
],
|
|
5687
6174
|
"/about": [
|
|
5688
6175
|
{ id: "manifesto", label: "Manifesto" },
|
|
5689
6176
|
{ id: "story-letter", label: "Our Story" },
|
|
5690
6177
|
{ id: "lagree-explainer", label: "Lagree Explainer" },
|
|
5691
6178
|
{ id: "waitlist-cta", label: "Waitlist" },
|
|
5692
|
-
{ id: "personal-training", label: "Personal training" }
|
|
6179
|
+
{ id: "personal-training", label: "Personal training" },
|
|
6180
|
+
{ id: "footer", label: "Footer" }
|
|
6181
|
+
],
|
|
6182
|
+
"/classes": [
|
|
6183
|
+
{ id: "class-library", label: "Class Library" },
|
|
6184
|
+
{ id: "footer", label: "Footer" }
|
|
5693
6185
|
],
|
|
5694
|
-
"/classes": [{ id: "class-library", label: "Class Library" }],
|
|
5695
6186
|
"/pricing": [
|
|
5696
6187
|
{ id: "page-header", label: "Page Header" },
|
|
5697
6188
|
{ id: "free-class-cta", label: "Free Class" },
|
|
@@ -5699,19 +6190,25 @@ var DEV_SECTIONS_BY_PATH = {
|
|
|
5699
6190
|
{ id: "monthly-memberships", label: "Memberships" },
|
|
5700
6191
|
{ id: "specialty-programs", label: "Specialty Programs" },
|
|
5701
6192
|
{ id: "package-matcher", label: "Packages" },
|
|
5702
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
6193
|
+
{ id: "wordmark", label: "Wordmark" },
|
|
6194
|
+
{ id: "footer", label: "Footer" }
|
|
5703
6195
|
],
|
|
5704
6196
|
"/studio": [
|
|
5705
6197
|
{ id: "studio-intro", label: "Studio Intro" },
|
|
5706
6198
|
{ id: "studio-features", label: "Studio Features" },
|
|
5707
6199
|
{ id: "studio-gallery", label: "Studio Gallery" },
|
|
5708
|
-
{ id: "studio-visit", label: "Visit Studio" }
|
|
6200
|
+
{ id: "studio-visit", label: "Visit Studio" },
|
|
6201
|
+
{ id: "footer", label: "Footer" }
|
|
6202
|
+
],
|
|
6203
|
+
"/instructors": [
|
|
6204
|
+
{ id: "instructor-grid", label: "Instructors" },
|
|
6205
|
+
{ id: "footer", label: "Footer" }
|
|
5709
6206
|
],
|
|
5710
|
-
"/instructors": [{ id: "instructor-grid", label: "Instructors" }],
|
|
5711
6207
|
"/contact": [
|
|
5712
6208
|
{ id: "hello-hero", label: "Hello" },
|
|
5713
6209
|
{ id: "contact-form", label: "Contact Form" },
|
|
5714
|
-
{ id: "faq", label: "FAQ" }
|
|
6210
|
+
{ id: "faq", label: "FAQ" },
|
|
6211
|
+
{ id: "footer", label: "Footer" }
|
|
5715
6212
|
]
|
|
5716
6213
|
};
|
|
5717
6214
|
function shouldUseDevFixtures() {
|
|
@@ -5721,8 +6218,277 @@ function shouldUseDevFixtures() {
|
|
|
5721
6218
|
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
5722
6219
|
}
|
|
5723
6220
|
|
|
5724
|
-
// src/
|
|
6221
|
+
// src/lib/nav-items.ts
|
|
6222
|
+
var NAV_COUNT_KEY = "__ohw_nav_count";
|
|
6223
|
+
var NAV_ORDER_KEY = "__ohw_nav_order";
|
|
6224
|
+
function getLinkHref(el) {
|
|
6225
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
6226
|
+
if (key) {
|
|
6227
|
+
const stored = getStoredLinkHref(key);
|
|
6228
|
+
if (stored !== void 0) return stored;
|
|
6229
|
+
}
|
|
6230
|
+
return el.getAttribute("href") ?? "";
|
|
6231
|
+
}
|
|
6232
|
+
function isNavbarButton(el) {
|
|
6233
|
+
return el.hasAttribute("data-ohw-role") && el.getAttribute("data-ohw-role") === "navbar-button";
|
|
6234
|
+
}
|
|
6235
|
+
function isNavbarLinkItem(el) {
|
|
6236
|
+
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6237
|
+
if (isNavbarButton(el)) return false;
|
|
6238
|
+
if (!el.querySelector('[data-ohw-editable="text"]')) return false;
|
|
6239
|
+
return Boolean(el.closest("nav, [data-ohw-nav-container], [data-ohw-nav-drawer]"));
|
|
6240
|
+
}
|
|
6241
|
+
function getNavbarDesktopContainer() {
|
|
6242
|
+
return document.querySelector("[data-ohw-nav-container]");
|
|
6243
|
+
}
|
|
6244
|
+
function getNavbarDrawerContainer() {
|
|
6245
|
+
return document.querySelector("[data-ohw-nav-drawer]");
|
|
6246
|
+
}
|
|
6247
|
+
function listNavbarItems() {
|
|
6248
|
+
const desktop = getNavbarDesktopContainer();
|
|
6249
|
+
if (desktop) {
|
|
6250
|
+
return Array.from(desktop.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6251
|
+
}
|
|
6252
|
+
const drawer = getNavbarDrawerContainer();
|
|
6253
|
+
if (drawer) {
|
|
6254
|
+
return Array.from(drawer.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6255
|
+
}
|
|
6256
|
+
return Array.from(document.querySelectorAll("nav [data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6257
|
+
}
|
|
6258
|
+
function parseNavIndexFromKey(key) {
|
|
6259
|
+
if (!key) return null;
|
|
6260
|
+
const match = key.match(/^nav-(\d+)-href$/);
|
|
6261
|
+
if (!match) return null;
|
|
6262
|
+
return parseInt(match[1], 10);
|
|
6263
|
+
}
|
|
6264
|
+
function getNavbarIndicesInDom() {
|
|
6265
|
+
const indices = /* @__PURE__ */ new Set();
|
|
6266
|
+
for (const item of listNavbarItems()) {
|
|
6267
|
+
const idx = parseNavIndexFromKey(item.getAttribute("data-ohw-href-key"));
|
|
6268
|
+
if (idx !== null) indices.add(idx);
|
|
6269
|
+
}
|
|
6270
|
+
return [...indices].sort((a, b) => a - b);
|
|
6271
|
+
}
|
|
6272
|
+
function getNextNavbarIndex() {
|
|
6273
|
+
const indices = getNavbarIndicesInDom();
|
|
6274
|
+
if (indices.length === 0) return 0;
|
|
6275
|
+
return Math.max(...indices) + 1;
|
|
6276
|
+
}
|
|
6277
|
+
function getNavbarExistingTargets() {
|
|
6278
|
+
return listNavbarItems().map((el) => getLinkHref(el)).filter(Boolean);
|
|
6279
|
+
}
|
|
6280
|
+
function getNavOrderFromDom() {
|
|
6281
|
+
return listNavbarItems().map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6282
|
+
}
|
|
6283
|
+
function parseNavOrder(content) {
|
|
6284
|
+
const raw = content[NAV_ORDER_KEY];
|
|
6285
|
+
if (!raw) return null;
|
|
6286
|
+
try {
|
|
6287
|
+
const parsed = JSON.parse(raw);
|
|
6288
|
+
if (!Array.isArray(parsed)) return null;
|
|
6289
|
+
return parsed.filter((key) => typeof key === "string" && key.length > 0);
|
|
6290
|
+
} catch {
|
|
6291
|
+
return null;
|
|
6292
|
+
}
|
|
6293
|
+
}
|
|
6294
|
+
function findCounterpartByHrefKey(hrefKey, root) {
|
|
6295
|
+
return root.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
6296
|
+
}
|
|
6297
|
+
function cloneNavLinkShell(template) {
|
|
6298
|
+
const anchor = document.createElement("a");
|
|
6299
|
+
if (template) {
|
|
6300
|
+
anchor.style.cssText = template.style.cssText;
|
|
6301
|
+
if (template.className) anchor.className = template.className;
|
|
6302
|
+
}
|
|
6303
|
+
anchor.style.cursor = "pointer";
|
|
6304
|
+
anchor.style.textDecoration = "none";
|
|
6305
|
+
return anchor;
|
|
6306
|
+
}
|
|
6307
|
+
function buildNavLink(index, href, label, template) {
|
|
6308
|
+
const anchor = cloneNavLinkShell(template);
|
|
6309
|
+
anchor.href = href;
|
|
6310
|
+
anchor.setAttribute("data-ohw-href-key", `nav-${index}-href`);
|
|
6311
|
+
const span = document.createElement("span");
|
|
6312
|
+
span.setAttribute("data-ohw-editable", "text");
|
|
6313
|
+
span.setAttribute("data-ohw-key", `nav-${index}-label`);
|
|
6314
|
+
span.textContent = label;
|
|
6315
|
+
anchor.appendChild(span);
|
|
6316
|
+
return anchor;
|
|
6317
|
+
}
|
|
6318
|
+
function insertNavLinkInContainer(container, anchor, afterHrefKey) {
|
|
6319
|
+
if (!afterHrefKey) {
|
|
6320
|
+
container.appendChild(anchor);
|
|
6321
|
+
return;
|
|
6322
|
+
}
|
|
6323
|
+
const afterEl = findCounterpartByHrefKey(afterHrefKey, container);
|
|
6324
|
+
if (afterEl?.parentElement === container) {
|
|
6325
|
+
afterEl.insertAdjacentElement("afterend", anchor);
|
|
6326
|
+
return;
|
|
6327
|
+
}
|
|
6328
|
+
container.appendChild(anchor);
|
|
6329
|
+
}
|
|
6330
|
+
function insertNavbarItemDom(index, href, label, afterAnchor) {
|
|
6331
|
+
const afterHrefKey = afterAnchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
6332
|
+
const desktopItems = getNavbarDesktopContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6333
|
+
const drawerItems = getNavbarDrawerContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6334
|
+
const desktopTemplate = Array.from(desktopItems).find(isNavbarLinkItem) ?? null;
|
|
6335
|
+
const drawerTemplate = Array.from(drawerItems).find(isNavbarLinkItem) ?? null;
|
|
6336
|
+
let primary = null;
|
|
6337
|
+
const desktopContainer = getNavbarDesktopContainer();
|
|
6338
|
+
if (desktopContainer) {
|
|
6339
|
+
const desktopAnchor = buildNavLink(index, href, label, desktopTemplate);
|
|
6340
|
+
insertNavLinkInContainer(desktopContainer, desktopAnchor, afterHrefKey);
|
|
6341
|
+
primary = desktopAnchor;
|
|
6342
|
+
}
|
|
6343
|
+
const drawerContainer = getNavbarDrawerContainer();
|
|
6344
|
+
if (drawerContainer) {
|
|
6345
|
+
const drawerAnchor = buildNavLink(index, href, label, drawerTemplate);
|
|
6346
|
+
insertNavLinkInContainer(drawerContainer, drawerAnchor, afterHrefKey);
|
|
6347
|
+
if (!primary) primary = drawerAnchor;
|
|
6348
|
+
}
|
|
6349
|
+
if (!primary) {
|
|
6350
|
+
const fallback = buildNavLink(index, href, label, listNavbarItems()[0] ?? null);
|
|
6351
|
+
const nav = document.querySelector("nav");
|
|
6352
|
+
nav?.appendChild(fallback);
|
|
6353
|
+
primary = fallback;
|
|
6354
|
+
}
|
|
6355
|
+
return primary;
|
|
6356
|
+
}
|
|
6357
|
+
function applyNavOrderToContainer(container, order) {
|
|
6358
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6359
|
+
for (const hrefKey of order) {
|
|
6360
|
+
if (seen.has(hrefKey)) continue;
|
|
6361
|
+
seen.add(hrefKey);
|
|
6362
|
+
const el = findCounterpartByHrefKey(hrefKey, container);
|
|
6363
|
+
if (el) container.appendChild(el);
|
|
6364
|
+
}
|
|
6365
|
+
for (const el of container.querySelectorAll("[data-ohw-href-key]")) {
|
|
6366
|
+
if (!isNavbarLinkItem(el)) continue;
|
|
6367
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
6368
|
+
if (!key || seen.has(key)) continue;
|
|
6369
|
+
container.appendChild(el);
|
|
6370
|
+
}
|
|
6371
|
+
}
|
|
6372
|
+
function applyNavOrder(order) {
|
|
6373
|
+
const desktop = getNavbarDesktopContainer();
|
|
6374
|
+
if (desktop) applyNavOrderToContainer(desktop, order);
|
|
6375
|
+
const drawer = getNavbarDrawerContainer();
|
|
6376
|
+
if (drawer) applyNavOrderToContainer(drawer, order);
|
|
6377
|
+
}
|
|
6378
|
+
function collectNavbarIndicesFromContent(content) {
|
|
6379
|
+
const indices = /* @__PURE__ */ new Set();
|
|
6380
|
+
for (const key of Object.keys(content)) {
|
|
6381
|
+
const idx = parseNavIndexFromKey(key);
|
|
6382
|
+
if (idx !== null) indices.add(idx);
|
|
6383
|
+
}
|
|
6384
|
+
const countRaw = content[NAV_COUNT_KEY];
|
|
6385
|
+
if (countRaw) {
|
|
6386
|
+
const count = parseInt(countRaw, 10);
|
|
6387
|
+
if (Number.isFinite(count) && count > 0) {
|
|
6388
|
+
for (let i = 0; i < count; i++) indices.add(i);
|
|
6389
|
+
}
|
|
6390
|
+
}
|
|
6391
|
+
return [...indices].sort((a, b) => a - b);
|
|
6392
|
+
}
|
|
6393
|
+
function navbarIndexExistsInDom(index) {
|
|
6394
|
+
return document.querySelector(`[data-ohw-href-key="nav-${index}-href"]`) !== null;
|
|
6395
|
+
}
|
|
6396
|
+
function reconcileNavbarItemsFromContent(content) {
|
|
6397
|
+
const indices = collectNavbarIndicesFromContent(content);
|
|
6398
|
+
for (const index of indices) {
|
|
6399
|
+
if (navbarIndexExistsInDom(index)) continue;
|
|
6400
|
+
const href = content[`nav-${index}-href`];
|
|
6401
|
+
const label = content[`nav-${index}-label`];
|
|
6402
|
+
if (!href && !label) continue;
|
|
6403
|
+
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
6404
|
+
}
|
|
6405
|
+
const order = parseNavOrder(content);
|
|
6406
|
+
if (order?.length) applyNavOrder(order);
|
|
6407
|
+
}
|
|
6408
|
+
function buildNavOrderAfterInsert(afterAnchor, newHrefKey) {
|
|
6409
|
+
const order = getNavOrderFromDom();
|
|
6410
|
+
if (!afterAnchor) {
|
|
6411
|
+
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6412
|
+
return order;
|
|
6413
|
+
}
|
|
6414
|
+
const afterKey = afterAnchor.getAttribute("data-ohw-href-key");
|
|
6415
|
+
if (!afterKey) {
|
|
6416
|
+
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6417
|
+
return order;
|
|
6418
|
+
}
|
|
6419
|
+
const withoutNew = order.filter((key) => key !== newHrefKey);
|
|
6420
|
+
const pos = withoutNew.indexOf(afterKey);
|
|
6421
|
+
if (pos >= 0) {
|
|
6422
|
+
withoutNew.splice(pos + 1, 0, newHrefKey);
|
|
6423
|
+
return withoutNew;
|
|
6424
|
+
}
|
|
6425
|
+
withoutNew.push(newHrefKey);
|
|
6426
|
+
return withoutNew;
|
|
6427
|
+
}
|
|
6428
|
+
function insertNavbarItem(href, label, afterAnchor = null) {
|
|
6429
|
+
const index = getNextNavbarIndex();
|
|
6430
|
+
const anchor = insertNavbarItemDom(index, href, label, afterAnchor);
|
|
6431
|
+
if (!anchor) throw new Error("Failed to insert navbar item");
|
|
6432
|
+
const hrefKey = `nav-${index}-href`;
|
|
6433
|
+
const order = buildNavOrderAfterInsert(afterAnchor, hrefKey);
|
|
6434
|
+
applyNavOrder(order);
|
|
6435
|
+
return {
|
|
6436
|
+
anchor,
|
|
6437
|
+
index,
|
|
6438
|
+
hrefKey,
|
|
6439
|
+
labelKey: `nav-${index}-label`,
|
|
6440
|
+
href,
|
|
6441
|
+
label,
|
|
6442
|
+
order
|
|
6443
|
+
};
|
|
6444
|
+
}
|
|
6445
|
+
|
|
6446
|
+
// src/ui/navbar-container-chrome.tsx
|
|
6447
|
+
import { Plus as Plus2 } from "lucide-react";
|
|
5725
6448
|
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
6449
|
+
function NavbarContainerChrome({
|
|
6450
|
+
rect,
|
|
6451
|
+
onAdd
|
|
6452
|
+
}) {
|
|
6453
|
+
const chromeGap = 6;
|
|
6454
|
+
return /* @__PURE__ */ jsx21(
|
|
6455
|
+
"div",
|
|
6456
|
+
{
|
|
6457
|
+
"data-ohw-navbar-container-chrome": "",
|
|
6458
|
+
"data-ohw-bridge": "",
|
|
6459
|
+
className: "pointer-events-none fixed z-[2147483647]",
|
|
6460
|
+
style: {
|
|
6461
|
+
top: rect.top - chromeGap,
|
|
6462
|
+
left: rect.left - chromeGap,
|
|
6463
|
+
width: rect.width + chromeGap * 2,
|
|
6464
|
+
height: rect.height + chromeGap * 2
|
|
6465
|
+
},
|
|
6466
|
+
children: /* @__PURE__ */ jsx21(
|
|
6467
|
+
"button",
|
|
6468
|
+
{
|
|
6469
|
+
type: "button",
|
|
6470
|
+
"data-ohw-navbar-add-button": "",
|
|
6471
|
+
className: "pointer-events-auto absolute left-1/2 flex p-0.5 rounded-[10px] size-7 -translate-x-1/2 translate-y-1/2 items-center justify-center border border-border bg-background shadow-sm transition-colors hover:bg-muted/80",
|
|
6472
|
+
style: { top: "70%" },
|
|
6473
|
+
"aria-label": "Add item",
|
|
6474
|
+
onMouseDown: (e) => {
|
|
6475
|
+
e.preventDefault();
|
|
6476
|
+
e.stopPropagation();
|
|
6477
|
+
},
|
|
6478
|
+
onClick: (e) => {
|
|
6479
|
+
e.preventDefault();
|
|
6480
|
+
e.stopPropagation();
|
|
6481
|
+
onAdd();
|
|
6482
|
+
},
|
|
6483
|
+
children: /* @__PURE__ */ jsx21(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
6484
|
+
}
|
|
6485
|
+
)
|
|
6486
|
+
}
|
|
6487
|
+
);
|
|
6488
|
+
}
|
|
6489
|
+
|
|
6490
|
+
// src/ui/badge.tsx
|
|
6491
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
5726
6492
|
var badgeVariants = cva(
|
|
5727
6493
|
"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",
|
|
5728
6494
|
{
|
|
@@ -5740,12 +6506,12 @@ var badgeVariants = cva(
|
|
|
5740
6506
|
}
|
|
5741
6507
|
);
|
|
5742
6508
|
function Badge({ className, variant, ...props }) {
|
|
5743
|
-
return /* @__PURE__ */
|
|
6509
|
+
return /* @__PURE__ */ jsx22("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
5744
6510
|
}
|
|
5745
6511
|
|
|
5746
6512
|
// src/OhhwellsBridge.tsx
|
|
5747
6513
|
import { Link as Link2 } from "lucide-react";
|
|
5748
|
-
import { Fragment as
|
|
6514
|
+
import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
5749
6515
|
var PRIMARY2 = "#0885FE";
|
|
5750
6516
|
var IMAGE_FADE_MS = 300;
|
|
5751
6517
|
function runOpacityFade(el, onDone) {
|
|
@@ -5924,7 +6690,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
5924
6690
|
const root = createRoot(container);
|
|
5925
6691
|
flushSync(() => {
|
|
5926
6692
|
root.render(
|
|
5927
|
-
/* @__PURE__ */
|
|
6693
|
+
/* @__PURE__ */ jsx23(
|
|
5928
6694
|
SchedulingWidget,
|
|
5929
6695
|
{
|
|
5930
6696
|
notifyOnConnect,
|
|
@@ -5964,7 +6730,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
5964
6730
|
}
|
|
5965
6731
|
}
|
|
5966
6732
|
}
|
|
5967
|
-
function
|
|
6733
|
+
function getLinkHref2(el) {
|
|
5968
6734
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
5969
6735
|
return anchor?.getAttribute("href") ?? "";
|
|
5970
6736
|
}
|
|
@@ -6001,7 +6767,7 @@ function collectEditableNodes() {
|
|
|
6001
6767
|
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
6002
6768
|
}
|
|
6003
6769
|
if (el.dataset.ohwEditable === "link") {
|
|
6004
|
-
return { key: el.dataset.ohwKey ?? "", type: "link", text:
|
|
6770
|
+
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref2(el) };
|
|
6005
6771
|
}
|
|
6006
6772
|
return {
|
|
6007
6773
|
key: el.dataset.ohwKey ?? "",
|
|
@@ -6012,7 +6778,7 @@ function collectEditableNodes() {
|
|
|
6012
6778
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
6013
6779
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
6014
6780
|
if (!key) return;
|
|
6015
|
-
nodes.push({ key, type: "link", text:
|
|
6781
|
+
nodes.push({ key, type: "link", text: getLinkHref2(el) });
|
|
6016
6782
|
});
|
|
6017
6783
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
6018
6784
|
const key = el.dataset.ohwKey ?? "";
|
|
@@ -6104,7 +6870,7 @@ function applyLinkByKey(key, val) {
|
|
|
6104
6870
|
}
|
|
6105
6871
|
function isInsideLinkEditor(target) {
|
|
6106
6872
|
return Boolean(
|
|
6107
|
-
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
6873
|
+
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
6108
6874
|
);
|
|
6109
6875
|
}
|
|
6110
6876
|
function getHrefKeyFromElement(el) {
|
|
@@ -6115,7 +6881,7 @@ function getHrefKeyFromElement(el) {
|
|
|
6115
6881
|
if (!key) return null;
|
|
6116
6882
|
return { anchor, key };
|
|
6117
6883
|
}
|
|
6118
|
-
function
|
|
6884
|
+
function isNavbarButton2(el) {
|
|
6119
6885
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
6120
6886
|
}
|
|
6121
6887
|
function getNavigationItemAnchor(el) {
|
|
@@ -6127,19 +6893,8 @@ function getNavigationItemAnchor(el) {
|
|
|
6127
6893
|
function isNavigationItem(el) {
|
|
6128
6894
|
return getNavigationItemAnchor(el) !== null;
|
|
6129
6895
|
}
|
|
6130
|
-
function getNavigationItemAddHintTarget(anchor) {
|
|
6131
|
-
const items = listNavigationItems();
|
|
6132
|
-
const idx = items.indexOf(anchor);
|
|
6133
|
-
if (idx >= 0 && idx < items.length - 1) return items[idx + 1];
|
|
6134
|
-
return anchor;
|
|
6135
|
-
}
|
|
6136
|
-
function listNavigationItems() {
|
|
6137
|
-
return Array.from(
|
|
6138
|
-
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
6139
|
-
).filter((el) => isNavigationItem(el));
|
|
6140
|
-
}
|
|
6141
6896
|
function getNavigationItemReorderState(anchor) {
|
|
6142
|
-
if (
|
|
6897
|
+
if (isNavbarButton2(anchor)) return { key: null, disabled: false };
|
|
6143
6898
|
return getReorderHandleStateFromAnchor(anchor);
|
|
6144
6899
|
}
|
|
6145
6900
|
function getReorderHandleState(el) {
|
|
@@ -6161,6 +6916,104 @@ function clearHrefKeyHover(anchor) {
|
|
|
6161
6916
|
function isInsideNavigationItem(el) {
|
|
6162
6917
|
return getNavigationItemAnchor(el) !== null;
|
|
6163
6918
|
}
|
|
6919
|
+
function getNavigationRoot(el) {
|
|
6920
|
+
const explicit = el.closest("[data-ohw-nav-root]");
|
|
6921
|
+
if (explicit) return explicit;
|
|
6922
|
+
return el.closest("nav, footer, aside");
|
|
6923
|
+
}
|
|
6924
|
+
function findFooterItemGroup(item) {
|
|
6925
|
+
const footer = item.closest("footer");
|
|
6926
|
+
if (!footer) return null;
|
|
6927
|
+
let node = item.parentElement;
|
|
6928
|
+
while (node && node !== footer) {
|
|
6929
|
+
const hasDirectNavItems = Array.from(
|
|
6930
|
+
node.querySelectorAll(":scope > [data-ohw-href-key]")
|
|
6931
|
+
).some(isNavigationItem);
|
|
6932
|
+
if (hasDirectNavItems) return node;
|
|
6933
|
+
node = node.parentElement;
|
|
6934
|
+
}
|
|
6935
|
+
return null;
|
|
6936
|
+
}
|
|
6937
|
+
function isNavigationRoot(el) {
|
|
6938
|
+
return el.hasAttribute("data-ohw-nav-root") || el.matches("nav, footer, aside");
|
|
6939
|
+
}
|
|
6940
|
+
function isInferredFooterGroup(el) {
|
|
6941
|
+
const footer = el.closest("footer");
|
|
6942
|
+
if (!footer || el === footer) return false;
|
|
6943
|
+
return Array.from(el.querySelectorAll(":scope > [data-ohw-href-key]")).some(isNavigationItem);
|
|
6944
|
+
}
|
|
6945
|
+
function isNavigationContainer(el) {
|
|
6946
|
+
return el.hasAttribute("data-ohw-nav-container") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
6947
|
+
}
|
|
6948
|
+
function isPointOverNavigation(x, y) {
|
|
6949
|
+
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
6950
|
+
if (!navRoot) return false;
|
|
6951
|
+
const r2 = navRoot.getBoundingClientRect();
|
|
6952
|
+
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
6953
|
+
}
|
|
6954
|
+
function isPointOverNavItem(container, x, y) {
|
|
6955
|
+
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
|
|
6956
|
+
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
6957
|
+
const itemRect = el.getBoundingClientRect();
|
|
6958
|
+
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
6959
|
+
});
|
|
6960
|
+
}
|
|
6961
|
+
function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
6962
|
+
if (getNavigationItemAnchor(target)) return null;
|
|
6963
|
+
if (target.closest('[data-ohw-role="navbar-button"]')) return null;
|
|
6964
|
+
const plainLink = target.closest("a");
|
|
6965
|
+
if (plainLink && !plainLink.hasAttribute("data-ohw-href-key") && !plainLink.closest("[data-ohw-nav-container]")) {
|
|
6966
|
+
return null;
|
|
6967
|
+
}
|
|
6968
|
+
const fromClosest = target.closest("[data-ohw-nav-container]");
|
|
6969
|
+
if (fromClosest && !isPointOverNavItem(fromClosest, clientX, clientY)) {
|
|
6970
|
+
return fromClosest;
|
|
6971
|
+
}
|
|
6972
|
+
const navRoot = target.closest("[data-ohw-nav-root]");
|
|
6973
|
+
if (!navRoot) return null;
|
|
6974
|
+
const container = navRoot.querySelector("[data-ohw-nav-container]");
|
|
6975
|
+
if (!container || isPointOverNavItem(container, clientX, clientY)) return null;
|
|
6976
|
+
if (target === navRoot || target.hasAttribute("data-ohw-nav-root")) {
|
|
6977
|
+
return container;
|
|
6978
|
+
}
|
|
6979
|
+
return null;
|
|
6980
|
+
}
|
|
6981
|
+
function getNavigationSelectionParent(el) {
|
|
6982
|
+
if (isNavigationItem(el)) {
|
|
6983
|
+
const explicit = el.closest("[data-ohw-nav-container]");
|
|
6984
|
+
if (explicit) return explicit;
|
|
6985
|
+
const footerGroup = findFooterItemGroup(el);
|
|
6986
|
+
if (footerGroup) return footerGroup;
|
|
6987
|
+
return getNavigationRoot(el);
|
|
6988
|
+
}
|
|
6989
|
+
if (el.hasAttribute("data-ohw-nav-container") || isInferredFooterGroup(el)) {
|
|
6990
|
+
return getNavigationRoot(el);
|
|
6991
|
+
}
|
|
6992
|
+
return null;
|
|
6993
|
+
}
|
|
6994
|
+
function placeCaretAtPoint(el, x, y) {
|
|
6995
|
+
const selection = window.getSelection();
|
|
6996
|
+
if (!selection) return;
|
|
6997
|
+
if (typeof document.caretRangeFromPoint === "function") {
|
|
6998
|
+
const range = document.caretRangeFromPoint(x, y);
|
|
6999
|
+
if (range && el.contains(range.startContainer)) {
|
|
7000
|
+
selection.removeAllRanges();
|
|
7001
|
+
selection.addRange(range);
|
|
7002
|
+
return;
|
|
7003
|
+
}
|
|
7004
|
+
}
|
|
7005
|
+
const caretPositionFromPoint = document.caretPositionFromPoint;
|
|
7006
|
+
if (typeof caretPositionFromPoint === "function") {
|
|
7007
|
+
const position = caretPositionFromPoint(x, y);
|
|
7008
|
+
if (position && el.contains(position.offsetNode)) {
|
|
7009
|
+
const range = document.createRange();
|
|
7010
|
+
range.setStart(position.offsetNode, position.offset);
|
|
7011
|
+
range.collapse(true);
|
|
7012
|
+
selection.removeAllRanges();
|
|
7013
|
+
selection.addRange(range);
|
|
7014
|
+
}
|
|
7015
|
+
}
|
|
7016
|
+
}
|
|
6164
7017
|
function collectSections() {
|
|
6165
7018
|
return collectSectionsFromDom();
|
|
6166
7019
|
}
|
|
@@ -6308,7 +7161,7 @@ function EditGlowChrome({
|
|
|
6308
7161
|
dragDisabled = false
|
|
6309
7162
|
}) {
|
|
6310
7163
|
const GAP = 6;
|
|
6311
|
-
return /* @__PURE__ */
|
|
7164
|
+
return /* @__PURE__ */ jsxs13(
|
|
6312
7165
|
"div",
|
|
6313
7166
|
{
|
|
6314
7167
|
ref: elRef,
|
|
@@ -6323,7 +7176,7 @@ function EditGlowChrome({
|
|
|
6323
7176
|
zIndex: 2147483646
|
|
6324
7177
|
},
|
|
6325
7178
|
children: [
|
|
6326
|
-
/* @__PURE__ */
|
|
7179
|
+
/* @__PURE__ */ jsx23(
|
|
6327
7180
|
"div",
|
|
6328
7181
|
{
|
|
6329
7182
|
style: {
|
|
@@ -6336,7 +7189,7 @@ function EditGlowChrome({
|
|
|
6336
7189
|
}
|
|
6337
7190
|
}
|
|
6338
7191
|
),
|
|
6339
|
-
reorderHrefKey && /* @__PURE__ */
|
|
7192
|
+
reorderHrefKey && /* @__PURE__ */ jsx23(
|
|
6340
7193
|
"div",
|
|
6341
7194
|
{
|
|
6342
7195
|
"data-ohw-drag-handle-container": "",
|
|
@@ -6348,7 +7201,7 @@ function EditGlowChrome({
|
|
|
6348
7201
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
6349
7202
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
6350
7203
|
},
|
|
6351
|
-
children: /* @__PURE__ */
|
|
7204
|
+
children: /* @__PURE__ */ jsx23(
|
|
6352
7205
|
DragHandle,
|
|
6353
7206
|
{
|
|
6354
7207
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -6452,7 +7305,7 @@ function FloatingToolbar({
|
|
|
6452
7305
|
onEditLink
|
|
6453
7306
|
}) {
|
|
6454
7307
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
6455
|
-
return /* @__PURE__ */
|
|
7308
|
+
return /* @__PURE__ */ jsx23(
|
|
6456
7309
|
"div",
|
|
6457
7310
|
{
|
|
6458
7311
|
ref: elRef,
|
|
@@ -6464,12 +7317,12 @@ function FloatingToolbar({
|
|
|
6464
7317
|
zIndex: 2147483647,
|
|
6465
7318
|
pointerEvents: "auto"
|
|
6466
7319
|
},
|
|
6467
|
-
children: /* @__PURE__ */
|
|
6468
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
6469
|
-
gi > 0 && /* @__PURE__ */
|
|
7320
|
+
children: /* @__PURE__ */ jsxs13(CustomToolbar, { children: [
|
|
7321
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs13(React9.Fragment, { children: [
|
|
7322
|
+
gi > 0 && /* @__PURE__ */ jsx23(CustomToolbarDivider, {}),
|
|
6470
7323
|
btns.map((btn) => {
|
|
6471
7324
|
const isActive = activeCommands.has(btn.cmd);
|
|
6472
|
-
return /* @__PURE__ */
|
|
7325
|
+
return /* @__PURE__ */ jsx23(
|
|
6473
7326
|
CustomToolbarButton,
|
|
6474
7327
|
{
|
|
6475
7328
|
title: btn.title,
|
|
@@ -6478,7 +7331,7 @@ function FloatingToolbar({
|
|
|
6478
7331
|
e.preventDefault();
|
|
6479
7332
|
onCommand(btn.cmd);
|
|
6480
7333
|
},
|
|
6481
|
-
children: /* @__PURE__ */
|
|
7334
|
+
children: /* @__PURE__ */ jsx23(
|
|
6482
7335
|
"svg",
|
|
6483
7336
|
{
|
|
6484
7337
|
width: "16",
|
|
@@ -6499,7 +7352,7 @@ function FloatingToolbar({
|
|
|
6499
7352
|
);
|
|
6500
7353
|
})
|
|
6501
7354
|
] }, gi)),
|
|
6502
|
-
showEditLink ? /* @__PURE__ */
|
|
7355
|
+
showEditLink ? /* @__PURE__ */ jsx23(
|
|
6503
7356
|
CustomToolbarButton,
|
|
6504
7357
|
{
|
|
6505
7358
|
type: "button",
|
|
@@ -6513,7 +7366,7 @@ function FloatingToolbar({
|
|
|
6513
7366
|
e.preventDefault();
|
|
6514
7367
|
e.stopPropagation();
|
|
6515
7368
|
},
|
|
6516
|
-
children: /* @__PURE__ */
|
|
7369
|
+
children: /* @__PURE__ */ jsx23(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
6517
7370
|
}
|
|
6518
7371
|
) : null
|
|
6519
7372
|
] })
|
|
@@ -6530,7 +7383,7 @@ function StateToggle({
|
|
|
6530
7383
|
states,
|
|
6531
7384
|
onStateChange
|
|
6532
7385
|
}) {
|
|
6533
|
-
return /* @__PURE__ */
|
|
7386
|
+
return /* @__PURE__ */ jsx23(
|
|
6534
7387
|
ToggleGroup,
|
|
6535
7388
|
{
|
|
6536
7389
|
"data-ohw-state-toggle": "",
|
|
@@ -6544,7 +7397,7 @@ function StateToggle({
|
|
|
6544
7397
|
left: rect.right - 8,
|
|
6545
7398
|
transform: "translateX(-100%)"
|
|
6546
7399
|
},
|
|
6547
|
-
children: states.map((state) => /* @__PURE__ */
|
|
7400
|
+
children: states.map((state) => /* @__PURE__ */ jsx23(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
6548
7401
|
}
|
|
6549
7402
|
);
|
|
6550
7403
|
}
|
|
@@ -6567,12 +7420,12 @@ function resolveSubdomain(subdomainFromQuery) {
|
|
|
6567
7420
|
return "";
|
|
6568
7421
|
}
|
|
6569
7422
|
function OhhwellsBridge() {
|
|
6570
|
-
const pathname =
|
|
6571
|
-
const router =
|
|
7423
|
+
const pathname = usePathname2();
|
|
7424
|
+
const router = useRouter2();
|
|
6572
7425
|
const searchParams = useSearchParams();
|
|
6573
7426
|
const isEditMode = isEditSessionActive();
|
|
6574
|
-
const [bridgeRoot, setBridgeRoot] =
|
|
6575
|
-
|
|
7427
|
+
const [bridgeRoot, setBridgeRoot] = useState6(null);
|
|
7428
|
+
useEffect7(() => {
|
|
6576
7429
|
const figtreeFontId = "ohw-figtree-font";
|
|
6577
7430
|
if (!document.getElementById(figtreeFontId)) {
|
|
6578
7431
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -6600,83 +7453,91 @@ function OhhwellsBridge() {
|
|
|
6600
7453
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
6601
7454
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
6602
7455
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
6603
|
-
const
|
|
7456
|
+
const postToParent2 = useCallback3((data) => {
|
|
6604
7457
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
6605
7458
|
window.parent.postMessage(data, "*");
|
|
6606
7459
|
}
|
|
6607
7460
|
}, []);
|
|
6608
|
-
const [fetchState, setFetchState] =
|
|
6609
|
-
const autoSaveTimers =
|
|
6610
|
-
const activeElRef =
|
|
6611
|
-
const selectedElRef =
|
|
6612
|
-
const originalContentRef =
|
|
6613
|
-
const activeStateElRef =
|
|
6614
|
-
const parentScrollRef =
|
|
6615
|
-
const visibleViewportRef =
|
|
6616
|
-
const [dialogPortalContainer, setDialogPortalContainer] =
|
|
6617
|
-
const attachVisibleViewport =
|
|
7461
|
+
const [fetchState, setFetchState] = useState6("idle");
|
|
7462
|
+
const autoSaveTimers = useRef5(/* @__PURE__ */ new Map());
|
|
7463
|
+
const activeElRef = useRef5(null);
|
|
7464
|
+
const selectedElRef = useRef5(null);
|
|
7465
|
+
const originalContentRef = useRef5(null);
|
|
7466
|
+
const activeStateElRef = useRef5(null);
|
|
7467
|
+
const parentScrollRef = useRef5(null);
|
|
7468
|
+
const visibleViewportRef = useRef5(null);
|
|
7469
|
+
const [dialogPortalContainer, setDialogPortalContainer] = useState6(null);
|
|
7470
|
+
const attachVisibleViewport = useCallback3((node) => {
|
|
6618
7471
|
visibleViewportRef.current = node;
|
|
6619
7472
|
setDialogPortalContainer(node);
|
|
6620
7473
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
6621
7474
|
}, []);
|
|
6622
|
-
const toolbarElRef =
|
|
6623
|
-
const glowElRef =
|
|
6624
|
-
const hoveredImageRef =
|
|
6625
|
-
const hoveredImageHasTextOverlapRef =
|
|
6626
|
-
const dragOverElRef =
|
|
6627
|
-
const [mediaHover, setMediaHover] =
|
|
6628
|
-
const [uploadingRects, setUploadingRects] =
|
|
6629
|
-
const hoveredGapRef =
|
|
6630
|
-
const imageUnhoverTimerRef =
|
|
6631
|
-
const imageShowTimerRef =
|
|
6632
|
-
const editStylesRef =
|
|
6633
|
-
const activateRef =
|
|
7475
|
+
const toolbarElRef = useRef5(null);
|
|
7476
|
+
const glowElRef = useRef5(null);
|
|
7477
|
+
const hoveredImageRef = useRef5(null);
|
|
7478
|
+
const hoveredImageHasTextOverlapRef = useRef5(false);
|
|
7479
|
+
const dragOverElRef = useRef5(null);
|
|
7480
|
+
const [mediaHover, setMediaHover] = useState6(null);
|
|
7481
|
+
const [uploadingRects, setUploadingRects] = useState6({});
|
|
7482
|
+
const hoveredGapRef = useRef5(null);
|
|
7483
|
+
const imageUnhoverTimerRef = useRef5(null);
|
|
7484
|
+
const imageShowTimerRef = useRef5(null);
|
|
7485
|
+
const editStylesRef = useRef5(null);
|
|
7486
|
+
const activateRef = useRef5(() => {
|
|
7487
|
+
});
|
|
7488
|
+
const deactivateRef = useRef5(() => {
|
|
6634
7489
|
});
|
|
6635
|
-
const
|
|
7490
|
+
const selectRef = useRef5(() => {
|
|
6636
7491
|
});
|
|
6637
|
-
const
|
|
7492
|
+
const selectFrameRef = useRef5(() => {
|
|
6638
7493
|
});
|
|
6639
|
-
const deselectRef =
|
|
7494
|
+
const deselectRef = useRef5(() => {
|
|
6640
7495
|
});
|
|
6641
|
-
const reselectNavigationItemRef =
|
|
7496
|
+
const reselectNavigationItemRef = useRef5(() => {
|
|
6642
7497
|
});
|
|
6643
|
-
const commitNavigationTextEditRef =
|
|
7498
|
+
const commitNavigationTextEditRef = useRef5(() => {
|
|
6644
7499
|
});
|
|
6645
|
-
const refreshActiveCommandsRef =
|
|
7500
|
+
const refreshActiveCommandsRef = useRef5(() => {
|
|
6646
7501
|
});
|
|
6647
|
-
const postToParentRef =
|
|
6648
|
-
postToParentRef.current =
|
|
6649
|
-
const sectionsLoadedRef =
|
|
6650
|
-
const pendingScheduleConfigRequests =
|
|
6651
|
-
const [toolbarRect, setToolbarRect] =
|
|
6652
|
-
const [toolbarVariant, setToolbarVariant] =
|
|
6653
|
-
const toolbarVariantRef =
|
|
7502
|
+
const postToParentRef = useRef5(postToParent2);
|
|
7503
|
+
postToParentRef.current = postToParent2;
|
|
7504
|
+
const sectionsLoadedRef = useRef5(false);
|
|
7505
|
+
const pendingScheduleConfigRequests = useRef5([]);
|
|
7506
|
+
const [toolbarRect, setToolbarRect] = useState6(null);
|
|
7507
|
+
const [toolbarVariant, setToolbarVariant] = useState6("none");
|
|
7508
|
+
const toolbarVariantRef = useRef5("none");
|
|
6654
7509
|
toolbarVariantRef.current = toolbarVariant;
|
|
6655
|
-
const [reorderHrefKey, setReorderHrefKey] =
|
|
6656
|
-
const [reorderDragDisabled, setReorderDragDisabled] =
|
|
6657
|
-
const [toggleState, setToggleState] =
|
|
6658
|
-
const [maxBadge, setMaxBadge] =
|
|
6659
|
-
const [activeCommands, setActiveCommands] =
|
|
6660
|
-
const [sectionGap, setSectionGap] =
|
|
6661
|
-
const [toolbarShowEditLink, setToolbarShowEditLink] =
|
|
6662
|
-
const
|
|
6663
|
-
const [
|
|
6664
|
-
const
|
|
6665
|
-
const [
|
|
6666
|
-
const
|
|
6667
|
-
const [
|
|
6668
|
-
const [
|
|
6669
|
-
const [
|
|
6670
|
-
const
|
|
6671
|
-
const
|
|
6672
|
-
const
|
|
6673
|
-
const
|
|
6674
|
-
const
|
|
7510
|
+
const [reorderHrefKey, setReorderHrefKey] = useState6(null);
|
|
7511
|
+
const [reorderDragDisabled, setReorderDragDisabled] = useState6(false);
|
|
7512
|
+
const [toggleState, setToggleState] = useState6(null);
|
|
7513
|
+
const [maxBadge, setMaxBadge] = useState6(null);
|
|
7514
|
+
const [activeCommands, setActiveCommands] = useState6(/* @__PURE__ */ new Set());
|
|
7515
|
+
const [sectionGap, setSectionGap] = useState6(null);
|
|
7516
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = useState6(false);
|
|
7517
|
+
const hoveredNavContainerRef = useRef5(null);
|
|
7518
|
+
const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState6(null);
|
|
7519
|
+
const hoveredItemElRef = useRef5(null);
|
|
7520
|
+
const [hoveredItemRect, setHoveredItemRect] = useState6(null);
|
|
7521
|
+
const siblingHintElRef = useRef5(null);
|
|
7522
|
+
const [siblingHintRect, setSiblingHintRect] = useState6(null);
|
|
7523
|
+
const [isItemDragging, setIsItemDragging] = useState6(false);
|
|
7524
|
+
const [linkPopover, setLinkPopover] = useState6(null);
|
|
7525
|
+
const linkPopoverSessionRef = useRef5(null);
|
|
7526
|
+
const addNavAfterAnchorRef = useRef5(null);
|
|
7527
|
+
const editContentRef = useRef5({});
|
|
7528
|
+
const [sitePages, setSitePages] = useState6([]);
|
|
7529
|
+
const [sectionsByPath, setSectionsByPath] = useState6({});
|
|
7530
|
+
const sectionsPrefetchGenRef = useRef5(0);
|
|
7531
|
+
const setLinkPopoverRef = useRef5(setLinkPopover);
|
|
7532
|
+
const linkPopoverPanelRef = useRef5(null);
|
|
7533
|
+
const linkPopoverOpenRef = useRef5(false);
|
|
7534
|
+
const linkPopoverGraceUntilRef = useRef5(0);
|
|
6675
7535
|
setLinkPopoverRef.current = setLinkPopover;
|
|
7536
|
+
linkPopoverSessionRef.current = linkPopover;
|
|
6676
7537
|
const bumpLinkPopoverGrace = () => {
|
|
6677
7538
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
6678
7539
|
};
|
|
6679
|
-
const runSectionsPrefetch =
|
|
7540
|
+
const runSectionsPrefetch = useCallback3((pages) => {
|
|
6680
7541
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
6681
7542
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
6682
7543
|
const paths = pages.map((p) => p.path);
|
|
@@ -6695,9 +7556,9 @@ function OhhwellsBridge() {
|
|
|
6695
7556
|
);
|
|
6696
7557
|
});
|
|
6697
7558
|
}, [isEditMode, pathname]);
|
|
6698
|
-
const runSectionsPrefetchRef =
|
|
7559
|
+
const runSectionsPrefetchRef = useRef5(runSectionsPrefetch);
|
|
6699
7560
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
6700
|
-
|
|
7561
|
+
useEffect7(() => {
|
|
6701
7562
|
if (!linkPopover) return;
|
|
6702
7563
|
if (hoveredImageRef.current) {
|
|
6703
7564
|
hoveredImageRef.current = null;
|
|
@@ -6706,7 +7567,7 @@ function OhhwellsBridge() {
|
|
|
6706
7567
|
hoveredGapRef.current = null;
|
|
6707
7568
|
setSectionGap(null);
|
|
6708
7569
|
setMediaHover(null);
|
|
6709
|
-
|
|
7570
|
+
postToParent2({ type: "ow:link-modal-lock", locked: true });
|
|
6710
7571
|
const html = document.documentElement;
|
|
6711
7572
|
const body = document.body;
|
|
6712
7573
|
const prevHtmlOverflow = html.style.overflow;
|
|
@@ -6723,15 +7584,16 @@ function OhhwellsBridge() {
|
|
|
6723
7584
|
const scrollOpts = { passive: false, capture: true };
|
|
6724
7585
|
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6725
7586
|
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
7587
|
+
postToParent2({ type: "ow:image-unhover" });
|
|
6726
7588
|
return () => {
|
|
6727
|
-
|
|
7589
|
+
postToParent2({ type: "ow:link-modal-lock", locked: false });
|
|
6728
7590
|
html.style.overflow = prevHtmlOverflow;
|
|
6729
7591
|
body.style.overflow = prevBodyOverflow;
|
|
6730
7592
|
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6731
7593
|
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6732
7594
|
};
|
|
6733
|
-
}, [linkPopover,
|
|
6734
|
-
|
|
7595
|
+
}, [linkPopover, postToParent2]);
|
|
7596
|
+
useEffect7(() => {
|
|
6735
7597
|
if (!isEditMode) return;
|
|
6736
7598
|
const useFixtures = shouldUseDevFixtures();
|
|
6737
7599
|
if (useFixtures) {
|
|
@@ -6752,17 +7614,17 @@ function OhhwellsBridge() {
|
|
|
6752
7614
|
runSectionsPrefetchRef.current(mapped);
|
|
6753
7615
|
};
|
|
6754
7616
|
window.addEventListener("message", onSitePages);
|
|
6755
|
-
if (!useFixtures)
|
|
7617
|
+
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
6756
7618
|
return () => window.removeEventListener("message", onSitePages);
|
|
6757
|
-
}, [isEditMode,
|
|
6758
|
-
|
|
7619
|
+
}, [isEditMode, postToParent2]);
|
|
7620
|
+
useEffect7(() => {
|
|
6759
7621
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
6760
7622
|
void loadAllSectionsManifest().then((manifest) => {
|
|
6761
7623
|
if (Object.keys(manifest).length === 0) return;
|
|
6762
7624
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
6763
7625
|
});
|
|
6764
7626
|
}, [isEditMode]);
|
|
6765
|
-
|
|
7627
|
+
useEffect7(() => {
|
|
6766
7628
|
const update = () => {
|
|
6767
7629
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
6768
7630
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -6786,10 +7648,10 @@ function OhhwellsBridge() {
|
|
|
6786
7648
|
vvp.removeEventListener("resize", update);
|
|
6787
7649
|
};
|
|
6788
7650
|
}, []);
|
|
6789
|
-
const refreshStateRules =
|
|
7651
|
+
const refreshStateRules = useCallback3(() => {
|
|
6790
7652
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
6791
7653
|
}, []);
|
|
6792
|
-
const processConfigRequest =
|
|
7654
|
+
const processConfigRequest = useCallback3((insertAfterVal) => {
|
|
6793
7655
|
const tracker = getSectionsTracker();
|
|
6794
7656
|
let entries = [];
|
|
6795
7657
|
try {
|
|
@@ -6812,7 +7674,7 @@ function OhhwellsBridge() {
|
|
|
6812
7674
|
}
|
|
6813
7675
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
6814
7676
|
}, [isEditMode]);
|
|
6815
|
-
const deactivate =
|
|
7677
|
+
const deactivate = useCallback3(() => {
|
|
6816
7678
|
const el = activeElRef.current;
|
|
6817
7679
|
if (!el) return;
|
|
6818
7680
|
const key = el.dataset.ohwKey;
|
|
@@ -6841,21 +7703,23 @@ function OhhwellsBridge() {
|
|
|
6841
7703
|
setMaxBadge(null);
|
|
6842
7704
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6843
7705
|
setToolbarShowEditLink(false);
|
|
6844
|
-
|
|
6845
|
-
}, [
|
|
6846
|
-
const deselect =
|
|
7706
|
+
postToParent2({ type: "ow:exit-edit" });
|
|
7707
|
+
}, [postToParent2]);
|
|
7708
|
+
const deselect = useCallback3(() => {
|
|
6847
7709
|
selectedElRef.current = null;
|
|
6848
7710
|
setReorderHrefKey(null);
|
|
6849
7711
|
setReorderDragDisabled(false);
|
|
6850
7712
|
siblingHintElRef.current = null;
|
|
6851
7713
|
setSiblingHintRect(null);
|
|
6852
7714
|
setIsItemDragging(false);
|
|
7715
|
+
hoveredNavContainerRef.current = null;
|
|
7716
|
+
setHoveredNavContainerRect(null);
|
|
6853
7717
|
if (!activeElRef.current) {
|
|
6854
7718
|
setToolbarRect(null);
|
|
6855
7719
|
setToolbarVariant("none");
|
|
6856
7720
|
}
|
|
6857
7721
|
}, []);
|
|
6858
|
-
const reselectNavigationItem =
|
|
7722
|
+
const reselectNavigationItem = useCallback3((navAnchor) => {
|
|
6859
7723
|
selectedElRef.current = navAnchor;
|
|
6860
7724
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
6861
7725
|
setReorderHrefKey(key);
|
|
@@ -6865,7 +7729,7 @@ function OhhwellsBridge() {
|
|
|
6865
7729
|
setToolbarShowEditLink(false);
|
|
6866
7730
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6867
7731
|
}, []);
|
|
6868
|
-
const commitNavigationTextEdit =
|
|
7732
|
+
const commitNavigationTextEdit = useCallback3((navAnchor) => {
|
|
6869
7733
|
const el = activeElRef.current;
|
|
6870
7734
|
if (!el) return;
|
|
6871
7735
|
const key = el.dataset.ohwKey;
|
|
@@ -6878,9 +7742,9 @@ function OhhwellsBridge() {
|
|
|
6878
7742
|
const html = sanitizeHtml(el.innerHTML);
|
|
6879
7743
|
const original = originalContentRef.current ?? "";
|
|
6880
7744
|
if (html !== sanitizeHtml(original)) {
|
|
6881
|
-
|
|
7745
|
+
postToParent2({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
6882
7746
|
const h = document.documentElement.scrollHeight;
|
|
6883
|
-
if (h > 50)
|
|
7747
|
+
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
6884
7748
|
}
|
|
6885
7749
|
}
|
|
6886
7750
|
el.removeAttribute("contenteditable");
|
|
@@ -6888,31 +7752,38 @@ function OhhwellsBridge() {
|
|
|
6888
7752
|
setMaxBadge(null);
|
|
6889
7753
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6890
7754
|
setToolbarShowEditLink(false);
|
|
6891
|
-
|
|
7755
|
+
postToParent2({ type: "ow:exit-edit" });
|
|
6892
7756
|
reselectNavigationItem(navAnchor);
|
|
6893
|
-
}, [
|
|
6894
|
-
const
|
|
6895
|
-
const
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
7757
|
+
}, [postToParent2, reselectNavigationItem]);
|
|
7758
|
+
const handleAddTopLevelNavItem = useCallback3(() => {
|
|
7759
|
+
const items = listNavbarItems();
|
|
7760
|
+
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
7761
|
+
deselectRef.current();
|
|
7762
|
+
deactivateRef.current();
|
|
7763
|
+
bumpLinkPopoverGrace();
|
|
7764
|
+
setLinkPopover({
|
|
7765
|
+
key: "__add-nav__",
|
|
7766
|
+
mode: "create",
|
|
7767
|
+
intent: "add-nav"
|
|
7768
|
+
});
|
|
6900
7769
|
}, []);
|
|
6901
|
-
const handleItemDragStart =
|
|
7770
|
+
const handleItemDragStart = useCallback3(() => {
|
|
6902
7771
|
siblingHintElRef.current = null;
|
|
6903
7772
|
setSiblingHintRect(null);
|
|
6904
7773
|
setIsItemDragging(true);
|
|
6905
7774
|
}, []);
|
|
6906
|
-
const handleItemDragEnd =
|
|
7775
|
+
const handleItemDragEnd = useCallback3(() => {
|
|
6907
7776
|
setIsItemDragging(false);
|
|
6908
7777
|
}, []);
|
|
6909
7778
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
6910
7779
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
6911
|
-
const select =
|
|
7780
|
+
const select = useCallback3((anchor) => {
|
|
6912
7781
|
if (!isNavigationItem(anchor)) return;
|
|
6913
7782
|
if (activeElRef.current) deactivate();
|
|
6914
7783
|
selectedElRef.current = anchor;
|
|
6915
7784
|
clearHrefKeyHover(anchor);
|
|
7785
|
+
hoveredNavContainerRef.current = null;
|
|
7786
|
+
setHoveredNavContainerRect(null);
|
|
6916
7787
|
setHoveredItemRect(null);
|
|
6917
7788
|
hoveredItemElRef.current = null;
|
|
6918
7789
|
siblingHintElRef.current = null;
|
|
@@ -6926,7 +7797,26 @@ function OhhwellsBridge() {
|
|
|
6926
7797
|
setToolbarShowEditLink(false);
|
|
6927
7798
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6928
7799
|
}, [deactivate]);
|
|
6929
|
-
const
|
|
7800
|
+
const selectFrame = useCallback3((el) => {
|
|
7801
|
+
if (!isNavigationContainer(el)) return;
|
|
7802
|
+
if (activeElRef.current) deactivate();
|
|
7803
|
+
selectedElRef.current = el;
|
|
7804
|
+
clearHrefKeyHover(el);
|
|
7805
|
+
hoveredNavContainerRef.current = null;
|
|
7806
|
+
setHoveredNavContainerRect(null);
|
|
7807
|
+
setHoveredItemRect(null);
|
|
7808
|
+
hoveredItemElRef.current = null;
|
|
7809
|
+
siblingHintElRef.current = null;
|
|
7810
|
+
setSiblingHintRect(null);
|
|
7811
|
+
setIsItemDragging(false);
|
|
7812
|
+
setReorderHrefKey(null);
|
|
7813
|
+
setReorderDragDisabled(false);
|
|
7814
|
+
setToolbarVariant("select-frame");
|
|
7815
|
+
setToolbarRect(el.getBoundingClientRect());
|
|
7816
|
+
setToolbarShowEditLink(false);
|
|
7817
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7818
|
+
}, [deactivate]);
|
|
7819
|
+
const activate = useCallback3((el, options) => {
|
|
6930
7820
|
if (activeElRef.current === el) return;
|
|
6931
7821
|
selectedElRef.current = null;
|
|
6932
7822
|
deactivate();
|
|
@@ -6944,6 +7834,9 @@ function OhhwellsBridge() {
|
|
|
6944
7834
|
activeElRef.current = el;
|
|
6945
7835
|
originalContentRef.current = el.innerHTML;
|
|
6946
7836
|
el.focus();
|
|
7837
|
+
if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
7838
|
+
placeCaretAtPoint(el, options.caretX, options.caretY);
|
|
7839
|
+
}
|
|
6947
7840
|
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
6948
7841
|
const navAnchor = getNavigationItemAnchor(el);
|
|
6949
7842
|
if (navAnchor) {
|
|
@@ -6955,12 +7848,13 @@ function OhhwellsBridge() {
|
|
|
6955
7848
|
setReorderDragDisabled(reorderDisabled);
|
|
6956
7849
|
}
|
|
6957
7850
|
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
6958
|
-
|
|
7851
|
+
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
6959
7852
|
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
6960
|
-
}, [deactivate,
|
|
7853
|
+
}, [deactivate, postToParent2]);
|
|
6961
7854
|
activateRef.current = activate;
|
|
6962
7855
|
deactivateRef.current = deactivate;
|
|
6963
7856
|
selectRef.current = select;
|
|
7857
|
+
selectFrameRef.current = selectFrame;
|
|
6964
7858
|
deselectRef.current = deselect;
|
|
6965
7859
|
useLayoutEffect2(() => {
|
|
6966
7860
|
if (!subdomain || isEditMode) {
|
|
@@ -7002,6 +7896,7 @@ function OhhwellsBridge() {
|
|
|
7002
7896
|
});
|
|
7003
7897
|
applyLinkByKey(key, val);
|
|
7004
7898
|
}
|
|
7899
|
+
reconcileNavbarItemsFromContent(content);
|
|
7005
7900
|
enforceLinkHrefs();
|
|
7006
7901
|
initSectionsFromContent(content, true);
|
|
7007
7902
|
sectionsLoadedRef.current = true;
|
|
@@ -7030,7 +7925,7 @@ function OhhwellsBridge() {
|
|
|
7030
7925
|
cancelled = true;
|
|
7031
7926
|
};
|
|
7032
7927
|
}, [subdomain, isEditMode]);
|
|
7033
|
-
|
|
7928
|
+
useEffect7(() => {
|
|
7034
7929
|
if (!subdomain || isEditMode) return;
|
|
7035
7930
|
let debounceTimer = null;
|
|
7036
7931
|
let observer = null;
|
|
@@ -7061,6 +7956,7 @@ function OhhwellsBridge() {
|
|
|
7061
7956
|
});
|
|
7062
7957
|
applyLinkByKey(key, val);
|
|
7063
7958
|
}
|
|
7959
|
+
reconcileNavbarItemsFromContent(content);
|
|
7064
7960
|
} finally {
|
|
7065
7961
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
7066
7962
|
}
|
|
@@ -7084,20 +7980,38 @@ function OhhwellsBridge() {
|
|
|
7084
7980
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
7085
7981
|
el.style.display = visible ? "flex" : "none";
|
|
7086
7982
|
}, [subdomain, fetchState]);
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
}, [pathname,
|
|
7090
|
-
|
|
7983
|
+
useEffect7(() => {
|
|
7984
|
+
postToParent2({ type: "ow:navigation", path: pathname });
|
|
7985
|
+
}, [pathname, postToParent2]);
|
|
7986
|
+
useEffect7(() => {
|
|
7091
7987
|
if (!isEditMode) return;
|
|
7988
|
+
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
7989
|
+
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
7092
7990
|
setLinkPopover(null);
|
|
7093
7991
|
deselectRef.current();
|
|
7094
7992
|
deactivateRef.current();
|
|
7095
7993
|
}, [pathname, isEditMode]);
|
|
7096
|
-
|
|
7994
|
+
useEffect7(() => {
|
|
7995
|
+
const contentForNav = () => {
|
|
7996
|
+
if (isEditMode) return editContentRef.current;
|
|
7997
|
+
if (!subdomain) return {};
|
|
7998
|
+
return contentCache.get(subdomain) ?? {};
|
|
7999
|
+
};
|
|
8000
|
+
const run = () => reconcileNavbarItemsFromContent(contentForNav());
|
|
8001
|
+
run();
|
|
8002
|
+
const nav = document.querySelector("nav");
|
|
8003
|
+
if (!nav) return;
|
|
8004
|
+
const observer = new MutationObserver(() => {
|
|
8005
|
+
requestAnimationFrame(run);
|
|
8006
|
+
});
|
|
8007
|
+
observer.observe(nav, { childList: true, subtree: true });
|
|
8008
|
+
return () => observer.disconnect();
|
|
8009
|
+
}, [isEditMode, pathname, subdomain, fetchState]);
|
|
8010
|
+
useEffect7(() => {
|
|
7097
8011
|
if (!isEditMode) return;
|
|
7098
8012
|
const measure = () => {
|
|
7099
8013
|
const h = document.body.scrollHeight;
|
|
7100
|
-
if (h > 50)
|
|
8014
|
+
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
7101
8015
|
};
|
|
7102
8016
|
const t1 = setTimeout(measure, 50);
|
|
7103
8017
|
const t2 = setTimeout(measure, 500);
|
|
@@ -7116,8 +8030,8 @@ function OhhwellsBridge() {
|
|
|
7116
8030
|
if (resizeTimer) clearTimeout(resizeTimer);
|
|
7117
8031
|
window.removeEventListener("resize", handleResize);
|
|
7118
8032
|
};
|
|
7119
|
-
}, [pathname, isEditMode,
|
|
7120
|
-
|
|
8033
|
+
}, [pathname, isEditMode, postToParent2]);
|
|
8034
|
+
useEffect7(() => {
|
|
7121
8035
|
if (!subdomainFromQuery || isEditMode) return;
|
|
7122
8036
|
const handleClick = (e) => {
|
|
7123
8037
|
const anchor = e.target.closest("a");
|
|
@@ -7133,7 +8047,7 @@ function OhhwellsBridge() {
|
|
|
7133
8047
|
document.addEventListener("click", handleClick, true);
|
|
7134
8048
|
return () => document.removeEventListener("click", handleClick, true);
|
|
7135
8049
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
7136
|
-
|
|
8050
|
+
useEffect7(() => {
|
|
7137
8051
|
if (!isEditMode) {
|
|
7138
8052
|
editStylesRef.current?.base.remove();
|
|
7139
8053
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -7206,6 +8120,13 @@ function OhhwellsBridge() {
|
|
|
7206
8120
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
7207
8121
|
if (isInsideLinkEditor(target)) return;
|
|
7208
8122
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
8123
|
+
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8124
|
+
if (navFromChrome) {
|
|
8125
|
+
e.preventDefault();
|
|
8126
|
+
e.stopPropagation();
|
|
8127
|
+
selectFrameRef.current(navFromChrome);
|
|
8128
|
+
return;
|
|
8129
|
+
}
|
|
7209
8130
|
e.preventDefault();
|
|
7210
8131
|
e.stopPropagation();
|
|
7211
8132
|
return;
|
|
@@ -7220,7 +8141,8 @@ function OhhwellsBridge() {
|
|
|
7220
8141
|
bumpLinkPopoverGrace();
|
|
7221
8142
|
setLinkPopoverRef.current({
|
|
7222
8143
|
key: editable.dataset.ohwKey ?? "",
|
|
7223
|
-
|
|
8144
|
+
mode: "edit",
|
|
8145
|
+
target: getLinkHref2(editable)
|
|
7224
8146
|
});
|
|
7225
8147
|
return;
|
|
7226
8148
|
}
|
|
@@ -7236,7 +8158,7 @@ function OhhwellsBridge() {
|
|
|
7236
8158
|
e.preventDefault();
|
|
7237
8159
|
e.stopPropagation();
|
|
7238
8160
|
if (selectedElRef.current === navAnchor) {
|
|
7239
|
-
activateRef.current(editable);
|
|
8161
|
+
activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
|
|
7240
8162
|
return;
|
|
7241
8163
|
}
|
|
7242
8164
|
selectRef.current(navAnchor);
|
|
@@ -7255,6 +8177,22 @@ function OhhwellsBridge() {
|
|
|
7255
8177
|
selectRef.current(hrefAnchor);
|
|
7256
8178
|
return;
|
|
7257
8179
|
}
|
|
8180
|
+
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8181
|
+
if (navContainerToSelect) {
|
|
8182
|
+
e.preventDefault();
|
|
8183
|
+
e.stopPropagation();
|
|
8184
|
+
selectFrameRef.current(navContainerToSelect);
|
|
8185
|
+
return;
|
|
8186
|
+
}
|
|
8187
|
+
const selectedContainer = selectedElRef.current;
|
|
8188
|
+
if (selectedContainer && isNavigationContainer(selectedContainer)) {
|
|
8189
|
+
const navItem = getNavigationItemAnchor(target);
|
|
8190
|
+
if (!navItem && (selectedContainer === target || selectedContainer.contains(target))) {
|
|
8191
|
+
e.preventDefault();
|
|
8192
|
+
e.stopPropagation();
|
|
8193
|
+
return;
|
|
8194
|
+
}
|
|
8195
|
+
}
|
|
7258
8196
|
if (activeElRef.current) {
|
|
7259
8197
|
const sel = window.getSelection();
|
|
7260
8198
|
if (sel && !sel.isCollapsed) {
|
|
@@ -7281,9 +8219,26 @@ function OhhwellsBridge() {
|
|
|
7281
8219
|
deactivateRef.current();
|
|
7282
8220
|
};
|
|
7283
8221
|
const handleMouseOver = (e) => {
|
|
8222
|
+
if (document.documentElement.hasAttribute("data-ohw-section-picking")) return;
|
|
7284
8223
|
const target = e.target;
|
|
8224
|
+
if (toolbarVariantRef.current !== "select-frame") {
|
|
8225
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
8226
|
+
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
8227
|
+
hoveredNavContainerRef.current = navContainer;
|
|
8228
|
+
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
8229
|
+
hoveredItemElRef.current = null;
|
|
8230
|
+
setHoveredItemRect(null);
|
|
8231
|
+
return;
|
|
8232
|
+
}
|
|
8233
|
+
if (!target.closest("[data-ohw-nav-container]")) {
|
|
8234
|
+
hoveredNavContainerRef.current = null;
|
|
8235
|
+
setHoveredNavContainerRect(null);
|
|
8236
|
+
}
|
|
8237
|
+
}
|
|
7285
8238
|
const navAnchor = getNavigationItemAnchor(target);
|
|
7286
8239
|
if (navAnchor) {
|
|
8240
|
+
hoveredNavContainerRef.current = null;
|
|
8241
|
+
setHoveredNavContainerRect(null);
|
|
7287
8242
|
const selected2 = selectedElRef.current;
|
|
7288
8243
|
if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
|
|
7289
8244
|
clearHrefKeyHover(navAnchor);
|
|
@@ -7308,6 +8263,14 @@ function OhhwellsBridge() {
|
|
|
7308
8263
|
};
|
|
7309
8264
|
const handleMouseOut = (e) => {
|
|
7310
8265
|
const target = e.target;
|
|
8266
|
+
if (target.closest("[data-ohw-nav-container]")) {
|
|
8267
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
8268
|
+
if (related2?.closest("[data-ohw-nav-container], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
8269
|
+
return;
|
|
8270
|
+
}
|
|
8271
|
+
hoveredNavContainerRef.current = null;
|
|
8272
|
+
setHoveredNavContainerRect(null);
|
|
8273
|
+
}
|
|
7311
8274
|
const navAnchor = getNavigationItemAnchor(target);
|
|
7312
8275
|
if (navAnchor) {
|
|
7313
8276
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -7429,6 +8392,56 @@ function OhhwellsBridge() {
|
|
|
7429
8392
|
}
|
|
7430
8393
|
return smallest;
|
|
7431
8394
|
};
|
|
8395
|
+
const dismissImageHover = () => {
|
|
8396
|
+
if (hoveredImageRef.current) {
|
|
8397
|
+
hoveredImageRef.current = null;
|
|
8398
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
8399
|
+
resumeAnimTracks();
|
|
8400
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8401
|
+
}
|
|
8402
|
+
};
|
|
8403
|
+
const probeNavigationHoverAt = (x, y) => {
|
|
8404
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
8405
|
+
hoveredNavContainerRef.current = null;
|
|
8406
|
+
setHoveredNavContainerRect(null);
|
|
8407
|
+
return;
|
|
8408
|
+
}
|
|
8409
|
+
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
8410
|
+
if (!navContainer) {
|
|
8411
|
+
hoveredNavContainerRef.current = null;
|
|
8412
|
+
setHoveredNavContainerRect(null);
|
|
8413
|
+
return;
|
|
8414
|
+
}
|
|
8415
|
+
const containerRect = navContainer.getBoundingClientRect();
|
|
8416
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
8417
|
+
if (!overContainer) {
|
|
8418
|
+
hoveredNavContainerRef.current = null;
|
|
8419
|
+
setHoveredNavContainerRect(null);
|
|
8420
|
+
return;
|
|
8421
|
+
}
|
|
8422
|
+
const navItemHit = Array.from(
|
|
8423
|
+
navContainer.querySelectorAll("[data-ohw-href-key]")
|
|
8424
|
+
).find((el) => {
|
|
8425
|
+
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
8426
|
+
const itemRect = el.getBoundingClientRect();
|
|
8427
|
+
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
8428
|
+
});
|
|
8429
|
+
if (navItemHit) {
|
|
8430
|
+
hoveredNavContainerRef.current = null;
|
|
8431
|
+
setHoveredNavContainerRect(null);
|
|
8432
|
+
const selected = selectedElRef.current;
|
|
8433
|
+
if (selected !== navItemHit && !selected?.contains(navItemHit)) {
|
|
8434
|
+
clearHrefKeyHover(navItemHit);
|
|
8435
|
+
hoveredItemElRef.current = navItemHit;
|
|
8436
|
+
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
8437
|
+
}
|
|
8438
|
+
return;
|
|
8439
|
+
}
|
|
8440
|
+
hoveredNavContainerRef.current = navContainer;
|
|
8441
|
+
setHoveredNavContainerRect(containerRect);
|
|
8442
|
+
hoveredItemElRef.current = null;
|
|
8443
|
+
setHoveredItemRect(null);
|
|
8444
|
+
};
|
|
7432
8445
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
7433
8446
|
if (linkPopoverOpenRef.current) {
|
|
7434
8447
|
if (hoveredImageRef.current) {
|
|
@@ -7437,18 +8450,22 @@ function OhhwellsBridge() {
|
|
|
7437
8450
|
resumeAnimTracks();
|
|
7438
8451
|
clearImageHover();
|
|
7439
8452
|
}
|
|
8453
|
+
dismissImageHover();
|
|
8454
|
+
return;
|
|
8455
|
+
}
|
|
8456
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8457
|
+
if (isPointOverNavigation(x, y)) {
|
|
8458
|
+
dismissImageHover();
|
|
8459
|
+
probeNavigationHoverAt(x, y);
|
|
7440
8460
|
return;
|
|
7441
8461
|
}
|
|
8462
|
+
hoveredNavContainerRef.current = null;
|
|
8463
|
+
setHoveredNavContainerRect(null);
|
|
7442
8464
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
7443
8465
|
if (toggleEl) {
|
|
7444
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7445
8466
|
const tr = toggleEl.getBoundingClientRect();
|
|
7446
8467
|
if (x >= tr.left && x <= tr.right && y >= tr.top && y <= tr.bottom) {
|
|
7447
|
-
|
|
7448
|
-
hoveredImageRef.current = null;
|
|
7449
|
-
resumeAnimTracks();
|
|
7450
|
-
clearImageHover();
|
|
7451
|
-
}
|
|
8468
|
+
dismissImageHover();
|
|
7452
8469
|
return;
|
|
7453
8470
|
}
|
|
7454
8471
|
}
|
|
@@ -7461,15 +8478,18 @@ function OhhwellsBridge() {
|
|
|
7461
8478
|
resumeAnimTracks();
|
|
7462
8479
|
clearImageHover();
|
|
7463
8480
|
}
|
|
7464
|
-
|
|
8481
|
+
if (activeElRef.current) {
|
|
8482
|
+
dismissImageHover();
|
|
8483
|
+
return;
|
|
8484
|
+
}
|
|
7465
8485
|
}
|
|
7466
8486
|
if (imgEl) {
|
|
7467
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8487
|
+
const { x: x2, y: y2 } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7468
8488
|
const overMediaChrome = Array.from(
|
|
7469
8489
|
document.querySelectorAll("[data-ohw-media-chrome]")
|
|
7470
8490
|
).some((el) => {
|
|
7471
8491
|
const r2 = el.getBoundingClientRect();
|
|
7472
|
-
return
|
|
8492
|
+
return x2 >= r2.left && x2 <= r2.right && y2 >= r2.top && y2 <= r2.bottom;
|
|
7473
8493
|
});
|
|
7474
8494
|
if (overMediaChrome) {
|
|
7475
8495
|
if (hoveredImageRef.current) {
|
|
@@ -7480,7 +8500,7 @@ function OhhwellsBridge() {
|
|
|
7480
8500
|
}
|
|
7481
8501
|
return;
|
|
7482
8502
|
}
|
|
7483
|
-
const topEl = document.elementFromPoint(
|
|
8503
|
+
const topEl = document.elementFromPoint(x2, y2);
|
|
7484
8504
|
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
7485
8505
|
if (hoveredImageRef.current) {
|
|
7486
8506
|
hoveredImageRef.current = null;
|
|
@@ -7503,7 +8523,7 @@ function OhhwellsBridge() {
|
|
|
7503
8523
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7504
8524
|
).find((el) => {
|
|
7505
8525
|
const er = el.getBoundingClientRect();
|
|
7506
|
-
return
|
|
8526
|
+
return x2 >= er.left && x2 <= er.right && y2 >= er.top && y2 <= er.bottom;
|
|
7507
8527
|
});
|
|
7508
8528
|
if (imageUnhoverTimerRef.current) {
|
|
7509
8529
|
clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -7579,12 +8599,12 @@ function OhhwellsBridge() {
|
|
|
7579
8599
|
resumeAnimTracks();
|
|
7580
8600
|
clearImageHover();
|
|
7581
8601
|
}
|
|
7582
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8602
|
+
const { x: x2, y: y2 } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7583
8603
|
const textEl = Array.from(
|
|
7584
8604
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7585
8605
|
).find((el) => {
|
|
7586
8606
|
const er = el.getBoundingClientRect();
|
|
7587
|
-
return
|
|
8607
|
+
return x2 >= er.left && x2 <= er.right && y2 >= er.top && y2 <= er.bottom;
|
|
7588
8608
|
});
|
|
7589
8609
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7590
8610
|
if (textEl && !textEl.hasAttribute("contenteditable")) {
|
|
@@ -7608,6 +8628,14 @@ function OhhwellsBridge() {
|
|
|
7608
8628
|
}
|
|
7609
8629
|
};
|
|
7610
8630
|
const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
|
|
8631
|
+
if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
8632
|
+
if (activeStateElRef.current) {
|
|
8633
|
+
activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
|
|
8634
|
+
activeStateElRef.current = null;
|
|
8635
|
+
setToggleState(null);
|
|
8636
|
+
}
|
|
8637
|
+
return;
|
|
8638
|
+
}
|
|
7611
8639
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7612
8640
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
7613
8641
|
if (toggleEl) {
|
|
@@ -7884,6 +8912,8 @@ function OhhwellsBridge() {
|
|
|
7884
8912
|
sectionsLoadedRef.current = true;
|
|
7885
8913
|
pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
|
|
7886
8914
|
}
|
|
8915
|
+
editContentRef.current = { ...editContentRef.current, ...content };
|
|
8916
|
+
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
7887
8917
|
enforceLinkHrefs();
|
|
7888
8918
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
7889
8919
|
};
|
|
@@ -7891,6 +8921,7 @@ function OhhwellsBridge() {
|
|
|
7891
8921
|
const handleDeactivate = (e) => {
|
|
7892
8922
|
if (e.data?.type !== "ow:deactivate") return;
|
|
7893
8923
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
8924
|
+
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
7894
8925
|
if (linkPopoverOpenRef.current) {
|
|
7895
8926
|
setLinkPopoverRef.current(null);
|
|
7896
8927
|
return;
|
|
@@ -7899,13 +8930,31 @@ function OhhwellsBridge() {
|
|
|
7899
8930
|
deactivateRef.current();
|
|
7900
8931
|
};
|
|
7901
8932
|
window.addEventListener("message", handleDeactivate);
|
|
8933
|
+
const handleUiEscape = (e) => {
|
|
8934
|
+
if (e.data?.type !== "ui:escape") return;
|
|
8935
|
+
if (linkPopoverOpenRef.current) {
|
|
8936
|
+
setLinkPopoverRef.current(null);
|
|
8937
|
+
}
|
|
8938
|
+
};
|
|
8939
|
+
window.addEventListener("message", handleUiEscape);
|
|
7902
8940
|
const handleKeyDown = (e) => {
|
|
8941
|
+
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
7903
8942
|
if (e.key === "Escape" && linkPopoverOpenRef.current) {
|
|
7904
8943
|
setLinkPopoverRef.current(null);
|
|
7905
8944
|
return;
|
|
7906
8945
|
}
|
|
7907
8946
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
7908
|
-
|
|
8947
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
8948
|
+
deselectRef.current();
|
|
8949
|
+
return;
|
|
8950
|
+
}
|
|
8951
|
+
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
8952
|
+
if (parent) {
|
|
8953
|
+
e.preventDefault();
|
|
8954
|
+
selectFrameRef.current(parent);
|
|
8955
|
+
} else {
|
|
8956
|
+
deselectRef.current();
|
|
8957
|
+
}
|
|
7909
8958
|
return;
|
|
7910
8959
|
}
|
|
7911
8960
|
if (e.key === "Escape" && activeElRef.current) {
|
|
@@ -7963,6 +9012,9 @@ function OhhwellsBridge() {
|
|
|
7963
9012
|
if (hoveredItemElRef.current) {
|
|
7964
9013
|
setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
|
|
7965
9014
|
}
|
|
9015
|
+
if (hoveredNavContainerRef.current) {
|
|
9016
|
+
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
9017
|
+
}
|
|
7966
9018
|
if (siblingHintElRef.current) {
|
|
7967
9019
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
7968
9020
|
}
|
|
@@ -8159,9 +9211,45 @@ function OhhwellsBridge() {
|
|
|
8159
9211
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
8160
9212
|
});
|
|
8161
9213
|
if (textEditable) {
|
|
8162
|
-
|
|
9214
|
+
const hrefCtx = getHrefKeyFromElement(textEditable);
|
|
9215
|
+
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
9216
|
+
if (navAnchor) {
|
|
9217
|
+
if (selectedElRef.current === navAnchor) {
|
|
9218
|
+
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
9219
|
+
} else {
|
|
9220
|
+
selectRef.current(navAnchor);
|
|
9221
|
+
}
|
|
9222
|
+
return;
|
|
9223
|
+
}
|
|
9224
|
+
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
8163
9225
|
return;
|
|
8164
9226
|
}
|
|
9227
|
+
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
9228
|
+
if (navContainer) {
|
|
9229
|
+
const r2 = navContainer.getBoundingClientRect();
|
|
9230
|
+
const pad = 8;
|
|
9231
|
+
const over = clientX >= r2.left - pad && clientX <= r2.right + pad && clientY >= r2.top - pad && clientY <= r2.bottom + pad;
|
|
9232
|
+
if (over && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
9233
|
+
selectFrameRef.current(navContainer);
|
|
9234
|
+
return;
|
|
9235
|
+
}
|
|
9236
|
+
}
|
|
9237
|
+
const navRoot = document.querySelector("[data-ohw-nav-root]");
|
|
9238
|
+
if (navRoot && navContainer) {
|
|
9239
|
+
const rr = navRoot.getBoundingClientRect();
|
|
9240
|
+
if (clientX >= rr.left && clientX <= rr.right && clientY >= rr.top && clientY <= rr.bottom && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
9241
|
+
const book = navRoot.querySelector('[data-ohw-role="navbar-button"]');
|
|
9242
|
+
if (book) {
|
|
9243
|
+
const br = book.getBoundingClientRect();
|
|
9244
|
+
if (clientX >= br.left && clientX <= br.right && clientY >= br.top && clientY <= br.bottom) {
|
|
9245
|
+
deactivateRef.current();
|
|
9246
|
+
return;
|
|
9247
|
+
}
|
|
9248
|
+
}
|
|
9249
|
+
selectFrameRef.current(navContainer);
|
|
9250
|
+
return;
|
|
9251
|
+
}
|
|
9252
|
+
}
|
|
8165
9253
|
deactivateRef.current();
|
|
8166
9254
|
};
|
|
8167
9255
|
window.addEventListener("message", handleSave);
|
|
@@ -8224,13 +9312,14 @@ function OhhwellsBridge() {
|
|
|
8224
9312
|
window.removeEventListener("message", handleClickAt);
|
|
8225
9313
|
window.removeEventListener("message", handleHydrate);
|
|
8226
9314
|
window.removeEventListener("message", handleDeactivate);
|
|
9315
|
+
window.removeEventListener("message", handleUiEscape);
|
|
8227
9316
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
8228
9317
|
autoSaveTimers.current.clear();
|
|
8229
9318
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
8230
9319
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
8231
9320
|
};
|
|
8232
9321
|
}, [isEditMode, refreshStateRules]);
|
|
8233
|
-
|
|
9322
|
+
useEffect7(() => {
|
|
8234
9323
|
const handler = (e) => {
|
|
8235
9324
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
8236
9325
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -8246,7 +9335,7 @@ function OhhwellsBridge() {
|
|
|
8246
9335
|
window.addEventListener("message", handler);
|
|
8247
9336
|
return () => window.removeEventListener("message", handler);
|
|
8248
9337
|
}, [processConfigRequest]);
|
|
8249
|
-
|
|
9338
|
+
useEffect7(() => {
|
|
8250
9339
|
if (!isEditMode) return;
|
|
8251
9340
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
8252
9341
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -8267,27 +9356,27 @@ function OhhwellsBridge() {
|
|
|
8267
9356
|
const next = { ...prev, [pathKey]: sections };
|
|
8268
9357
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
8269
9358
|
});
|
|
8270
|
-
|
|
8271
|
-
|
|
9359
|
+
postToParent2({ type: "ow:ready", version: "1", path: pathname, nodes: collectEditableNodes(), sections });
|
|
9360
|
+
postToParent2({ type: "ow:request-site-pages" });
|
|
8272
9361
|
}, 150);
|
|
8273
9362
|
return () => {
|
|
8274
9363
|
cancelAnimationFrame(raf);
|
|
8275
9364
|
clearTimeout(timer);
|
|
8276
9365
|
};
|
|
8277
|
-
}, [pathname, isEditMode, refreshStateRules,
|
|
8278
|
-
|
|
9366
|
+
}, [pathname, isEditMode, refreshStateRules, postToParent2]);
|
|
9367
|
+
useEffect7(() => {
|
|
8279
9368
|
scrollToHashSectionWhenReady();
|
|
8280
9369
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
8281
9370
|
window.addEventListener("hashchange", onHashChange);
|
|
8282
9371
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
8283
9372
|
}, [pathname]);
|
|
8284
|
-
const handleCommand =
|
|
9373
|
+
const handleCommand = useCallback3((cmd) => {
|
|
8285
9374
|
document.execCommand(cmd, false);
|
|
8286
9375
|
activeElRef.current?.focus();
|
|
8287
9376
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
8288
9377
|
refreshActiveCommandsRef.current();
|
|
8289
9378
|
}, []);
|
|
8290
|
-
const handleStateChange =
|
|
9379
|
+
const handleStateChange = useCallback3((state) => {
|
|
8291
9380
|
if (!activeStateElRef.current) return;
|
|
8292
9381
|
const el = activeStateElRef.current;
|
|
8293
9382
|
if (state === "Default") {
|
|
@@ -8300,18 +9389,22 @@ function OhhwellsBridge() {
|
|
|
8300
9389
|
}
|
|
8301
9390
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
8302
9391
|
}, [deactivate]);
|
|
8303
|
-
const closeLinkPopover =
|
|
8304
|
-
|
|
9392
|
+
const closeLinkPopover = useCallback3(() => {
|
|
9393
|
+
addNavAfterAnchorRef.current = null;
|
|
9394
|
+
setLinkPopover(null);
|
|
9395
|
+
}, []);
|
|
9396
|
+
const openLinkPopoverForActive = useCallback3(() => {
|
|
8305
9397
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
8306
9398
|
if (!hrefCtx) return;
|
|
8307
9399
|
bumpLinkPopoverGrace();
|
|
8308
9400
|
setLinkPopover({
|
|
8309
9401
|
key: hrefCtx.key,
|
|
8310
|
-
|
|
9402
|
+
mode: "edit",
|
|
9403
|
+
target: getLinkHref2(hrefCtx.anchor)
|
|
8311
9404
|
});
|
|
8312
9405
|
deactivate();
|
|
8313
9406
|
}, [deactivate]);
|
|
8314
|
-
const openLinkPopoverForSelected =
|
|
9407
|
+
const openLinkPopoverForSelected = useCallback3(() => {
|
|
8315
9408
|
const anchor = selectedElRef.current;
|
|
8316
9409
|
if (!anchor) return;
|
|
8317
9410
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -8319,30 +9412,77 @@ function OhhwellsBridge() {
|
|
|
8319
9412
|
bumpLinkPopoverGrace();
|
|
8320
9413
|
setLinkPopover({
|
|
8321
9414
|
key,
|
|
8322
|
-
|
|
9415
|
+
mode: "edit",
|
|
9416
|
+
target: getLinkHref2(anchor)
|
|
8323
9417
|
});
|
|
8324
9418
|
deselect();
|
|
8325
9419
|
}, [deselect]);
|
|
8326
|
-
const handleLinkPopoverSubmit =
|
|
9420
|
+
const handleLinkPopoverSubmit = useCallback3(
|
|
8327
9421
|
(target) => {
|
|
8328
|
-
|
|
8329
|
-
|
|
9422
|
+
const session = linkPopoverSessionRef.current;
|
|
9423
|
+
if (!session) return;
|
|
9424
|
+
if (session.intent === "add-nav") {
|
|
9425
|
+
const trimmed = target.trim();
|
|
9426
|
+
let href = trimmed;
|
|
9427
|
+
let label = "Untitled";
|
|
9428
|
+
if (trimmed) {
|
|
9429
|
+
const { pageRoute, sectionId } = parseTarget(trimmed);
|
|
9430
|
+
const page = resolvePage(pageRoute, sitePages);
|
|
9431
|
+
const pageSections = getSectionsForPath(sectionsByPath, pageRoute);
|
|
9432
|
+
const section = sectionId ? pageSections.find((s) => s.id === sectionId) : void 0;
|
|
9433
|
+
label = section?.label ?? page.title;
|
|
9434
|
+
href = trimmed;
|
|
9435
|
+
}
|
|
9436
|
+
const afterAnchor = addNavAfterAnchorRef.current;
|
|
9437
|
+
const { anchor, hrefKey, labelKey, index, order } = insertNavbarItem(href, label, afterAnchor);
|
|
9438
|
+
applyLinkByKey(hrefKey, href);
|
|
9439
|
+
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
9440
|
+
el.textContent = label;
|
|
9441
|
+
});
|
|
9442
|
+
const navCount = String(index + 1);
|
|
9443
|
+
const orderJson = JSON.stringify(order);
|
|
9444
|
+
editContentRef.current = {
|
|
9445
|
+
...editContentRef.current,
|
|
9446
|
+
[hrefKey]: href,
|
|
9447
|
+
[labelKey]: label,
|
|
9448
|
+
[NAV_COUNT_KEY]: navCount,
|
|
9449
|
+
[NAV_ORDER_KEY]: orderJson
|
|
9450
|
+
};
|
|
9451
|
+
postToParent2({
|
|
9452
|
+
type: "ow:change",
|
|
9453
|
+
nodes: [
|
|
9454
|
+
{ key: hrefKey, text: href },
|
|
9455
|
+
{ key: labelKey, text: label },
|
|
9456
|
+
{ key: NAV_COUNT_KEY, text: navCount },
|
|
9457
|
+
{ key: NAV_ORDER_KEY, text: orderJson }
|
|
9458
|
+
]
|
|
9459
|
+
});
|
|
9460
|
+
postToParent2({ type: "ow:toast", title: "Link added", toastType: "success" });
|
|
9461
|
+
addNavAfterAnchorRef.current = null;
|
|
9462
|
+
setLinkPopover(null);
|
|
9463
|
+
enforceLinkHrefs();
|
|
9464
|
+
requestAnimationFrame(() => {
|
|
9465
|
+
selectRef.current(anchor);
|
|
9466
|
+
});
|
|
9467
|
+
return;
|
|
9468
|
+
}
|
|
9469
|
+
const { key } = session;
|
|
8330
9470
|
applyLinkByKey(key, target);
|
|
8331
|
-
|
|
9471
|
+
postToParent2({ type: "ow:change", nodes: [{ key, text: target }] });
|
|
8332
9472
|
setLinkPopover(null);
|
|
8333
9473
|
},
|
|
8334
|
-
[
|
|
9474
|
+
[postToParent2, sitePages, sectionsByPath]
|
|
8335
9475
|
);
|
|
8336
9476
|
const showEditLink = toolbarShowEditLink;
|
|
8337
9477
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
8338
9478
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
8339
|
-
const handleMediaReplace =
|
|
9479
|
+
const handleMediaReplace = useCallback3(
|
|
8340
9480
|
(key) => {
|
|
8341
|
-
|
|
9481
|
+
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
8342
9482
|
},
|
|
8343
|
-
[
|
|
9483
|
+
[postToParent2, mediaHover?.elementType]
|
|
8344
9484
|
);
|
|
8345
|
-
const handleMediaFadeOutComplete =
|
|
9485
|
+
const handleMediaFadeOutComplete = useCallback3((key) => {
|
|
8346
9486
|
setUploadingRects((prev) => {
|
|
8347
9487
|
if (!(key in prev)) return prev;
|
|
8348
9488
|
const next = { ...prev };
|
|
@@ -8350,7 +9490,7 @@ function OhhwellsBridge() {
|
|
|
8350
9490
|
return next;
|
|
8351
9491
|
});
|
|
8352
9492
|
}, []);
|
|
8353
|
-
const handleVideoSettingsChange =
|
|
9493
|
+
const handleVideoSettingsChange = useCallback3(
|
|
8354
9494
|
(key, settings) => {
|
|
8355
9495
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8356
9496
|
const video = getVideoEl(el);
|
|
@@ -8358,7 +9498,7 @@ function OhhwellsBridge() {
|
|
|
8358
9498
|
if (typeof settings.autoplay === "boolean") video.autoplay = settings.autoplay;
|
|
8359
9499
|
if (typeof settings.muted === "boolean") video.muted = settings.muted;
|
|
8360
9500
|
syncVideoPlayback(video);
|
|
8361
|
-
|
|
9501
|
+
postToParent2({
|
|
8362
9502
|
type: "ow:change",
|
|
8363
9503
|
nodes: [
|
|
8364
9504
|
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
@@ -8370,12 +9510,12 @@ function OhhwellsBridge() {
|
|
|
8370
9510
|
);
|
|
8371
9511
|
});
|
|
8372
9512
|
},
|
|
8373
|
-
[
|
|
9513
|
+
[postToParent2]
|
|
8374
9514
|
);
|
|
8375
|
-
return bridgeRoot ?
|
|
8376
|
-
/* @__PURE__ */
|
|
8377
|
-
/* @__PURE__ */
|
|
8378
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */
|
|
9515
|
+
return bridgeRoot ? createPortal2(
|
|
9516
|
+
/* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
9517
|
+
/* @__PURE__ */ jsx23("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
9518
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx23(
|
|
8379
9519
|
MediaOverlay,
|
|
8380
9520
|
{
|
|
8381
9521
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -8386,7 +9526,7 @@ function OhhwellsBridge() {
|
|
|
8386
9526
|
},
|
|
8387
9527
|
`uploading-${key}`
|
|
8388
9528
|
)),
|
|
8389
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */
|
|
9529
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx23(
|
|
8390
9530
|
MediaOverlay,
|
|
8391
9531
|
{
|
|
8392
9532
|
hover: mediaHover,
|
|
@@ -8395,31 +9535,40 @@ function OhhwellsBridge() {
|
|
|
8395
9535
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
8396
9536
|
}
|
|
8397
9537
|
),
|
|
8398
|
-
siblingHintRect && !isItemDragging && /* @__PURE__ */
|
|
8399
|
-
|
|
8400
|
-
|
|
9538
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ jsx23(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
9539
|
+
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && !siblingHintRect && /* @__PURE__ */ jsx23(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
9540
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx23(
|
|
9541
|
+
NavbarContainerChrome,
|
|
9542
|
+
{
|
|
9543
|
+
rect: toolbarRect,
|
|
9544
|
+
onAdd: handleAddTopLevelNavItem
|
|
9545
|
+
}
|
|
9546
|
+
),
|
|
9547
|
+
hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx23(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
9548
|
+
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ jsx23(
|
|
8401
9549
|
ItemInteractionLayer,
|
|
8402
9550
|
{
|
|
8403
9551
|
rect: toolbarRect,
|
|
8404
9552
|
elRef: glowElRef,
|
|
8405
9553
|
state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
|
|
8406
|
-
showHandle: Boolean(reorderHrefKey),
|
|
9554
|
+
showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey),
|
|
8407
9555
|
dragDisabled: reorderDragDisabled,
|
|
8408
9556
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
8409
9557
|
onDragHandleDragStart: handleItemDragStart,
|
|
8410
9558
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
8411
|
-
toolbar:
|
|
9559
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ jsx23(
|
|
8412
9560
|
ItemActionToolbar,
|
|
8413
9561
|
{
|
|
8414
9562
|
onEditLink: openLinkPopoverForSelected,
|
|
8415
|
-
|
|
8416
|
-
|
|
9563
|
+
addItemDisabled: true,
|
|
9564
|
+
editLinkDisabled: false,
|
|
9565
|
+
moreDisabled: true
|
|
8417
9566
|
}
|
|
8418
|
-
)
|
|
9567
|
+
) : void 0
|
|
8419
9568
|
}
|
|
8420
9569
|
),
|
|
8421
|
-
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */
|
|
8422
|
-
/* @__PURE__ */
|
|
9570
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
9571
|
+
/* @__PURE__ */ jsx23(
|
|
8423
9572
|
EditGlowChrome,
|
|
8424
9573
|
{
|
|
8425
9574
|
rect: toolbarRect,
|
|
@@ -8428,7 +9577,7 @@ function OhhwellsBridge() {
|
|
|
8428
9577
|
dragDisabled: reorderDragDisabled
|
|
8429
9578
|
}
|
|
8430
9579
|
),
|
|
8431
|
-
/* @__PURE__ */
|
|
9580
|
+
/* @__PURE__ */ jsx23(
|
|
8432
9581
|
FloatingToolbar,
|
|
8433
9582
|
{
|
|
8434
9583
|
rect: toolbarRect,
|
|
@@ -8441,7 +9590,7 @@ function OhhwellsBridge() {
|
|
|
8441
9590
|
}
|
|
8442
9591
|
)
|
|
8443
9592
|
] }),
|
|
8444
|
-
maxBadge && /* @__PURE__ */
|
|
9593
|
+
maxBadge && /* @__PURE__ */ jsxs13(
|
|
8445
9594
|
"div",
|
|
8446
9595
|
{
|
|
8447
9596
|
"data-ohw-max-badge": "",
|
|
@@ -8467,7 +9616,7 @@ function OhhwellsBridge() {
|
|
|
8467
9616
|
]
|
|
8468
9617
|
}
|
|
8469
9618
|
),
|
|
8470
|
-
toggleState && /* @__PURE__ */
|
|
9619
|
+
toggleState && !linkPopover && /* @__PURE__ */ jsx23(
|
|
8471
9620
|
StateToggle,
|
|
8472
9621
|
{
|
|
8473
9622
|
rect: toggleState.rect,
|
|
@@ -8476,15 +9625,15 @@ function OhhwellsBridge() {
|
|
|
8476
9625
|
onStateChange: handleStateChange
|
|
8477
9626
|
}
|
|
8478
9627
|
),
|
|
8479
|
-
sectionGap && /* @__PURE__ */
|
|
9628
|
+
sectionGap && !linkPopover && /* @__PURE__ */ jsxs13(
|
|
8480
9629
|
"div",
|
|
8481
9630
|
{
|
|
8482
9631
|
"data-ohw-section-insert-line": "",
|
|
8483
9632
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8484
9633
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8485
9634
|
children: [
|
|
8486
|
-
/* @__PURE__ */
|
|
8487
|
-
/* @__PURE__ */
|
|
9635
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9636
|
+
/* @__PURE__ */ jsx23(
|
|
8488
9637
|
Badge,
|
|
8489
9638
|
{
|
|
8490
9639
|
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",
|
|
@@ -8497,25 +9646,26 @@ function OhhwellsBridge() {
|
|
|
8497
9646
|
children: "Add Section"
|
|
8498
9647
|
}
|
|
8499
9648
|
),
|
|
8500
|
-
/* @__PURE__ */
|
|
9649
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8501
9650
|
]
|
|
8502
9651
|
}
|
|
8503
9652
|
),
|
|
8504
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */
|
|
9653
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx23(
|
|
8505
9654
|
LinkPopover,
|
|
8506
9655
|
{
|
|
8507
9656
|
panelRef: linkPopoverPanelRef,
|
|
8508
9657
|
portalContainer: dialogPortalContainer,
|
|
8509
9658
|
open: true,
|
|
8510
|
-
mode: "edit",
|
|
9659
|
+
mode: linkPopover.mode ?? "edit",
|
|
8511
9660
|
pages: sitePages,
|
|
8512
9661
|
sections: currentSections,
|
|
8513
9662
|
sectionsByPath,
|
|
8514
9663
|
initialTarget: linkPopover.target,
|
|
9664
|
+
existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
|
|
8515
9665
|
onClose: closeLinkPopover,
|
|
8516
9666
|
onSubmit: handleLinkPopoverSubmit
|
|
8517
9667
|
},
|
|
8518
|
-
|
|
9668
|
+
linkPopover.key
|
|
8519
9669
|
) : null
|
|
8520
9670
|
] }),
|
|
8521
9671
|
bridgeRoot
|