@ohhwells/bridge 0.1.39 → 0.1.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1796 -596
- 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 +1765 -565
- 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
|
-
|
|
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
|
+
)
|
|
5566
6138
|
}
|
|
5567
|
-
)
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
UrlOrPageInput,
|
|
5578
|
-
{
|
|
5579
|
-
value: state.searchValue,
|
|
5580
|
-
selectedPage: state.selectedPage,
|
|
5581
|
-
dropdownOpen: state.dropdownOpen,
|
|
5582
|
-
onDropdownOpenChange: state.setDropdownOpen,
|
|
5583
|
-
filteredPages: state.filteredPages,
|
|
5584
|
-
onInputChange: state.handleInputChange,
|
|
5585
|
-
onPageSelect: state.handlePageSelect,
|
|
5586
|
-
urlError: state.urlError
|
|
5587
|
-
}
|
|
5588
|
-
),
|
|
5589
|
-
state.showChooseSection ? /* @__PURE__ */ jsxs11("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
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
|
-
] })
|
|
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,120 @@ 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
|
+
}
|
|
7017
|
+
function selectAllTextInEditable(el) {
|
|
7018
|
+
const selection = window.getSelection();
|
|
7019
|
+
if (!selection) return;
|
|
7020
|
+
const range = document.createRange();
|
|
7021
|
+
range.selectNodeContents(el);
|
|
7022
|
+
selection.removeAllRanges();
|
|
7023
|
+
selection.addRange(range);
|
|
7024
|
+
}
|
|
7025
|
+
function getNavigationLabelEditable(target) {
|
|
7026
|
+
const editable = target.closest('[data-ohw-editable="text"]');
|
|
7027
|
+
if (!editable) return null;
|
|
7028
|
+
const hrefCtx = getHrefKeyFromElement(editable);
|
|
7029
|
+
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
7030
|
+
if (!navAnchor) return null;
|
|
7031
|
+
return { editable, navAnchor };
|
|
7032
|
+
}
|
|
6164
7033
|
function collectSections() {
|
|
6165
7034
|
return collectSectionsFromDom();
|
|
6166
7035
|
}
|
|
@@ -6308,7 +7177,7 @@ function EditGlowChrome({
|
|
|
6308
7177
|
dragDisabled = false
|
|
6309
7178
|
}) {
|
|
6310
7179
|
const GAP = 6;
|
|
6311
|
-
return /* @__PURE__ */
|
|
7180
|
+
return /* @__PURE__ */ jsxs13(
|
|
6312
7181
|
"div",
|
|
6313
7182
|
{
|
|
6314
7183
|
ref: elRef,
|
|
@@ -6323,7 +7192,7 @@ function EditGlowChrome({
|
|
|
6323
7192
|
zIndex: 2147483646
|
|
6324
7193
|
},
|
|
6325
7194
|
children: [
|
|
6326
|
-
/* @__PURE__ */
|
|
7195
|
+
/* @__PURE__ */ jsx23(
|
|
6327
7196
|
"div",
|
|
6328
7197
|
{
|
|
6329
7198
|
style: {
|
|
@@ -6336,7 +7205,7 @@ function EditGlowChrome({
|
|
|
6336
7205
|
}
|
|
6337
7206
|
}
|
|
6338
7207
|
),
|
|
6339
|
-
reorderHrefKey && /* @__PURE__ */
|
|
7208
|
+
reorderHrefKey && /* @__PURE__ */ jsx23(
|
|
6340
7209
|
"div",
|
|
6341
7210
|
{
|
|
6342
7211
|
"data-ohw-drag-handle-container": "",
|
|
@@ -6348,7 +7217,7 @@ function EditGlowChrome({
|
|
|
6348
7217
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
6349
7218
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
6350
7219
|
},
|
|
6351
|
-
children: /* @__PURE__ */
|
|
7220
|
+
children: /* @__PURE__ */ jsx23(
|
|
6352
7221
|
DragHandle,
|
|
6353
7222
|
{
|
|
6354
7223
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -6452,7 +7321,7 @@ function FloatingToolbar({
|
|
|
6452
7321
|
onEditLink
|
|
6453
7322
|
}) {
|
|
6454
7323
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
6455
|
-
return /* @__PURE__ */
|
|
7324
|
+
return /* @__PURE__ */ jsx23(
|
|
6456
7325
|
"div",
|
|
6457
7326
|
{
|
|
6458
7327
|
ref: elRef,
|
|
@@ -6464,12 +7333,12 @@ function FloatingToolbar({
|
|
|
6464
7333
|
zIndex: 2147483647,
|
|
6465
7334
|
pointerEvents: "auto"
|
|
6466
7335
|
},
|
|
6467
|
-
children: /* @__PURE__ */
|
|
6468
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
6469
|
-
gi > 0 && /* @__PURE__ */
|
|
7336
|
+
children: /* @__PURE__ */ jsxs13(CustomToolbar, { children: [
|
|
7337
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs13(React9.Fragment, { children: [
|
|
7338
|
+
gi > 0 && /* @__PURE__ */ jsx23(CustomToolbarDivider, {}),
|
|
6470
7339
|
btns.map((btn) => {
|
|
6471
7340
|
const isActive = activeCommands.has(btn.cmd);
|
|
6472
|
-
return /* @__PURE__ */
|
|
7341
|
+
return /* @__PURE__ */ jsx23(
|
|
6473
7342
|
CustomToolbarButton,
|
|
6474
7343
|
{
|
|
6475
7344
|
title: btn.title,
|
|
@@ -6478,7 +7347,7 @@ function FloatingToolbar({
|
|
|
6478
7347
|
e.preventDefault();
|
|
6479
7348
|
onCommand(btn.cmd);
|
|
6480
7349
|
},
|
|
6481
|
-
children: /* @__PURE__ */
|
|
7350
|
+
children: /* @__PURE__ */ jsx23(
|
|
6482
7351
|
"svg",
|
|
6483
7352
|
{
|
|
6484
7353
|
width: "16",
|
|
@@ -6499,7 +7368,7 @@ function FloatingToolbar({
|
|
|
6499
7368
|
);
|
|
6500
7369
|
})
|
|
6501
7370
|
] }, gi)),
|
|
6502
|
-
showEditLink ? /* @__PURE__ */
|
|
7371
|
+
showEditLink ? /* @__PURE__ */ jsx23(
|
|
6503
7372
|
CustomToolbarButton,
|
|
6504
7373
|
{
|
|
6505
7374
|
type: "button",
|
|
@@ -6513,7 +7382,7 @@ function FloatingToolbar({
|
|
|
6513
7382
|
e.preventDefault();
|
|
6514
7383
|
e.stopPropagation();
|
|
6515
7384
|
},
|
|
6516
|
-
children: /* @__PURE__ */
|
|
7385
|
+
children: /* @__PURE__ */ jsx23(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
6517
7386
|
}
|
|
6518
7387
|
) : null
|
|
6519
7388
|
] })
|
|
@@ -6530,7 +7399,7 @@ function StateToggle({
|
|
|
6530
7399
|
states,
|
|
6531
7400
|
onStateChange
|
|
6532
7401
|
}) {
|
|
6533
|
-
return /* @__PURE__ */
|
|
7402
|
+
return /* @__PURE__ */ jsx23(
|
|
6534
7403
|
ToggleGroup,
|
|
6535
7404
|
{
|
|
6536
7405
|
"data-ohw-state-toggle": "",
|
|
@@ -6544,7 +7413,7 @@ function StateToggle({
|
|
|
6544
7413
|
left: rect.right - 8,
|
|
6545
7414
|
transform: "translateX(-100%)"
|
|
6546
7415
|
},
|
|
6547
|
-
children: states.map((state) => /* @__PURE__ */
|
|
7416
|
+
children: states.map((state) => /* @__PURE__ */ jsx23(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
6548
7417
|
}
|
|
6549
7418
|
);
|
|
6550
7419
|
}
|
|
@@ -6567,12 +7436,12 @@ function resolveSubdomain(subdomainFromQuery) {
|
|
|
6567
7436
|
return "";
|
|
6568
7437
|
}
|
|
6569
7438
|
function OhhwellsBridge() {
|
|
6570
|
-
const pathname =
|
|
6571
|
-
const router =
|
|
7439
|
+
const pathname = usePathname2();
|
|
7440
|
+
const router = useRouter2();
|
|
6572
7441
|
const searchParams = useSearchParams();
|
|
6573
7442
|
const isEditMode = isEditSessionActive();
|
|
6574
|
-
const [bridgeRoot, setBridgeRoot] =
|
|
6575
|
-
|
|
7443
|
+
const [bridgeRoot, setBridgeRoot] = useState6(null);
|
|
7444
|
+
useEffect7(() => {
|
|
6576
7445
|
const figtreeFontId = "ohw-figtree-font";
|
|
6577
7446
|
if (!document.getElementById(figtreeFontId)) {
|
|
6578
7447
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -6600,83 +7469,91 @@ function OhhwellsBridge() {
|
|
|
6600
7469
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
6601
7470
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
6602
7471
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
6603
|
-
const
|
|
7472
|
+
const postToParent2 = useCallback3((data) => {
|
|
6604
7473
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
6605
7474
|
window.parent.postMessage(data, "*");
|
|
6606
7475
|
}
|
|
6607
7476
|
}, []);
|
|
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 =
|
|
7477
|
+
const [fetchState, setFetchState] = useState6("idle");
|
|
7478
|
+
const autoSaveTimers = useRef5(/* @__PURE__ */ new Map());
|
|
7479
|
+
const activeElRef = useRef5(null);
|
|
7480
|
+
const selectedElRef = useRef5(null);
|
|
7481
|
+
const originalContentRef = useRef5(null);
|
|
7482
|
+
const activeStateElRef = useRef5(null);
|
|
7483
|
+
const parentScrollRef = useRef5(null);
|
|
7484
|
+
const visibleViewportRef = useRef5(null);
|
|
7485
|
+
const [dialogPortalContainer, setDialogPortalContainer] = useState6(null);
|
|
7486
|
+
const attachVisibleViewport = useCallback3((node) => {
|
|
6618
7487
|
visibleViewportRef.current = node;
|
|
6619
7488
|
setDialogPortalContainer(node);
|
|
6620
7489
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
6621
7490
|
}, []);
|
|
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 =
|
|
7491
|
+
const toolbarElRef = useRef5(null);
|
|
7492
|
+
const glowElRef = useRef5(null);
|
|
7493
|
+
const hoveredImageRef = useRef5(null);
|
|
7494
|
+
const hoveredImageHasTextOverlapRef = useRef5(false);
|
|
7495
|
+
const dragOverElRef = useRef5(null);
|
|
7496
|
+
const [mediaHover, setMediaHover] = useState6(null);
|
|
7497
|
+
const [uploadingRects, setUploadingRects] = useState6({});
|
|
7498
|
+
const hoveredGapRef = useRef5(null);
|
|
7499
|
+
const imageUnhoverTimerRef = useRef5(null);
|
|
7500
|
+
const imageShowTimerRef = useRef5(null);
|
|
7501
|
+
const editStylesRef = useRef5(null);
|
|
7502
|
+
const activateRef = useRef5(() => {
|
|
7503
|
+
});
|
|
7504
|
+
const deactivateRef = useRef5(() => {
|
|
6634
7505
|
});
|
|
6635
|
-
const
|
|
7506
|
+
const selectRef = useRef5(() => {
|
|
6636
7507
|
});
|
|
6637
|
-
const
|
|
7508
|
+
const selectFrameRef = useRef5(() => {
|
|
6638
7509
|
});
|
|
6639
|
-
const deselectRef =
|
|
7510
|
+
const deselectRef = useRef5(() => {
|
|
6640
7511
|
});
|
|
6641
|
-
const reselectNavigationItemRef =
|
|
7512
|
+
const reselectNavigationItemRef = useRef5(() => {
|
|
6642
7513
|
});
|
|
6643
|
-
const commitNavigationTextEditRef =
|
|
7514
|
+
const commitNavigationTextEditRef = useRef5(() => {
|
|
6644
7515
|
});
|
|
6645
|
-
const refreshActiveCommandsRef =
|
|
7516
|
+
const refreshActiveCommandsRef = useRef5(() => {
|
|
6646
7517
|
});
|
|
6647
|
-
const postToParentRef =
|
|
6648
|
-
postToParentRef.current =
|
|
6649
|
-
const sectionsLoadedRef =
|
|
6650
|
-
const pendingScheduleConfigRequests =
|
|
6651
|
-
const [toolbarRect, setToolbarRect] =
|
|
6652
|
-
const [toolbarVariant, setToolbarVariant] =
|
|
6653
|
-
const toolbarVariantRef =
|
|
7518
|
+
const postToParentRef = useRef5(postToParent2);
|
|
7519
|
+
postToParentRef.current = postToParent2;
|
|
7520
|
+
const sectionsLoadedRef = useRef5(false);
|
|
7521
|
+
const pendingScheduleConfigRequests = useRef5([]);
|
|
7522
|
+
const [toolbarRect, setToolbarRect] = useState6(null);
|
|
7523
|
+
const [toolbarVariant, setToolbarVariant] = useState6("none");
|
|
7524
|
+
const toolbarVariantRef = useRef5("none");
|
|
6654
7525
|
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
|
|
7526
|
+
const [reorderHrefKey, setReorderHrefKey] = useState6(null);
|
|
7527
|
+
const [reorderDragDisabled, setReorderDragDisabled] = useState6(false);
|
|
7528
|
+
const [toggleState, setToggleState] = useState6(null);
|
|
7529
|
+
const [maxBadge, setMaxBadge] = useState6(null);
|
|
7530
|
+
const [activeCommands, setActiveCommands] = useState6(/* @__PURE__ */ new Set());
|
|
7531
|
+
const [sectionGap, setSectionGap] = useState6(null);
|
|
7532
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = useState6(false);
|
|
7533
|
+
const hoveredNavContainerRef = useRef5(null);
|
|
7534
|
+
const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState6(null);
|
|
7535
|
+
const hoveredItemElRef = useRef5(null);
|
|
7536
|
+
const [hoveredItemRect, setHoveredItemRect] = useState6(null);
|
|
7537
|
+
const siblingHintElRef = useRef5(null);
|
|
7538
|
+
const [siblingHintRect, setSiblingHintRect] = useState6(null);
|
|
7539
|
+
const [isItemDragging, setIsItemDragging] = useState6(false);
|
|
7540
|
+
const [linkPopover, setLinkPopover] = useState6(null);
|
|
7541
|
+
const linkPopoverSessionRef = useRef5(null);
|
|
7542
|
+
const addNavAfterAnchorRef = useRef5(null);
|
|
7543
|
+
const editContentRef = useRef5({});
|
|
7544
|
+
const [sitePages, setSitePages] = useState6([]);
|
|
7545
|
+
const [sectionsByPath, setSectionsByPath] = useState6({});
|
|
7546
|
+
const sectionsPrefetchGenRef = useRef5(0);
|
|
7547
|
+
const setLinkPopoverRef = useRef5(setLinkPopover);
|
|
7548
|
+
const linkPopoverPanelRef = useRef5(null);
|
|
7549
|
+
const linkPopoverOpenRef = useRef5(false);
|
|
7550
|
+
const linkPopoverGraceUntilRef = useRef5(0);
|
|
6675
7551
|
setLinkPopoverRef.current = setLinkPopover;
|
|
7552
|
+
linkPopoverSessionRef.current = linkPopover;
|
|
6676
7553
|
const bumpLinkPopoverGrace = () => {
|
|
6677
7554
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
6678
7555
|
};
|
|
6679
|
-
const runSectionsPrefetch =
|
|
7556
|
+
const runSectionsPrefetch = useCallback3((pages) => {
|
|
6680
7557
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
6681
7558
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
6682
7559
|
const paths = pages.map((p) => p.path);
|
|
@@ -6695,9 +7572,9 @@ function OhhwellsBridge() {
|
|
|
6695
7572
|
);
|
|
6696
7573
|
});
|
|
6697
7574
|
}, [isEditMode, pathname]);
|
|
6698
|
-
const runSectionsPrefetchRef =
|
|
7575
|
+
const runSectionsPrefetchRef = useRef5(runSectionsPrefetch);
|
|
6699
7576
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
6700
|
-
|
|
7577
|
+
useEffect7(() => {
|
|
6701
7578
|
if (!linkPopover) return;
|
|
6702
7579
|
if (hoveredImageRef.current) {
|
|
6703
7580
|
hoveredImageRef.current = null;
|
|
@@ -6706,7 +7583,7 @@ function OhhwellsBridge() {
|
|
|
6706
7583
|
hoveredGapRef.current = null;
|
|
6707
7584
|
setSectionGap(null);
|
|
6708
7585
|
setMediaHover(null);
|
|
6709
|
-
|
|
7586
|
+
postToParent2({ type: "ow:link-modal-lock", locked: true });
|
|
6710
7587
|
const html = document.documentElement;
|
|
6711
7588
|
const body = document.body;
|
|
6712
7589
|
const prevHtmlOverflow = html.style.overflow;
|
|
@@ -6723,15 +7600,16 @@ function OhhwellsBridge() {
|
|
|
6723
7600
|
const scrollOpts = { passive: false, capture: true };
|
|
6724
7601
|
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6725
7602
|
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
7603
|
+
postToParent2({ type: "ow:image-unhover" });
|
|
6726
7604
|
return () => {
|
|
6727
|
-
|
|
7605
|
+
postToParent2({ type: "ow:link-modal-lock", locked: false });
|
|
6728
7606
|
html.style.overflow = prevHtmlOverflow;
|
|
6729
7607
|
body.style.overflow = prevBodyOverflow;
|
|
6730
7608
|
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6731
7609
|
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6732
7610
|
};
|
|
6733
|
-
}, [linkPopover,
|
|
6734
|
-
|
|
7611
|
+
}, [linkPopover, postToParent2]);
|
|
7612
|
+
useEffect7(() => {
|
|
6735
7613
|
if (!isEditMode) return;
|
|
6736
7614
|
const useFixtures = shouldUseDevFixtures();
|
|
6737
7615
|
if (useFixtures) {
|
|
@@ -6752,17 +7630,17 @@ function OhhwellsBridge() {
|
|
|
6752
7630
|
runSectionsPrefetchRef.current(mapped);
|
|
6753
7631
|
};
|
|
6754
7632
|
window.addEventListener("message", onSitePages);
|
|
6755
|
-
if (!useFixtures)
|
|
7633
|
+
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
6756
7634
|
return () => window.removeEventListener("message", onSitePages);
|
|
6757
|
-
}, [isEditMode,
|
|
6758
|
-
|
|
7635
|
+
}, [isEditMode, postToParent2]);
|
|
7636
|
+
useEffect7(() => {
|
|
6759
7637
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
6760
7638
|
void loadAllSectionsManifest().then((manifest) => {
|
|
6761
7639
|
if (Object.keys(manifest).length === 0) return;
|
|
6762
7640
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
6763
7641
|
});
|
|
6764
7642
|
}, [isEditMode]);
|
|
6765
|
-
|
|
7643
|
+
useEffect7(() => {
|
|
6766
7644
|
const update = () => {
|
|
6767
7645
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
6768
7646
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -6786,10 +7664,10 @@ function OhhwellsBridge() {
|
|
|
6786
7664
|
vvp.removeEventListener("resize", update);
|
|
6787
7665
|
};
|
|
6788
7666
|
}, []);
|
|
6789
|
-
const refreshStateRules =
|
|
7667
|
+
const refreshStateRules = useCallback3(() => {
|
|
6790
7668
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
6791
7669
|
}, []);
|
|
6792
|
-
const processConfigRequest =
|
|
7670
|
+
const processConfigRequest = useCallback3((insertAfterVal) => {
|
|
6793
7671
|
const tracker = getSectionsTracker();
|
|
6794
7672
|
let entries = [];
|
|
6795
7673
|
try {
|
|
@@ -6812,7 +7690,7 @@ function OhhwellsBridge() {
|
|
|
6812
7690
|
}
|
|
6813
7691
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
6814
7692
|
}, [isEditMode]);
|
|
6815
|
-
const deactivate =
|
|
7693
|
+
const deactivate = useCallback3(() => {
|
|
6816
7694
|
const el = activeElRef.current;
|
|
6817
7695
|
if (!el) return;
|
|
6818
7696
|
const key = el.dataset.ohwKey;
|
|
@@ -6841,21 +7719,23 @@ function OhhwellsBridge() {
|
|
|
6841
7719
|
setMaxBadge(null);
|
|
6842
7720
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6843
7721
|
setToolbarShowEditLink(false);
|
|
6844
|
-
|
|
6845
|
-
}, [
|
|
6846
|
-
const deselect =
|
|
7722
|
+
postToParent2({ type: "ow:exit-edit" });
|
|
7723
|
+
}, [postToParent2]);
|
|
7724
|
+
const deselect = useCallback3(() => {
|
|
6847
7725
|
selectedElRef.current = null;
|
|
6848
7726
|
setReorderHrefKey(null);
|
|
6849
7727
|
setReorderDragDisabled(false);
|
|
6850
7728
|
siblingHintElRef.current = null;
|
|
6851
7729
|
setSiblingHintRect(null);
|
|
6852
7730
|
setIsItemDragging(false);
|
|
7731
|
+
hoveredNavContainerRef.current = null;
|
|
7732
|
+
setHoveredNavContainerRect(null);
|
|
6853
7733
|
if (!activeElRef.current) {
|
|
6854
7734
|
setToolbarRect(null);
|
|
6855
7735
|
setToolbarVariant("none");
|
|
6856
7736
|
}
|
|
6857
7737
|
}, []);
|
|
6858
|
-
const reselectNavigationItem =
|
|
7738
|
+
const reselectNavigationItem = useCallback3((navAnchor) => {
|
|
6859
7739
|
selectedElRef.current = navAnchor;
|
|
6860
7740
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
6861
7741
|
setReorderHrefKey(key);
|
|
@@ -6865,7 +7745,7 @@ function OhhwellsBridge() {
|
|
|
6865
7745
|
setToolbarShowEditLink(false);
|
|
6866
7746
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6867
7747
|
}, []);
|
|
6868
|
-
const commitNavigationTextEdit =
|
|
7748
|
+
const commitNavigationTextEdit = useCallback3((navAnchor) => {
|
|
6869
7749
|
const el = activeElRef.current;
|
|
6870
7750
|
if (!el) return;
|
|
6871
7751
|
const key = el.dataset.ohwKey;
|
|
@@ -6878,9 +7758,9 @@ function OhhwellsBridge() {
|
|
|
6878
7758
|
const html = sanitizeHtml(el.innerHTML);
|
|
6879
7759
|
const original = originalContentRef.current ?? "";
|
|
6880
7760
|
if (html !== sanitizeHtml(original)) {
|
|
6881
|
-
|
|
7761
|
+
postToParent2({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
6882
7762
|
const h = document.documentElement.scrollHeight;
|
|
6883
|
-
if (h > 50)
|
|
7763
|
+
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
6884
7764
|
}
|
|
6885
7765
|
}
|
|
6886
7766
|
el.removeAttribute("contenteditable");
|
|
@@ -6888,31 +7768,38 @@ function OhhwellsBridge() {
|
|
|
6888
7768
|
setMaxBadge(null);
|
|
6889
7769
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6890
7770
|
setToolbarShowEditLink(false);
|
|
6891
|
-
|
|
7771
|
+
postToParent2({ type: "ow:exit-edit" });
|
|
6892
7772
|
reselectNavigationItem(navAnchor);
|
|
6893
|
-
}, [
|
|
6894
|
-
const
|
|
6895
|
-
const
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
7773
|
+
}, [postToParent2, reselectNavigationItem]);
|
|
7774
|
+
const handleAddTopLevelNavItem = useCallback3(() => {
|
|
7775
|
+
const items = listNavbarItems();
|
|
7776
|
+
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
7777
|
+
deselectRef.current();
|
|
7778
|
+
deactivateRef.current();
|
|
7779
|
+
bumpLinkPopoverGrace();
|
|
7780
|
+
setLinkPopover({
|
|
7781
|
+
key: "__add-nav__",
|
|
7782
|
+
mode: "create",
|
|
7783
|
+
intent: "add-nav"
|
|
7784
|
+
});
|
|
6900
7785
|
}, []);
|
|
6901
|
-
const handleItemDragStart =
|
|
7786
|
+
const handleItemDragStart = useCallback3(() => {
|
|
6902
7787
|
siblingHintElRef.current = null;
|
|
6903
7788
|
setSiblingHintRect(null);
|
|
6904
7789
|
setIsItemDragging(true);
|
|
6905
7790
|
}, []);
|
|
6906
|
-
const handleItemDragEnd =
|
|
7791
|
+
const handleItemDragEnd = useCallback3(() => {
|
|
6907
7792
|
setIsItemDragging(false);
|
|
6908
7793
|
}, []);
|
|
6909
7794
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
6910
7795
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
6911
|
-
const select =
|
|
7796
|
+
const select = useCallback3((anchor) => {
|
|
6912
7797
|
if (!isNavigationItem(anchor)) return;
|
|
6913
7798
|
if (activeElRef.current) deactivate();
|
|
6914
7799
|
selectedElRef.current = anchor;
|
|
6915
7800
|
clearHrefKeyHover(anchor);
|
|
7801
|
+
hoveredNavContainerRef.current = null;
|
|
7802
|
+
setHoveredNavContainerRect(null);
|
|
6916
7803
|
setHoveredItemRect(null);
|
|
6917
7804
|
hoveredItemElRef.current = null;
|
|
6918
7805
|
siblingHintElRef.current = null;
|
|
@@ -6926,7 +7813,26 @@ function OhhwellsBridge() {
|
|
|
6926
7813
|
setToolbarShowEditLink(false);
|
|
6927
7814
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6928
7815
|
}, [deactivate]);
|
|
6929
|
-
const
|
|
7816
|
+
const selectFrame = useCallback3((el) => {
|
|
7817
|
+
if (!isNavigationContainer(el)) return;
|
|
7818
|
+
if (activeElRef.current) deactivate();
|
|
7819
|
+
selectedElRef.current = el;
|
|
7820
|
+
clearHrefKeyHover(el);
|
|
7821
|
+
hoveredNavContainerRef.current = null;
|
|
7822
|
+
setHoveredNavContainerRect(null);
|
|
7823
|
+
setHoveredItemRect(null);
|
|
7824
|
+
hoveredItemElRef.current = null;
|
|
7825
|
+
siblingHintElRef.current = null;
|
|
7826
|
+
setSiblingHintRect(null);
|
|
7827
|
+
setIsItemDragging(false);
|
|
7828
|
+
setReorderHrefKey(null);
|
|
7829
|
+
setReorderDragDisabled(false);
|
|
7830
|
+
setToolbarVariant("select-frame");
|
|
7831
|
+
setToolbarRect(el.getBoundingClientRect());
|
|
7832
|
+
setToolbarShowEditLink(false);
|
|
7833
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7834
|
+
}, [deactivate]);
|
|
7835
|
+
const activate = useCallback3((el, options) => {
|
|
6930
7836
|
if (activeElRef.current === el) return;
|
|
6931
7837
|
selectedElRef.current = null;
|
|
6932
7838
|
deactivate();
|
|
@@ -6944,6 +7850,9 @@ function OhhwellsBridge() {
|
|
|
6944
7850
|
activeElRef.current = el;
|
|
6945
7851
|
originalContentRef.current = el.innerHTML;
|
|
6946
7852
|
el.focus();
|
|
7853
|
+
if (options?.caretX !== void 0 && options?.caretY !== void 0) {
|
|
7854
|
+
placeCaretAtPoint(el, options.caretX, options.caretY);
|
|
7855
|
+
}
|
|
6947
7856
|
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
6948
7857
|
const navAnchor = getNavigationItemAnchor(el);
|
|
6949
7858
|
if (navAnchor) {
|
|
@@ -6955,12 +7864,13 @@ function OhhwellsBridge() {
|
|
|
6955
7864
|
setReorderDragDisabled(reorderDisabled);
|
|
6956
7865
|
}
|
|
6957
7866
|
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
6958
|
-
|
|
7867
|
+
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
6959
7868
|
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
6960
|
-
}, [deactivate,
|
|
7869
|
+
}, [deactivate, postToParent2]);
|
|
6961
7870
|
activateRef.current = activate;
|
|
6962
7871
|
deactivateRef.current = deactivate;
|
|
6963
7872
|
selectRef.current = select;
|
|
7873
|
+
selectFrameRef.current = selectFrame;
|
|
6964
7874
|
deselectRef.current = deselect;
|
|
6965
7875
|
useLayoutEffect2(() => {
|
|
6966
7876
|
if (!subdomain || isEditMode) {
|
|
@@ -7002,6 +7912,7 @@ function OhhwellsBridge() {
|
|
|
7002
7912
|
});
|
|
7003
7913
|
applyLinkByKey(key, val);
|
|
7004
7914
|
}
|
|
7915
|
+
reconcileNavbarItemsFromContent(content);
|
|
7005
7916
|
enforceLinkHrefs();
|
|
7006
7917
|
initSectionsFromContent(content, true);
|
|
7007
7918
|
sectionsLoadedRef.current = true;
|
|
@@ -7030,7 +7941,7 @@ function OhhwellsBridge() {
|
|
|
7030
7941
|
cancelled = true;
|
|
7031
7942
|
};
|
|
7032
7943
|
}, [subdomain, isEditMode]);
|
|
7033
|
-
|
|
7944
|
+
useEffect7(() => {
|
|
7034
7945
|
if (!subdomain || isEditMode) return;
|
|
7035
7946
|
let debounceTimer = null;
|
|
7036
7947
|
let observer = null;
|
|
@@ -7061,6 +7972,7 @@ function OhhwellsBridge() {
|
|
|
7061
7972
|
});
|
|
7062
7973
|
applyLinkByKey(key, val);
|
|
7063
7974
|
}
|
|
7975
|
+
reconcileNavbarItemsFromContent(content);
|
|
7064
7976
|
} finally {
|
|
7065
7977
|
observer?.observe(document.body, { childList: true, subtree: true });
|
|
7066
7978
|
}
|
|
@@ -7084,20 +7996,38 @@ function OhhwellsBridge() {
|
|
|
7084
7996
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
7085
7997
|
el.style.display = visible ? "flex" : "none";
|
|
7086
7998
|
}, [subdomain, fetchState]);
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
}, [pathname,
|
|
7090
|
-
|
|
7999
|
+
useEffect7(() => {
|
|
8000
|
+
postToParent2({ type: "ow:navigation", path: pathname });
|
|
8001
|
+
}, [pathname, postToParent2]);
|
|
8002
|
+
useEffect7(() => {
|
|
7091
8003
|
if (!isEditMode) return;
|
|
8004
|
+
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
8005
|
+
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
7092
8006
|
setLinkPopover(null);
|
|
7093
8007
|
deselectRef.current();
|
|
7094
8008
|
deactivateRef.current();
|
|
7095
8009
|
}, [pathname, isEditMode]);
|
|
7096
|
-
|
|
8010
|
+
useEffect7(() => {
|
|
8011
|
+
const contentForNav = () => {
|
|
8012
|
+
if (isEditMode) return editContentRef.current;
|
|
8013
|
+
if (!subdomain) return {};
|
|
8014
|
+
return contentCache.get(subdomain) ?? {};
|
|
8015
|
+
};
|
|
8016
|
+
const run = () => reconcileNavbarItemsFromContent(contentForNav());
|
|
8017
|
+
run();
|
|
8018
|
+
const nav = document.querySelector("nav");
|
|
8019
|
+
if (!nav) return;
|
|
8020
|
+
const observer = new MutationObserver(() => {
|
|
8021
|
+
requestAnimationFrame(run);
|
|
8022
|
+
});
|
|
8023
|
+
observer.observe(nav, { childList: true, subtree: true });
|
|
8024
|
+
return () => observer.disconnect();
|
|
8025
|
+
}, [isEditMode, pathname, subdomain, fetchState]);
|
|
8026
|
+
useEffect7(() => {
|
|
7097
8027
|
if (!isEditMode) return;
|
|
7098
8028
|
const measure = () => {
|
|
7099
8029
|
const h = document.body.scrollHeight;
|
|
7100
|
-
if (h > 50)
|
|
8030
|
+
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
7101
8031
|
};
|
|
7102
8032
|
const t1 = setTimeout(measure, 50);
|
|
7103
8033
|
const t2 = setTimeout(measure, 500);
|
|
@@ -7116,8 +8046,8 @@ function OhhwellsBridge() {
|
|
|
7116
8046
|
if (resizeTimer) clearTimeout(resizeTimer);
|
|
7117
8047
|
window.removeEventListener("resize", handleResize);
|
|
7118
8048
|
};
|
|
7119
|
-
}, [pathname, isEditMode,
|
|
7120
|
-
|
|
8049
|
+
}, [pathname, isEditMode, postToParent2]);
|
|
8050
|
+
useEffect7(() => {
|
|
7121
8051
|
if (!subdomainFromQuery || isEditMode) return;
|
|
7122
8052
|
const handleClick = (e) => {
|
|
7123
8053
|
const anchor = e.target.closest("a");
|
|
@@ -7133,7 +8063,7 @@ function OhhwellsBridge() {
|
|
|
7133
8063
|
document.addEventListener("click", handleClick, true);
|
|
7134
8064
|
return () => document.removeEventListener("click", handleClick, true);
|
|
7135
8065
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
7136
|
-
|
|
8066
|
+
useEffect7(() => {
|
|
7137
8067
|
if (!isEditMode) {
|
|
7138
8068
|
editStylesRef.current?.base.remove();
|
|
7139
8069
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -7206,6 +8136,13 @@ function OhhwellsBridge() {
|
|
|
7206
8136
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
7207
8137
|
if (isInsideLinkEditor(target)) return;
|
|
7208
8138
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
8139
|
+
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8140
|
+
if (navFromChrome) {
|
|
8141
|
+
e.preventDefault();
|
|
8142
|
+
e.stopPropagation();
|
|
8143
|
+
selectFrameRef.current(navFromChrome);
|
|
8144
|
+
return;
|
|
8145
|
+
}
|
|
7209
8146
|
e.preventDefault();
|
|
7210
8147
|
e.stopPropagation();
|
|
7211
8148
|
return;
|
|
@@ -7220,7 +8157,8 @@ function OhhwellsBridge() {
|
|
|
7220
8157
|
bumpLinkPopoverGrace();
|
|
7221
8158
|
setLinkPopoverRef.current({
|
|
7222
8159
|
key: editable.dataset.ohwKey ?? "",
|
|
7223
|
-
|
|
8160
|
+
mode: "edit",
|
|
8161
|
+
target: getLinkHref2(editable)
|
|
7224
8162
|
});
|
|
7225
8163
|
return;
|
|
7226
8164
|
}
|
|
@@ -7236,7 +8174,8 @@ function OhhwellsBridge() {
|
|
|
7236
8174
|
e.preventDefault();
|
|
7237
8175
|
e.stopPropagation();
|
|
7238
8176
|
if (selectedElRef.current === navAnchor) {
|
|
7239
|
-
|
|
8177
|
+
if (e.detail >= 2) return;
|
|
8178
|
+
activateRef.current(editable, { caretX: e.clientX, caretY: e.clientY });
|
|
7240
8179
|
return;
|
|
7241
8180
|
}
|
|
7242
8181
|
selectRef.current(navAnchor);
|
|
@@ -7255,6 +8194,22 @@ function OhhwellsBridge() {
|
|
|
7255
8194
|
selectRef.current(hrefAnchor);
|
|
7256
8195
|
return;
|
|
7257
8196
|
}
|
|
8197
|
+
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8198
|
+
if (navContainerToSelect) {
|
|
8199
|
+
e.preventDefault();
|
|
8200
|
+
e.stopPropagation();
|
|
8201
|
+
selectFrameRef.current(navContainerToSelect);
|
|
8202
|
+
return;
|
|
8203
|
+
}
|
|
8204
|
+
const selectedContainer = selectedElRef.current;
|
|
8205
|
+
if (selectedContainer && isNavigationContainer(selectedContainer)) {
|
|
8206
|
+
const navItem = getNavigationItemAnchor(target);
|
|
8207
|
+
if (!navItem && (selectedContainer === target || selectedContainer.contains(target))) {
|
|
8208
|
+
e.preventDefault();
|
|
8209
|
+
e.stopPropagation();
|
|
8210
|
+
return;
|
|
8211
|
+
}
|
|
8212
|
+
}
|
|
7258
8213
|
if (activeElRef.current) {
|
|
7259
8214
|
const sel = window.getSelection();
|
|
7260
8215
|
if (sel && !sel.isCollapsed) {
|
|
@@ -7280,10 +8235,49 @@ function OhhwellsBridge() {
|
|
|
7280
8235
|
deselectRef.current();
|
|
7281
8236
|
deactivateRef.current();
|
|
7282
8237
|
};
|
|
8238
|
+
const handleDblClick = (e) => {
|
|
8239
|
+
const target = e.target;
|
|
8240
|
+
if (target.closest("[data-ohw-toolbar]")) return;
|
|
8241
|
+
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
8242
|
+
if (target.closest("[data-ohw-max-badge]")) return;
|
|
8243
|
+
if (isInsideLinkEditor(target)) return;
|
|
8244
|
+
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
8245
|
+
return;
|
|
8246
|
+
}
|
|
8247
|
+
const navLabel = getNavigationLabelEditable(target);
|
|
8248
|
+
if (!navLabel) return;
|
|
8249
|
+
const { editable } = navLabel;
|
|
8250
|
+
e.preventDefault();
|
|
8251
|
+
e.stopPropagation();
|
|
8252
|
+
if (activeElRef.current !== editable) {
|
|
8253
|
+
activateRef.current(editable);
|
|
8254
|
+
}
|
|
8255
|
+
requestAnimationFrame(() => {
|
|
8256
|
+
selectAllTextInEditable(editable);
|
|
8257
|
+
refreshActiveCommandsRef.current();
|
|
8258
|
+
});
|
|
8259
|
+
};
|
|
7283
8260
|
const handleMouseOver = (e) => {
|
|
8261
|
+
if (document.documentElement.hasAttribute("data-ohw-section-picking")) return;
|
|
7284
8262
|
const target = e.target;
|
|
8263
|
+
if (toolbarVariantRef.current !== "select-frame") {
|
|
8264
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
8265
|
+
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
8266
|
+
hoveredNavContainerRef.current = navContainer;
|
|
8267
|
+
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
8268
|
+
hoveredItemElRef.current = null;
|
|
8269
|
+
setHoveredItemRect(null);
|
|
8270
|
+
return;
|
|
8271
|
+
}
|
|
8272
|
+
if (!target.closest("[data-ohw-nav-container]")) {
|
|
8273
|
+
hoveredNavContainerRef.current = null;
|
|
8274
|
+
setHoveredNavContainerRect(null);
|
|
8275
|
+
}
|
|
8276
|
+
}
|
|
7285
8277
|
const navAnchor = getNavigationItemAnchor(target);
|
|
7286
8278
|
if (navAnchor) {
|
|
8279
|
+
hoveredNavContainerRef.current = null;
|
|
8280
|
+
setHoveredNavContainerRect(null);
|
|
7287
8281
|
const selected2 = selectedElRef.current;
|
|
7288
8282
|
if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
|
|
7289
8283
|
clearHrefKeyHover(navAnchor);
|
|
@@ -7308,6 +8302,14 @@ function OhhwellsBridge() {
|
|
|
7308
8302
|
};
|
|
7309
8303
|
const handleMouseOut = (e) => {
|
|
7310
8304
|
const target = e.target;
|
|
8305
|
+
if (target.closest("[data-ohw-nav-container]")) {
|
|
8306
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
8307
|
+
if (related2?.closest("[data-ohw-nav-container], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
8308
|
+
return;
|
|
8309
|
+
}
|
|
8310
|
+
hoveredNavContainerRef.current = null;
|
|
8311
|
+
setHoveredNavContainerRect(null);
|
|
8312
|
+
}
|
|
7311
8313
|
const navAnchor = getNavigationItemAnchor(target);
|
|
7312
8314
|
if (navAnchor) {
|
|
7313
8315
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -7429,6 +8431,56 @@ function OhhwellsBridge() {
|
|
|
7429
8431
|
}
|
|
7430
8432
|
return smallest;
|
|
7431
8433
|
};
|
|
8434
|
+
const dismissImageHover = () => {
|
|
8435
|
+
if (hoveredImageRef.current) {
|
|
8436
|
+
hoveredImageRef.current = null;
|
|
8437
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
8438
|
+
resumeAnimTracks();
|
|
8439
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8440
|
+
}
|
|
8441
|
+
};
|
|
8442
|
+
const probeNavigationHoverAt = (x, y) => {
|
|
8443
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
8444
|
+
hoveredNavContainerRef.current = null;
|
|
8445
|
+
setHoveredNavContainerRect(null);
|
|
8446
|
+
return;
|
|
8447
|
+
}
|
|
8448
|
+
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
8449
|
+
if (!navContainer) {
|
|
8450
|
+
hoveredNavContainerRef.current = null;
|
|
8451
|
+
setHoveredNavContainerRect(null);
|
|
8452
|
+
return;
|
|
8453
|
+
}
|
|
8454
|
+
const containerRect = navContainer.getBoundingClientRect();
|
|
8455
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
8456
|
+
if (!overContainer) {
|
|
8457
|
+
hoveredNavContainerRef.current = null;
|
|
8458
|
+
setHoveredNavContainerRect(null);
|
|
8459
|
+
return;
|
|
8460
|
+
}
|
|
8461
|
+
const navItemHit = Array.from(
|
|
8462
|
+
navContainer.querySelectorAll("[data-ohw-href-key]")
|
|
8463
|
+
).find((el) => {
|
|
8464
|
+
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
8465
|
+
const itemRect = el.getBoundingClientRect();
|
|
8466
|
+
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
8467
|
+
});
|
|
8468
|
+
if (navItemHit) {
|
|
8469
|
+
hoveredNavContainerRef.current = null;
|
|
8470
|
+
setHoveredNavContainerRect(null);
|
|
8471
|
+
const selected = selectedElRef.current;
|
|
8472
|
+
if (selected !== navItemHit && !selected?.contains(navItemHit)) {
|
|
8473
|
+
clearHrefKeyHover(navItemHit);
|
|
8474
|
+
hoveredItemElRef.current = navItemHit;
|
|
8475
|
+
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
8476
|
+
}
|
|
8477
|
+
return;
|
|
8478
|
+
}
|
|
8479
|
+
hoveredNavContainerRef.current = navContainer;
|
|
8480
|
+
setHoveredNavContainerRect(containerRect);
|
|
8481
|
+
hoveredItemElRef.current = null;
|
|
8482
|
+
setHoveredItemRect(null);
|
|
8483
|
+
};
|
|
7432
8484
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
7433
8485
|
if (linkPopoverOpenRef.current) {
|
|
7434
8486
|
if (hoveredImageRef.current) {
|
|
@@ -7437,18 +8489,22 @@ function OhhwellsBridge() {
|
|
|
7437
8489
|
resumeAnimTracks();
|
|
7438
8490
|
clearImageHover();
|
|
7439
8491
|
}
|
|
8492
|
+
dismissImageHover();
|
|
8493
|
+
return;
|
|
8494
|
+
}
|
|
8495
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8496
|
+
if (isPointOverNavigation(x, y)) {
|
|
8497
|
+
dismissImageHover();
|
|
8498
|
+
probeNavigationHoverAt(x, y);
|
|
7440
8499
|
return;
|
|
7441
8500
|
}
|
|
8501
|
+
hoveredNavContainerRef.current = null;
|
|
8502
|
+
setHoveredNavContainerRect(null);
|
|
7442
8503
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
7443
8504
|
if (toggleEl) {
|
|
7444
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7445
8505
|
const tr = toggleEl.getBoundingClientRect();
|
|
7446
8506
|
if (x >= tr.left && x <= tr.right && y >= tr.top && y <= tr.bottom) {
|
|
7447
|
-
|
|
7448
|
-
hoveredImageRef.current = null;
|
|
7449
|
-
resumeAnimTracks();
|
|
7450
|
-
clearImageHover();
|
|
7451
|
-
}
|
|
8507
|
+
dismissImageHover();
|
|
7452
8508
|
return;
|
|
7453
8509
|
}
|
|
7454
8510
|
}
|
|
@@ -7461,15 +8517,18 @@ function OhhwellsBridge() {
|
|
|
7461
8517
|
resumeAnimTracks();
|
|
7462
8518
|
clearImageHover();
|
|
7463
8519
|
}
|
|
7464
|
-
|
|
8520
|
+
if (activeElRef.current) {
|
|
8521
|
+
dismissImageHover();
|
|
8522
|
+
return;
|
|
8523
|
+
}
|
|
7465
8524
|
}
|
|
7466
8525
|
if (imgEl) {
|
|
7467
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8526
|
+
const { x: x2, y: y2 } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7468
8527
|
const overMediaChrome = Array.from(
|
|
7469
8528
|
document.querySelectorAll("[data-ohw-media-chrome]")
|
|
7470
8529
|
).some((el) => {
|
|
7471
8530
|
const r2 = el.getBoundingClientRect();
|
|
7472
|
-
return
|
|
8531
|
+
return x2 >= r2.left && x2 <= r2.right && y2 >= r2.top && y2 <= r2.bottom;
|
|
7473
8532
|
});
|
|
7474
8533
|
if (overMediaChrome) {
|
|
7475
8534
|
if (hoveredImageRef.current) {
|
|
@@ -7480,7 +8539,7 @@ function OhhwellsBridge() {
|
|
|
7480
8539
|
}
|
|
7481
8540
|
return;
|
|
7482
8541
|
}
|
|
7483
|
-
const topEl = document.elementFromPoint(
|
|
8542
|
+
const topEl = document.elementFromPoint(x2, y2);
|
|
7484
8543
|
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
7485
8544
|
if (hoveredImageRef.current) {
|
|
7486
8545
|
hoveredImageRef.current = null;
|
|
@@ -7503,7 +8562,7 @@ function OhhwellsBridge() {
|
|
|
7503
8562
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7504
8563
|
).find((el) => {
|
|
7505
8564
|
const er = el.getBoundingClientRect();
|
|
7506
|
-
return
|
|
8565
|
+
return x2 >= er.left && x2 <= er.right && y2 >= er.top && y2 <= er.bottom;
|
|
7507
8566
|
});
|
|
7508
8567
|
if (imageUnhoverTimerRef.current) {
|
|
7509
8568
|
clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -7579,12 +8638,12 @@ function OhhwellsBridge() {
|
|
|
7579
8638
|
resumeAnimTracks();
|
|
7580
8639
|
clearImageHover();
|
|
7581
8640
|
}
|
|
7582
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8641
|
+
const { x: x2, y: y2 } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7583
8642
|
const textEl = Array.from(
|
|
7584
8643
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7585
8644
|
).find((el) => {
|
|
7586
8645
|
const er = el.getBoundingClientRect();
|
|
7587
|
-
return
|
|
8646
|
+
return x2 >= er.left && x2 <= er.right && y2 >= er.top && y2 <= er.bottom;
|
|
7588
8647
|
});
|
|
7589
8648
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7590
8649
|
if (textEl && !textEl.hasAttribute("contenteditable")) {
|
|
@@ -7608,6 +8667,14 @@ function OhhwellsBridge() {
|
|
|
7608
8667
|
}
|
|
7609
8668
|
};
|
|
7610
8669
|
const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
|
|
8670
|
+
if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
8671
|
+
if (activeStateElRef.current) {
|
|
8672
|
+
activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
|
|
8673
|
+
activeStateElRef.current = null;
|
|
8674
|
+
setToggleState(null);
|
|
8675
|
+
}
|
|
8676
|
+
return;
|
|
8677
|
+
}
|
|
7611
8678
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7612
8679
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
7613
8680
|
if (toggleEl) {
|
|
@@ -7884,6 +8951,8 @@ function OhhwellsBridge() {
|
|
|
7884
8951
|
sectionsLoadedRef.current = true;
|
|
7885
8952
|
pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
|
|
7886
8953
|
}
|
|
8954
|
+
editContentRef.current = { ...editContentRef.current, ...content };
|
|
8955
|
+
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
7887
8956
|
enforceLinkHrefs();
|
|
7888
8957
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
7889
8958
|
};
|
|
@@ -7891,6 +8960,7 @@ function OhhwellsBridge() {
|
|
|
7891
8960
|
const handleDeactivate = (e) => {
|
|
7892
8961
|
if (e.data?.type !== "ow:deactivate") return;
|
|
7893
8962
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
8963
|
+
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
7894
8964
|
if (linkPopoverOpenRef.current) {
|
|
7895
8965
|
setLinkPopoverRef.current(null);
|
|
7896
8966
|
return;
|
|
@@ -7899,13 +8969,40 @@ function OhhwellsBridge() {
|
|
|
7899
8969
|
deactivateRef.current();
|
|
7900
8970
|
};
|
|
7901
8971
|
window.addEventListener("message", handleDeactivate);
|
|
8972
|
+
const handleUiEscape = (e) => {
|
|
8973
|
+
if (e.data?.type !== "ui:escape") return;
|
|
8974
|
+
if (linkPopoverOpenRef.current) {
|
|
8975
|
+
setLinkPopoverRef.current(null);
|
|
8976
|
+
}
|
|
8977
|
+
};
|
|
8978
|
+
window.addEventListener("message", handleUiEscape);
|
|
7902
8979
|
const handleKeyDown = (e) => {
|
|
8980
|
+
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
8981
|
+
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
8982
|
+
const navAnchor = getNavigationItemAnchor(activeElRef.current);
|
|
8983
|
+
if (navAnchor) {
|
|
8984
|
+
e.preventDefault();
|
|
8985
|
+
selectAllTextInEditable(activeElRef.current);
|
|
8986
|
+
refreshActiveCommandsRef.current();
|
|
8987
|
+
return;
|
|
8988
|
+
}
|
|
8989
|
+
}
|
|
7903
8990
|
if (e.key === "Escape" && linkPopoverOpenRef.current) {
|
|
7904
8991
|
setLinkPopoverRef.current(null);
|
|
7905
8992
|
return;
|
|
7906
8993
|
}
|
|
7907
8994
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
7908
|
-
|
|
8995
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
8996
|
+
deselectRef.current();
|
|
8997
|
+
return;
|
|
8998
|
+
}
|
|
8999
|
+
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
9000
|
+
if (parent) {
|
|
9001
|
+
e.preventDefault();
|
|
9002
|
+
selectFrameRef.current(parent);
|
|
9003
|
+
} else {
|
|
9004
|
+
deselectRef.current();
|
|
9005
|
+
}
|
|
7909
9006
|
return;
|
|
7910
9007
|
}
|
|
7911
9008
|
if (e.key === "Escape" && activeElRef.current) {
|
|
@@ -7963,6 +9060,9 @@ function OhhwellsBridge() {
|
|
|
7963
9060
|
if (hoveredItemElRef.current) {
|
|
7964
9061
|
setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
|
|
7965
9062
|
}
|
|
9063
|
+
if (hoveredNavContainerRef.current) {
|
|
9064
|
+
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
9065
|
+
}
|
|
7966
9066
|
if (siblingHintElRef.current) {
|
|
7967
9067
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
7968
9068
|
}
|
|
@@ -8159,9 +9259,45 @@ function OhhwellsBridge() {
|
|
|
8159
9259
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
8160
9260
|
});
|
|
8161
9261
|
if (textEditable) {
|
|
8162
|
-
|
|
9262
|
+
const hrefCtx = getHrefKeyFromElement(textEditable);
|
|
9263
|
+
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
9264
|
+
if (navAnchor) {
|
|
9265
|
+
if (selectedElRef.current === navAnchor) {
|
|
9266
|
+
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
9267
|
+
} else {
|
|
9268
|
+
selectRef.current(navAnchor);
|
|
9269
|
+
}
|
|
9270
|
+
return;
|
|
9271
|
+
}
|
|
9272
|
+
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
8163
9273
|
return;
|
|
8164
9274
|
}
|
|
9275
|
+
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
9276
|
+
if (navContainer) {
|
|
9277
|
+
const r2 = navContainer.getBoundingClientRect();
|
|
9278
|
+
const pad = 8;
|
|
9279
|
+
const over = clientX >= r2.left - pad && clientX <= r2.right + pad && clientY >= r2.top - pad && clientY <= r2.bottom + pad;
|
|
9280
|
+
if (over && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
9281
|
+
selectFrameRef.current(navContainer);
|
|
9282
|
+
return;
|
|
9283
|
+
}
|
|
9284
|
+
}
|
|
9285
|
+
const navRoot = document.querySelector("[data-ohw-nav-root]");
|
|
9286
|
+
if (navRoot && navContainer) {
|
|
9287
|
+
const rr = navRoot.getBoundingClientRect();
|
|
9288
|
+
if (clientX >= rr.left && clientX <= rr.right && clientY >= rr.top && clientY <= rr.bottom && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
9289
|
+
const book = navRoot.querySelector('[data-ohw-role="navbar-button"]');
|
|
9290
|
+
if (book) {
|
|
9291
|
+
const br = book.getBoundingClientRect();
|
|
9292
|
+
if (clientX >= br.left && clientX <= br.right && clientY >= br.top && clientY <= br.bottom) {
|
|
9293
|
+
deactivateRef.current();
|
|
9294
|
+
return;
|
|
9295
|
+
}
|
|
9296
|
+
}
|
|
9297
|
+
selectFrameRef.current(navContainer);
|
|
9298
|
+
return;
|
|
9299
|
+
}
|
|
9300
|
+
}
|
|
8165
9301
|
deactivateRef.current();
|
|
8166
9302
|
};
|
|
8167
9303
|
window.addEventListener("message", handleSave);
|
|
@@ -8183,6 +9319,7 @@ function OhhwellsBridge() {
|
|
|
8183
9319
|
};
|
|
8184
9320
|
window.addEventListener("resize", handleViewportResize, { passive: true });
|
|
8185
9321
|
document.addEventListener("click", handleClick, true);
|
|
9322
|
+
document.addEventListener("dblclick", handleDblClick, true);
|
|
8186
9323
|
document.addEventListener("paste", handlePaste, true);
|
|
8187
9324
|
document.addEventListener("input", handleInput, true);
|
|
8188
9325
|
document.addEventListener("mouseover", handleMouseOver, true);
|
|
@@ -8197,6 +9334,7 @@ function OhhwellsBridge() {
|
|
|
8197
9334
|
window.addEventListener("scroll", handleScroll, true);
|
|
8198
9335
|
return () => {
|
|
8199
9336
|
document.removeEventListener("click", handleClick, true);
|
|
9337
|
+
document.removeEventListener("dblclick", handleDblClick, true);
|
|
8200
9338
|
document.removeEventListener("paste", handlePaste, true);
|
|
8201
9339
|
document.removeEventListener("input", handleInput, true);
|
|
8202
9340
|
document.removeEventListener("mouseover", handleMouseOver, true);
|
|
@@ -8224,13 +9362,14 @@ function OhhwellsBridge() {
|
|
|
8224
9362
|
window.removeEventListener("message", handleClickAt);
|
|
8225
9363
|
window.removeEventListener("message", handleHydrate);
|
|
8226
9364
|
window.removeEventListener("message", handleDeactivate);
|
|
9365
|
+
window.removeEventListener("message", handleUiEscape);
|
|
8227
9366
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
8228
9367
|
autoSaveTimers.current.clear();
|
|
8229
9368
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
8230
9369
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
8231
9370
|
};
|
|
8232
9371
|
}, [isEditMode, refreshStateRules]);
|
|
8233
|
-
|
|
9372
|
+
useEffect7(() => {
|
|
8234
9373
|
const handler = (e) => {
|
|
8235
9374
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
8236
9375
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -8246,7 +9385,7 @@ function OhhwellsBridge() {
|
|
|
8246
9385
|
window.addEventListener("message", handler);
|
|
8247
9386
|
return () => window.removeEventListener("message", handler);
|
|
8248
9387
|
}, [processConfigRequest]);
|
|
8249
|
-
|
|
9388
|
+
useEffect7(() => {
|
|
8250
9389
|
if (!isEditMode) return;
|
|
8251
9390
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
8252
9391
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -8267,27 +9406,27 @@ function OhhwellsBridge() {
|
|
|
8267
9406
|
const next = { ...prev, [pathKey]: sections };
|
|
8268
9407
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
8269
9408
|
});
|
|
8270
|
-
|
|
8271
|
-
|
|
9409
|
+
postToParent2({ type: "ow:ready", version: "1", path: pathname, nodes: collectEditableNodes(), sections });
|
|
9410
|
+
postToParent2({ type: "ow:request-site-pages" });
|
|
8272
9411
|
}, 150);
|
|
8273
9412
|
return () => {
|
|
8274
9413
|
cancelAnimationFrame(raf);
|
|
8275
9414
|
clearTimeout(timer);
|
|
8276
9415
|
};
|
|
8277
|
-
}, [pathname, isEditMode, refreshStateRules,
|
|
8278
|
-
|
|
9416
|
+
}, [pathname, isEditMode, refreshStateRules, postToParent2]);
|
|
9417
|
+
useEffect7(() => {
|
|
8279
9418
|
scrollToHashSectionWhenReady();
|
|
8280
9419
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
8281
9420
|
window.addEventListener("hashchange", onHashChange);
|
|
8282
9421
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
8283
9422
|
}, [pathname]);
|
|
8284
|
-
const handleCommand =
|
|
9423
|
+
const handleCommand = useCallback3((cmd) => {
|
|
8285
9424
|
document.execCommand(cmd, false);
|
|
8286
9425
|
activeElRef.current?.focus();
|
|
8287
9426
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
8288
9427
|
refreshActiveCommandsRef.current();
|
|
8289
9428
|
}, []);
|
|
8290
|
-
const handleStateChange =
|
|
9429
|
+
const handleStateChange = useCallback3((state) => {
|
|
8291
9430
|
if (!activeStateElRef.current) return;
|
|
8292
9431
|
const el = activeStateElRef.current;
|
|
8293
9432
|
if (state === "Default") {
|
|
@@ -8300,18 +9439,22 @@ function OhhwellsBridge() {
|
|
|
8300
9439
|
}
|
|
8301
9440
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
8302
9441
|
}, [deactivate]);
|
|
8303
|
-
const closeLinkPopover =
|
|
8304
|
-
|
|
9442
|
+
const closeLinkPopover = useCallback3(() => {
|
|
9443
|
+
addNavAfterAnchorRef.current = null;
|
|
9444
|
+
setLinkPopover(null);
|
|
9445
|
+
}, []);
|
|
9446
|
+
const openLinkPopoverForActive = useCallback3(() => {
|
|
8305
9447
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
8306
9448
|
if (!hrefCtx) return;
|
|
8307
9449
|
bumpLinkPopoverGrace();
|
|
8308
9450
|
setLinkPopover({
|
|
8309
9451
|
key: hrefCtx.key,
|
|
8310
|
-
|
|
9452
|
+
mode: "edit",
|
|
9453
|
+
target: getLinkHref2(hrefCtx.anchor)
|
|
8311
9454
|
});
|
|
8312
9455
|
deactivate();
|
|
8313
9456
|
}, [deactivate]);
|
|
8314
|
-
const openLinkPopoverForSelected =
|
|
9457
|
+
const openLinkPopoverForSelected = useCallback3(() => {
|
|
8315
9458
|
const anchor = selectedElRef.current;
|
|
8316
9459
|
if (!anchor) return;
|
|
8317
9460
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -8319,30 +9462,77 @@ function OhhwellsBridge() {
|
|
|
8319
9462
|
bumpLinkPopoverGrace();
|
|
8320
9463
|
setLinkPopover({
|
|
8321
9464
|
key,
|
|
8322
|
-
|
|
9465
|
+
mode: "edit",
|
|
9466
|
+
target: getLinkHref2(anchor)
|
|
8323
9467
|
});
|
|
8324
9468
|
deselect();
|
|
8325
9469
|
}, [deselect]);
|
|
8326
|
-
const handleLinkPopoverSubmit =
|
|
9470
|
+
const handleLinkPopoverSubmit = useCallback3(
|
|
8327
9471
|
(target) => {
|
|
8328
|
-
|
|
8329
|
-
|
|
9472
|
+
const session = linkPopoverSessionRef.current;
|
|
9473
|
+
if (!session) return;
|
|
9474
|
+
if (session.intent === "add-nav") {
|
|
9475
|
+
const trimmed = target.trim();
|
|
9476
|
+
let href = trimmed;
|
|
9477
|
+
let label = "Untitled";
|
|
9478
|
+
if (trimmed) {
|
|
9479
|
+
const { pageRoute, sectionId } = parseTarget(trimmed);
|
|
9480
|
+
const page = resolvePage(pageRoute, sitePages);
|
|
9481
|
+
const pageSections = getSectionsForPath(sectionsByPath, pageRoute);
|
|
9482
|
+
const section = sectionId ? pageSections.find((s) => s.id === sectionId) : void 0;
|
|
9483
|
+
label = section?.label ?? page.title;
|
|
9484
|
+
href = trimmed;
|
|
9485
|
+
}
|
|
9486
|
+
const afterAnchor = addNavAfterAnchorRef.current;
|
|
9487
|
+
const { anchor, hrefKey, labelKey, index, order } = insertNavbarItem(href, label, afterAnchor);
|
|
9488
|
+
applyLinkByKey(hrefKey, href);
|
|
9489
|
+
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
9490
|
+
el.textContent = label;
|
|
9491
|
+
});
|
|
9492
|
+
const navCount = String(index + 1);
|
|
9493
|
+
const orderJson = JSON.stringify(order);
|
|
9494
|
+
editContentRef.current = {
|
|
9495
|
+
...editContentRef.current,
|
|
9496
|
+
[hrefKey]: href,
|
|
9497
|
+
[labelKey]: label,
|
|
9498
|
+
[NAV_COUNT_KEY]: navCount,
|
|
9499
|
+
[NAV_ORDER_KEY]: orderJson
|
|
9500
|
+
};
|
|
9501
|
+
postToParent2({
|
|
9502
|
+
type: "ow:change",
|
|
9503
|
+
nodes: [
|
|
9504
|
+
{ key: hrefKey, text: href },
|
|
9505
|
+
{ key: labelKey, text: label },
|
|
9506
|
+
{ key: NAV_COUNT_KEY, text: navCount },
|
|
9507
|
+
{ key: NAV_ORDER_KEY, text: orderJson }
|
|
9508
|
+
]
|
|
9509
|
+
});
|
|
9510
|
+
postToParent2({ type: "ow:toast", title: "Link added", toastType: "success" });
|
|
9511
|
+
addNavAfterAnchorRef.current = null;
|
|
9512
|
+
setLinkPopover(null);
|
|
9513
|
+
enforceLinkHrefs();
|
|
9514
|
+
requestAnimationFrame(() => {
|
|
9515
|
+
selectRef.current(anchor);
|
|
9516
|
+
});
|
|
9517
|
+
return;
|
|
9518
|
+
}
|
|
9519
|
+
const { key } = session;
|
|
8330
9520
|
applyLinkByKey(key, target);
|
|
8331
|
-
|
|
9521
|
+
postToParent2({ type: "ow:change", nodes: [{ key, text: target }] });
|
|
8332
9522
|
setLinkPopover(null);
|
|
8333
9523
|
},
|
|
8334
|
-
[
|
|
9524
|
+
[postToParent2, sitePages, sectionsByPath]
|
|
8335
9525
|
);
|
|
8336
9526
|
const showEditLink = toolbarShowEditLink;
|
|
8337
9527
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
8338
9528
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
8339
|
-
const handleMediaReplace =
|
|
9529
|
+
const handleMediaReplace = useCallback3(
|
|
8340
9530
|
(key) => {
|
|
8341
|
-
|
|
9531
|
+
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
8342
9532
|
},
|
|
8343
|
-
[
|
|
9533
|
+
[postToParent2, mediaHover?.elementType]
|
|
8344
9534
|
);
|
|
8345
|
-
const handleMediaFadeOutComplete =
|
|
9535
|
+
const handleMediaFadeOutComplete = useCallback3((key) => {
|
|
8346
9536
|
setUploadingRects((prev) => {
|
|
8347
9537
|
if (!(key in prev)) return prev;
|
|
8348
9538
|
const next = { ...prev };
|
|
@@ -8350,7 +9540,7 @@ function OhhwellsBridge() {
|
|
|
8350
9540
|
return next;
|
|
8351
9541
|
});
|
|
8352
9542
|
}, []);
|
|
8353
|
-
const handleVideoSettingsChange =
|
|
9543
|
+
const handleVideoSettingsChange = useCallback3(
|
|
8354
9544
|
(key, settings) => {
|
|
8355
9545
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8356
9546
|
const video = getVideoEl(el);
|
|
@@ -8358,7 +9548,7 @@ function OhhwellsBridge() {
|
|
|
8358
9548
|
if (typeof settings.autoplay === "boolean") video.autoplay = settings.autoplay;
|
|
8359
9549
|
if (typeof settings.muted === "boolean") video.muted = settings.muted;
|
|
8360
9550
|
syncVideoPlayback(video);
|
|
8361
|
-
|
|
9551
|
+
postToParent2({
|
|
8362
9552
|
type: "ow:change",
|
|
8363
9553
|
nodes: [
|
|
8364
9554
|
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
@@ -8370,12 +9560,12 @@ function OhhwellsBridge() {
|
|
|
8370
9560
|
);
|
|
8371
9561
|
});
|
|
8372
9562
|
},
|
|
8373
|
-
[
|
|
9563
|
+
[postToParent2]
|
|
8374
9564
|
);
|
|
8375
|
-
return bridgeRoot ?
|
|
8376
|
-
/* @__PURE__ */
|
|
8377
|
-
/* @__PURE__ */
|
|
8378
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */
|
|
9565
|
+
return bridgeRoot ? createPortal2(
|
|
9566
|
+
/* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
9567
|
+
/* @__PURE__ */ jsx23("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
9568
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx23(
|
|
8379
9569
|
MediaOverlay,
|
|
8380
9570
|
{
|
|
8381
9571
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -8386,7 +9576,7 @@ function OhhwellsBridge() {
|
|
|
8386
9576
|
},
|
|
8387
9577
|
`uploading-${key}`
|
|
8388
9578
|
)),
|
|
8389
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */
|
|
9579
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx23(
|
|
8390
9580
|
MediaOverlay,
|
|
8391
9581
|
{
|
|
8392
9582
|
hover: mediaHover,
|
|
@@ -8395,31 +9585,40 @@ function OhhwellsBridge() {
|
|
|
8395
9585
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
8396
9586
|
}
|
|
8397
9587
|
),
|
|
8398
|
-
siblingHintRect && !isItemDragging && /* @__PURE__ */
|
|
8399
|
-
|
|
8400
|
-
|
|
9588
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ jsx23(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
9589
|
+
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && !siblingHintRect && /* @__PURE__ */ jsx23(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
9590
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx23(
|
|
9591
|
+
NavbarContainerChrome,
|
|
9592
|
+
{
|
|
9593
|
+
rect: toolbarRect,
|
|
9594
|
+
onAdd: handleAddTopLevelNavItem
|
|
9595
|
+
}
|
|
9596
|
+
),
|
|
9597
|
+
hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx23(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
9598
|
+
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ jsx23(
|
|
8401
9599
|
ItemInteractionLayer,
|
|
8402
9600
|
{
|
|
8403
9601
|
rect: toolbarRect,
|
|
8404
9602
|
elRef: glowElRef,
|
|
8405
9603
|
state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
|
|
8406
|
-
showHandle: Boolean(reorderHrefKey),
|
|
9604
|
+
showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey),
|
|
8407
9605
|
dragDisabled: reorderDragDisabled,
|
|
8408
9606
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
8409
9607
|
onDragHandleDragStart: handleItemDragStart,
|
|
8410
9608
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
8411
|
-
toolbar:
|
|
9609
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ jsx23(
|
|
8412
9610
|
ItemActionToolbar,
|
|
8413
9611
|
{
|
|
8414
9612
|
onEditLink: openLinkPopoverForSelected,
|
|
8415
|
-
|
|
8416
|
-
|
|
9613
|
+
addItemDisabled: true,
|
|
9614
|
+
editLinkDisabled: false,
|
|
9615
|
+
moreDisabled: true
|
|
8417
9616
|
}
|
|
8418
|
-
)
|
|
9617
|
+
) : void 0
|
|
8419
9618
|
}
|
|
8420
9619
|
),
|
|
8421
|
-
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */
|
|
8422
|
-
/* @__PURE__ */
|
|
9620
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
9621
|
+
/* @__PURE__ */ jsx23(
|
|
8423
9622
|
EditGlowChrome,
|
|
8424
9623
|
{
|
|
8425
9624
|
rect: toolbarRect,
|
|
@@ -8428,7 +9627,7 @@ function OhhwellsBridge() {
|
|
|
8428
9627
|
dragDisabled: reorderDragDisabled
|
|
8429
9628
|
}
|
|
8430
9629
|
),
|
|
8431
|
-
/* @__PURE__ */
|
|
9630
|
+
/* @__PURE__ */ jsx23(
|
|
8432
9631
|
FloatingToolbar,
|
|
8433
9632
|
{
|
|
8434
9633
|
rect: toolbarRect,
|
|
@@ -8441,7 +9640,7 @@ function OhhwellsBridge() {
|
|
|
8441
9640
|
}
|
|
8442
9641
|
)
|
|
8443
9642
|
] }),
|
|
8444
|
-
maxBadge && /* @__PURE__ */
|
|
9643
|
+
maxBadge && /* @__PURE__ */ jsxs13(
|
|
8445
9644
|
"div",
|
|
8446
9645
|
{
|
|
8447
9646
|
"data-ohw-max-badge": "",
|
|
@@ -8467,7 +9666,7 @@ function OhhwellsBridge() {
|
|
|
8467
9666
|
]
|
|
8468
9667
|
}
|
|
8469
9668
|
),
|
|
8470
|
-
toggleState && /* @__PURE__ */
|
|
9669
|
+
toggleState && !linkPopover && /* @__PURE__ */ jsx23(
|
|
8471
9670
|
StateToggle,
|
|
8472
9671
|
{
|
|
8473
9672
|
rect: toggleState.rect,
|
|
@@ -8476,15 +9675,15 @@ function OhhwellsBridge() {
|
|
|
8476
9675
|
onStateChange: handleStateChange
|
|
8477
9676
|
}
|
|
8478
9677
|
),
|
|
8479
|
-
sectionGap && /* @__PURE__ */
|
|
9678
|
+
sectionGap && !linkPopover && /* @__PURE__ */ jsxs13(
|
|
8480
9679
|
"div",
|
|
8481
9680
|
{
|
|
8482
9681
|
"data-ohw-section-insert-line": "",
|
|
8483
9682
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8484
9683
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8485
9684
|
children: [
|
|
8486
|
-
/* @__PURE__ */
|
|
8487
|
-
/* @__PURE__ */
|
|
9685
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9686
|
+
/* @__PURE__ */ jsx23(
|
|
8488
9687
|
Badge,
|
|
8489
9688
|
{
|
|
8490
9689
|
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 +9696,26 @@ function OhhwellsBridge() {
|
|
|
8497
9696
|
children: "Add Section"
|
|
8498
9697
|
}
|
|
8499
9698
|
),
|
|
8500
|
-
/* @__PURE__ */
|
|
9699
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8501
9700
|
]
|
|
8502
9701
|
}
|
|
8503
9702
|
),
|
|
8504
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */
|
|
9703
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx23(
|
|
8505
9704
|
LinkPopover,
|
|
8506
9705
|
{
|
|
8507
9706
|
panelRef: linkPopoverPanelRef,
|
|
8508
9707
|
portalContainer: dialogPortalContainer,
|
|
8509
9708
|
open: true,
|
|
8510
|
-
mode: "edit",
|
|
9709
|
+
mode: linkPopover.mode ?? "edit",
|
|
8511
9710
|
pages: sitePages,
|
|
8512
9711
|
sections: currentSections,
|
|
8513
9712
|
sectionsByPath,
|
|
8514
9713
|
initialTarget: linkPopover.target,
|
|
9714
|
+
existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
|
|
8515
9715
|
onClose: closeLinkPopover,
|
|
8516
9716
|
onSubmit: handleLinkPopoverSubmit
|
|
8517
9717
|
},
|
|
8518
|
-
|
|
9718
|
+
linkPopover.key
|
|
8519
9719
|
) : null
|
|
8520
9720
|
] }),
|
|
8521
9721
|
bridgeRoot
|