@ohhwells/bridge 0.1.36-next.50 → 0.1.36-next.51
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 +1387 -519
- 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 +1349 -481
- package/dist/index.js.map +1 -1
- package/dist/styles.css +122 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -60,15 +60,18 @@ __export(index_exports, {
|
|
|
60
60
|
module.exports = __toCommonJS(index_exports);
|
|
61
61
|
|
|
62
62
|
// src/OhhwellsBridge.tsx
|
|
63
|
-
var
|
|
63
|
+
var import_react8 = __toESM(require("react"), 1);
|
|
64
64
|
var import_client = require("react-dom/client");
|
|
65
|
-
var
|
|
65
|
+
var import_react_dom2 = require("react-dom");
|
|
66
66
|
|
|
67
67
|
// src/linkHrefStore.ts
|
|
68
68
|
var linkHrefStore = /* @__PURE__ */ new Map();
|
|
69
69
|
function setStoredLinkHref(key, href) {
|
|
70
70
|
linkHrefStore.set(key, href);
|
|
71
71
|
}
|
|
72
|
+
function getStoredLinkHref(key) {
|
|
73
|
+
return linkHrefStore.get(key);
|
|
74
|
+
}
|
|
72
75
|
function enforceLinkHrefs() {
|
|
73
76
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
74
77
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
@@ -4456,6 +4459,7 @@ function ItemActionToolbar({
|
|
|
4456
4459
|
onEditLink,
|
|
4457
4460
|
onAddItem,
|
|
4458
4461
|
onMore,
|
|
4462
|
+
editLinkDisabled = false,
|
|
4459
4463
|
addItemDisabled = true,
|
|
4460
4464
|
moreDisabled = true,
|
|
4461
4465
|
tooltipSide = "bottom"
|
|
@@ -4466,8 +4470,10 @@ function ItemActionToolbar({
|
|
|
4466
4470
|
{
|
|
4467
4471
|
label: "Edit link",
|
|
4468
4472
|
side: tooltipSide,
|
|
4473
|
+
disabled: editLinkDisabled,
|
|
4469
4474
|
buttonProps: {
|
|
4470
4475
|
onMouseDown: (e) => {
|
|
4476
|
+
if (editLinkDisabled) return;
|
|
4471
4477
|
e.preventDefault();
|
|
4472
4478
|
e.stopPropagation();
|
|
4473
4479
|
onEditLink?.();
|
|
@@ -4854,8 +4860,8 @@ function MediaOverlay({
|
|
|
4854
4860
|
}
|
|
4855
4861
|
|
|
4856
4862
|
// src/OhhwellsBridge.tsx
|
|
4857
|
-
var
|
|
4858
|
-
var
|
|
4863
|
+
var import_react_dom3 = require("react-dom");
|
|
4864
|
+
var import_navigation2 = require("next/navigation");
|
|
4859
4865
|
|
|
4860
4866
|
// src/lib/session-search.ts
|
|
4861
4867
|
var STORAGE_KEY = "ohw-preserved-search";
|
|
@@ -5131,61 +5137,29 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
5131
5137
|
tick();
|
|
5132
5138
|
}
|
|
5133
5139
|
|
|
5140
|
+
// src/ui/link-modal/LinkPopover.tsx
|
|
5141
|
+
var import_react7 = require("react");
|
|
5142
|
+
|
|
5134
5143
|
// src/ui/dialog.tsx
|
|
5135
5144
|
var React7 = __toESM(require("react"), 1);
|
|
5136
5145
|
var import_radix_ui5 = require("radix-ui");
|
|
5137
|
-
|
|
5138
|
-
// src/ui/icons.tsx
|
|
5146
|
+
var import_lucide_react4 = require("lucide-react");
|
|
5139
5147
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
5140
|
-
function
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
] });
|
|
5145
|
-
}
|
|
5146
|
-
function IconChevronDown({ className, ...props }) {
|
|
5147
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m6 9 6 6 6-6" }) });
|
|
5148
|
-
}
|
|
5149
|
-
function IconFile({ className, ...props }) {
|
|
5150
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5151
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
5152
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
5153
|
-
] });
|
|
5154
|
-
}
|
|
5155
|
-
function IconInfo({ className, ...props }) {
|
|
5156
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5157
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
5158
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M12 16v-4" }),
|
|
5159
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M12 8h.01" })
|
|
5160
|
-
] });
|
|
5161
|
-
}
|
|
5162
|
-
function IconArrowRight({ className, ...props }) {
|
|
5163
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5164
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M5 12h14" }),
|
|
5165
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m12 5 7 7-7 7" })
|
|
5166
|
-
] });
|
|
5167
|
-
}
|
|
5168
|
-
function IconSection({ className, ...props }) {
|
|
5169
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5170
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
5171
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
5172
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
5173
|
-
] });
|
|
5174
|
-
}
|
|
5175
|
-
|
|
5176
|
-
// src/ui/dialog.tsx
|
|
5177
|
-
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
5178
|
-
function Dialog2({ ...props }) {
|
|
5179
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui5.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
5148
|
+
function Dialog2({
|
|
5149
|
+
...props
|
|
5150
|
+
}) {
|
|
5151
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_radix_ui5.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
5180
5152
|
}
|
|
5181
|
-
function DialogPortal({
|
|
5182
|
-
|
|
5153
|
+
function DialogPortal({
|
|
5154
|
+
...props
|
|
5155
|
+
}) {
|
|
5156
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_radix_ui5.Dialog.Portal, { ...props });
|
|
5183
5157
|
}
|
|
5184
5158
|
function DialogOverlay({
|
|
5185
5159
|
className,
|
|
5186
5160
|
...props
|
|
5187
5161
|
}) {
|
|
5188
|
-
return /* @__PURE__ */ (0,
|
|
5162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5189
5163
|
import_radix_ui5.Dialog.Overlay,
|
|
5190
5164
|
{
|
|
5191
5165
|
"data-slot": "dialog-overlay",
|
|
@@ -5195,57 +5169,74 @@ function DialogOverlay({
|
|
|
5195
5169
|
}
|
|
5196
5170
|
);
|
|
5197
5171
|
}
|
|
5198
|
-
var DialogContent = React7.forwardRef(
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
/* @__PURE__ */ (0,
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
children
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
});
|
|
5172
|
+
var DialogContent = React7.forwardRef(
|
|
5173
|
+
({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
5174
|
+
const positionMode = container ? "absolute" : "fixed";
|
|
5175
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
5176
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
5177
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
5178
|
+
import_radix_ui5.Dialog.Content,
|
|
5179
|
+
{
|
|
5180
|
+
ref,
|
|
5181
|
+
"data-slot": "dialog-content",
|
|
5182
|
+
className: cn(
|
|
5183
|
+
positionMode,
|
|
5184
|
+
"left-1/2 top-1/2 z-[2147483647] flex w-full max-w-[483px] -translate-x-1/2 -translate-y-1/2 flex-col overflow-visible",
|
|
5185
|
+
"rounded-xl border border-border bg-background font-sans shadow-lg outline-none",
|
|
5186
|
+
container ? "max-h-[calc(100%-32px)] max-w-[calc(100%-16px)]" : "max-h-[calc(100vh-32px)] max-w-[calc(100vw-16px)]",
|
|
5187
|
+
className
|
|
5188
|
+
),
|
|
5189
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
5190
|
+
...props,
|
|
5191
|
+
children: [
|
|
5192
|
+
children,
|
|
5193
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5194
|
+
import_radix_ui5.Dialog.Close,
|
|
5195
|
+
{
|
|
5196
|
+
type: "button",
|
|
5197
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5198
|
+
"aria-label": "Close",
|
|
5199
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.X, { size: 16, "aria-hidden": true })
|
|
5200
|
+
}
|
|
5201
|
+
) : null
|
|
5202
|
+
]
|
|
5203
|
+
}
|
|
5204
|
+
)
|
|
5205
|
+
] });
|
|
5206
|
+
}
|
|
5207
|
+
);
|
|
5232
5208
|
DialogContent.displayName = import_radix_ui5.Dialog.Content.displayName;
|
|
5233
|
-
function DialogHeader({
|
|
5234
|
-
|
|
5209
|
+
function DialogHeader({
|
|
5210
|
+
className,
|
|
5211
|
+
...props
|
|
5212
|
+
}) {
|
|
5213
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
5235
5214
|
}
|
|
5236
|
-
function DialogFooter({
|
|
5237
|
-
|
|
5215
|
+
function DialogFooter({
|
|
5216
|
+
className,
|
|
5217
|
+
...props
|
|
5218
|
+
}) {
|
|
5219
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5220
|
+
"div",
|
|
5221
|
+
{
|
|
5222
|
+
className: cn("flex items-center justify-end gap-2", className),
|
|
5223
|
+
...props
|
|
5224
|
+
}
|
|
5225
|
+
);
|
|
5238
5226
|
}
|
|
5239
|
-
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
5227
|
+
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5240
5228
|
import_radix_ui5.Dialog.Title,
|
|
5241
5229
|
{
|
|
5242
5230
|
ref,
|
|
5243
|
-
className: cn(
|
|
5231
|
+
className: cn(
|
|
5232
|
+
"text-lg font-semibold leading-none tracking-tight text-card-foreground",
|
|
5233
|
+
className
|
|
5234
|
+
),
|
|
5244
5235
|
...props
|
|
5245
5236
|
}
|
|
5246
5237
|
));
|
|
5247
5238
|
DialogTitle.displayName = import_radix_ui5.Dialog.Title.displayName;
|
|
5248
|
-
var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0,
|
|
5239
|
+
var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5249
5240
|
import_radix_ui5.Dialog.Description,
|
|
5250
5241
|
{
|
|
5251
5242
|
ref,
|
|
@@ -5256,38 +5247,64 @@ var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
5256
5247
|
DialogDescription.displayName = import_radix_ui5.Dialog.Description.displayName;
|
|
5257
5248
|
var DialogClose = import_radix_ui5.Dialog.Close;
|
|
5258
5249
|
|
|
5250
|
+
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5251
|
+
var import_lucide_react8 = require("lucide-react");
|
|
5252
|
+
|
|
5259
5253
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5260
|
-
var
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5254
|
+
var import_lucide_react5 = require("lucide-react");
|
|
5255
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
5256
|
+
function DestinationBreadcrumb({
|
|
5257
|
+
pageTitle,
|
|
5258
|
+
sectionLabel
|
|
5259
|
+
}) {
|
|
5260
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5261
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
|
|
5262
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
5263
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5264
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react5.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5265
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
|
|
5268
5266
|
] }),
|
|
5269
|
-
/* @__PURE__ */ (0,
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5267
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5268
|
+
import_lucide_react5.ArrowRight,
|
|
5269
|
+
{
|
|
5270
|
+
size: 16,
|
|
5271
|
+
className: "shrink-0 text-muted-foreground",
|
|
5272
|
+
"aria-hidden": true
|
|
5273
|
+
}
|
|
5274
|
+
),
|
|
5275
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5276
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5277
|
+
import_lucide_react5.GalleryVertical,
|
|
5278
|
+
{
|
|
5279
|
+
size: 16,
|
|
5280
|
+
className: "shrink-0 text-foreground",
|
|
5281
|
+
"aria-hidden": true
|
|
5282
|
+
}
|
|
5283
|
+
),
|
|
5284
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
5273
5285
|
] })
|
|
5274
5286
|
] })
|
|
5275
5287
|
] });
|
|
5276
5288
|
}
|
|
5277
5289
|
|
|
5278
5290
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5279
|
-
var
|
|
5280
|
-
|
|
5291
|
+
var import_lucide_react6 = require("lucide-react");
|
|
5292
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
5293
|
+
function SectionTreeItem({
|
|
5294
|
+
section,
|
|
5295
|
+
onSelect,
|
|
5296
|
+
selected
|
|
5297
|
+
}) {
|
|
5281
5298
|
const interactive = Boolean(onSelect);
|
|
5282
|
-
return /* @__PURE__ */ (0,
|
|
5283
|
-
/* @__PURE__ */ (0,
|
|
5299
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5300
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5284
5301
|
"div",
|
|
5285
5302
|
{
|
|
5286
5303
|
className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
5287
5304
|
"aria-hidden": true
|
|
5288
5305
|
}
|
|
5289
5306
|
),
|
|
5290
|
-
/* @__PURE__ */ (0,
|
|
5307
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
5291
5308
|
"div",
|
|
5292
5309
|
{
|
|
5293
5310
|
role: interactive ? "button" : void 0,
|
|
@@ -5305,32 +5322,30 @@ function SectionTreeItem({ section, onSelect, selected }) {
|
|
|
5305
5322
|
interactive && selected && "border-primary"
|
|
5306
5323
|
),
|
|
5307
5324
|
children: [
|
|
5308
|
-
/* @__PURE__ */ (0,
|
|
5309
|
-
|
|
5325
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5326
|
+
import_lucide_react6.GalleryVertical,
|
|
5327
|
+
{
|
|
5328
|
+
size: 16,
|
|
5329
|
+
className: "shrink-0 text-foreground",
|
|
5330
|
+
"aria-hidden": true
|
|
5331
|
+
}
|
|
5332
|
+
),
|
|
5333
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
5310
5334
|
]
|
|
5311
5335
|
}
|
|
5312
5336
|
)
|
|
5313
5337
|
] });
|
|
5314
5338
|
}
|
|
5315
|
-
function SectionPickerList({ sections, onSelect }) {
|
|
5316
|
-
if (sections.length === 0) {
|
|
5317
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
|
|
5318
|
-
}
|
|
5319
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
5320
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
|
|
5321
|
-
sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SectionTreeItem, { section, onSelect }, section.id))
|
|
5322
|
-
] });
|
|
5323
|
-
}
|
|
5324
5339
|
|
|
5325
5340
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5326
5341
|
var import_react4 = require("react");
|
|
5327
5342
|
|
|
5328
5343
|
// src/ui/input.tsx
|
|
5329
5344
|
var React8 = __toESM(require("react"), 1);
|
|
5330
|
-
var
|
|
5345
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
5331
5346
|
var Input = React8.forwardRef(
|
|
5332
5347
|
({ className, type, ...props }, ref) => {
|
|
5333
|
-
return /* @__PURE__ */ (0,
|
|
5348
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5334
5349
|
"input",
|
|
5335
5350
|
{
|
|
5336
5351
|
type,
|
|
@@ -5349,9 +5364,9 @@ Input.displayName = "Input";
|
|
|
5349
5364
|
|
|
5350
5365
|
// src/ui/label.tsx
|
|
5351
5366
|
var import_radix_ui6 = require("radix-ui");
|
|
5352
|
-
var
|
|
5367
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
5353
5368
|
function Label({ className, ...props }) {
|
|
5354
|
-
return /* @__PURE__ */ (0,
|
|
5369
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5355
5370
|
import_radix_ui6.Label.Root,
|
|
5356
5371
|
{
|
|
5357
5372
|
"data-slot": "label",
|
|
@@ -5362,9 +5377,12 @@ function Label({ className, ...props }) {
|
|
|
5362
5377
|
}
|
|
5363
5378
|
|
|
5364
5379
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5365
|
-
var
|
|
5366
|
-
|
|
5367
|
-
|
|
5380
|
+
var import_lucide_react7 = require("lucide-react");
|
|
5381
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5382
|
+
function FieldChevron({
|
|
5383
|
+
onClick
|
|
5384
|
+
}) {
|
|
5385
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5368
5386
|
"button",
|
|
5369
5387
|
{
|
|
5370
5388
|
type: "button",
|
|
@@ -5372,7 +5390,7 @@ function FieldChevron({ onClick }) {
|
|
|
5372
5390
|
onClick,
|
|
5373
5391
|
"aria-label": "Open page list",
|
|
5374
5392
|
tabIndex: -1,
|
|
5375
|
-
children: /* @__PURE__ */ (0,
|
|
5393
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.ChevronDown, { size: 16 })
|
|
5376
5394
|
}
|
|
5377
5395
|
);
|
|
5378
5396
|
}
|
|
@@ -5390,7 +5408,29 @@ function UrlOrPageInput({
|
|
|
5390
5408
|
}) {
|
|
5391
5409
|
const inputId = (0, import_react4.useId)();
|
|
5392
5410
|
const inputRef = (0, import_react4.useRef)(null);
|
|
5411
|
+
const rootRef = (0, import_react4.useRef)(null);
|
|
5393
5412
|
const [isFocused, setIsFocused] = (0, import_react4.useState)(false);
|
|
5413
|
+
(0, import_react4.useEffect)(() => {
|
|
5414
|
+
if (!dropdownOpen) return;
|
|
5415
|
+
const isOutside = (e) => {
|
|
5416
|
+
const root = rootRef.current;
|
|
5417
|
+
if (!root) return true;
|
|
5418
|
+
const path = typeof e.composedPath === "function" ? e.composedPath() : [];
|
|
5419
|
+
if (path.includes(root)) return false;
|
|
5420
|
+
const target = e.target;
|
|
5421
|
+
return !(target instanceof Node && root.contains(target));
|
|
5422
|
+
};
|
|
5423
|
+
const closeIfOutside = (e) => {
|
|
5424
|
+
if (!isOutside(e)) return;
|
|
5425
|
+
onDropdownOpenChange(false);
|
|
5426
|
+
};
|
|
5427
|
+
document.addEventListener("pointerdown", closeIfOutside, true);
|
|
5428
|
+
document.addEventListener("mousedown", closeIfOutside, true);
|
|
5429
|
+
return () => {
|
|
5430
|
+
document.removeEventListener("pointerdown", closeIfOutside, true);
|
|
5431
|
+
document.removeEventListener("mousedown", closeIfOutside, true);
|
|
5432
|
+
};
|
|
5433
|
+
}, [dropdownOpen, onDropdownOpenChange]);
|
|
5394
5434
|
const openDropdown = () => {
|
|
5395
5435
|
if (readOnly || filteredPages.length === 0) return;
|
|
5396
5436
|
onDropdownOpenChange(true);
|
|
@@ -5411,12 +5451,19 @@ function UrlOrPageInput({
|
|
|
5411
5451
|
"data-ohw-link-field flex h-10 w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
|
|
5412
5452
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
5413
5453
|
);
|
|
5414
|
-
return /* @__PURE__ */ (0,
|
|
5415
|
-
/* @__PURE__ */ (0,
|
|
5416
|
-
/* @__PURE__ */ (0,
|
|
5417
|
-
/* @__PURE__ */ (0,
|
|
5418
|
-
selectedPage ? /* @__PURE__ */ (0,
|
|
5419
|
-
|
|
5454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5455
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5456
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
|
|
5457
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5458
|
+
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5459
|
+
import_lucide_react7.File,
|
|
5460
|
+
{
|
|
5461
|
+
size: 16,
|
|
5462
|
+
className: "shrink-0 text-foreground",
|
|
5463
|
+
"aria-hidden": true
|
|
5464
|
+
}
|
|
5465
|
+
) }) : null,
|
|
5466
|
+
readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5420
5467
|
Input,
|
|
5421
5468
|
{
|
|
5422
5469
|
ref: inputRef,
|
|
@@ -5427,7 +5474,14 @@ function UrlOrPageInput({
|
|
|
5427
5474
|
setIsFocused(true);
|
|
5428
5475
|
if (!selectedPage) openDropdown();
|
|
5429
5476
|
},
|
|
5430
|
-
onBlur: () =>
|
|
5477
|
+
onBlur: () => {
|
|
5478
|
+
setIsFocused(false);
|
|
5479
|
+
requestAnimationFrame(() => {
|
|
5480
|
+
if (!rootRef.current?.contains(document.activeElement)) {
|
|
5481
|
+
onDropdownOpenChange(false);
|
|
5482
|
+
}
|
|
5483
|
+
});
|
|
5484
|
+
},
|
|
5431
5485
|
placeholder,
|
|
5432
5486
|
className: cn(
|
|
5433
5487
|
"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",
|
|
@@ -5435,7 +5489,7 @@ function UrlOrPageInput({
|
|
|
5435
5489
|
)
|
|
5436
5490
|
}
|
|
5437
5491
|
),
|
|
5438
|
-
selectedPage && !readOnly ? /* @__PURE__ */ (0,
|
|
5492
|
+
selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5439
5493
|
"button",
|
|
5440
5494
|
{
|
|
5441
5495
|
type: "button",
|
|
@@ -5443,26 +5497,26 @@ function UrlOrPageInput({
|
|
|
5443
5497
|
onMouseDown: clearSelection,
|
|
5444
5498
|
"aria-label": "Clear selected page",
|
|
5445
5499
|
tabIndex: -1,
|
|
5446
|
-
children: /* @__PURE__ */ (0,
|
|
5500
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.X, { size: 16, "aria-hidden": true })
|
|
5447
5501
|
}
|
|
5448
5502
|
) : null,
|
|
5449
|
-
!readOnly ? /* @__PURE__ */ (0,
|
|
5503
|
+
!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
|
|
5450
5504
|
] }),
|
|
5451
|
-
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0,
|
|
5505
|
+
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5452
5506
|
"div",
|
|
5453
5507
|
{
|
|
5454
5508
|
"data-ohw-link-page-dropdown": "",
|
|
5455
|
-
className: "absolute left-0 right-0
|
|
5509
|
+
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",
|
|
5456
5510
|
onMouseDown: (e) => e.preventDefault(),
|
|
5457
|
-
children: filteredPages.map((page) => /* @__PURE__ */ (0,
|
|
5511
|
+
children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
5458
5512
|
"button",
|
|
5459
5513
|
{
|
|
5460
5514
|
type: "button",
|
|
5461
5515
|
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",
|
|
5462
5516
|
onClick: () => onPageSelect(page),
|
|
5463
5517
|
children: [
|
|
5464
|
-
/* @__PURE__ */ (0,
|
|
5465
|
-
/* @__PURE__ */ (0,
|
|
5518
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react7.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5519
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "truncate", children: page.title })
|
|
5466
5520
|
]
|
|
5467
5521
|
},
|
|
5468
5522
|
page.path
|
|
@@ -5470,12 +5524,352 @@ function UrlOrPageInput({
|
|
|
5470
5524
|
}
|
|
5471
5525
|
) : null
|
|
5472
5526
|
] }),
|
|
5473
|
-
urlError ? /* @__PURE__ */ (0,
|
|
5527
|
+
urlError ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
|
|
5474
5528
|
] });
|
|
5475
5529
|
}
|
|
5476
5530
|
|
|
5477
|
-
// src/ui/link-modal/
|
|
5531
|
+
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5532
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5533
|
+
function LinkEditorPanel({ state, onClose }) {
|
|
5534
|
+
const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
|
|
5535
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
5536
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5537
|
+
"button",
|
|
5538
|
+
{
|
|
5539
|
+
type: "button",
|
|
5540
|
+
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
|
|
5541
|
+
"aria-label": "Close",
|
|
5542
|
+
onClick: onClose,
|
|
5543
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
|
|
5544
|
+
}
|
|
5545
|
+
) }),
|
|
5546
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5547
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5548
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5549
|
+
DestinationBreadcrumb,
|
|
5550
|
+
{
|
|
5551
|
+
pageTitle: state.selectedPage.title,
|
|
5552
|
+
sectionLabel: state.selectedSection.label
|
|
5553
|
+
}
|
|
5554
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5555
|
+
UrlOrPageInput,
|
|
5556
|
+
{
|
|
5557
|
+
value: state.searchValue,
|
|
5558
|
+
selectedPage: state.selectedPage,
|
|
5559
|
+
dropdownOpen: state.dropdownOpen,
|
|
5560
|
+
onDropdownOpenChange: state.setDropdownOpen,
|
|
5561
|
+
filteredPages: state.filteredPages,
|
|
5562
|
+
onInputChange: state.handleInputChange,
|
|
5563
|
+
onPageSelect: state.handlePageSelect,
|
|
5564
|
+
urlError: state.urlError
|
|
5565
|
+
}
|
|
5566
|
+
),
|
|
5567
|
+
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5568
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5569
|
+
Button,
|
|
5570
|
+
{
|
|
5571
|
+
type: "button",
|
|
5572
|
+
variant: "outline",
|
|
5573
|
+
className: "w-fit cursor-pointer",
|
|
5574
|
+
size: "sm",
|
|
5575
|
+
onClick: state.handleChooseSection,
|
|
5576
|
+
children: "Choose a section"
|
|
5577
|
+
}
|
|
5578
|
+
),
|
|
5579
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5580
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
|
|
5581
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
5582
|
+
] })
|
|
5583
|
+
] }) : null,
|
|
5584
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5585
|
+
] }),
|
|
5586
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5587
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5588
|
+
Button,
|
|
5589
|
+
{
|
|
5590
|
+
type: "button",
|
|
5591
|
+
variant: isCancel ? "outline" : "ghost",
|
|
5592
|
+
className: "leading-6 shadow-none cursor-pointer",
|
|
5593
|
+
style: isCancel ? {
|
|
5594
|
+
backgroundColor: "var(--ohw-background)",
|
|
5595
|
+
borderColor: "var(--ohw-border)",
|
|
5596
|
+
color: "var(--ohw-foreground)"
|
|
5597
|
+
} : void 0,
|
|
5598
|
+
onClick: state.handleSecondary,
|
|
5599
|
+
children: state.secondaryLabel
|
|
5600
|
+
}
|
|
5601
|
+
),
|
|
5602
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5603
|
+
Button,
|
|
5604
|
+
{
|
|
5605
|
+
type: "button",
|
|
5606
|
+
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5607
|
+
style: {
|
|
5608
|
+
backgroundColor: "var(--ohw-primary)",
|
|
5609
|
+
color: "var(--ohw-primary-foreground)"
|
|
5610
|
+
},
|
|
5611
|
+
disabled: !state.isValid,
|
|
5612
|
+
onClick: state.handleSubmit,
|
|
5613
|
+
children: state.submitLabel
|
|
5614
|
+
}
|
|
5615
|
+
)
|
|
5616
|
+
] })
|
|
5617
|
+
] });
|
|
5618
|
+
}
|
|
5619
|
+
|
|
5620
|
+
// src/ui/link-modal/SectionPickerOverlay.tsx
|
|
5478
5621
|
var import_react5 = require("react");
|
|
5622
|
+
var import_react_dom = require("react-dom");
|
|
5623
|
+
var import_lucide_react9 = require("lucide-react");
|
|
5624
|
+
var import_navigation = require("next/navigation");
|
|
5625
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5626
|
+
var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
|
|
5627
|
+
function rectsEqual(a, b) {
|
|
5628
|
+
if (a.size !== b.size) return false;
|
|
5629
|
+
for (const [id, rect] of a) {
|
|
5630
|
+
const other = b.get(id);
|
|
5631
|
+
if (!other || rect.top !== other.top || rect.left !== other.left || rect.width !== other.width || rect.height !== other.height) {
|
|
5632
|
+
return false;
|
|
5633
|
+
}
|
|
5634
|
+
}
|
|
5635
|
+
return true;
|
|
5636
|
+
}
|
|
5637
|
+
function useSectionRects(sectionIdsKey, enabled) {
|
|
5638
|
+
const [rects, setRects] = (0, import_react5.useState)(/* @__PURE__ */ new Map());
|
|
5639
|
+
const sectionIds = (0, import_react5.useMemo)(
|
|
5640
|
+
() => sectionIdsKey ? sectionIdsKey.split("\0") : [],
|
|
5641
|
+
[sectionIdsKey]
|
|
5642
|
+
);
|
|
5643
|
+
(0, import_react5.useEffect)(() => {
|
|
5644
|
+
if (!enabled || sectionIds.length === 0) {
|
|
5645
|
+
setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
|
|
5646
|
+
return;
|
|
5647
|
+
}
|
|
5648
|
+
const update = () => {
|
|
5649
|
+
const next = /* @__PURE__ */ new Map();
|
|
5650
|
+
for (const id of sectionIds) {
|
|
5651
|
+
const el = document.querySelector(
|
|
5652
|
+
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5653
|
+
);
|
|
5654
|
+
if (el) next.set(id, el.getBoundingClientRect());
|
|
5655
|
+
}
|
|
5656
|
+
setRects((prev) => rectsEqual(prev, next) ? prev : next);
|
|
5657
|
+
};
|
|
5658
|
+
update();
|
|
5659
|
+
const opts = { capture: true, passive: true };
|
|
5660
|
+
window.addEventListener("scroll", update, opts);
|
|
5661
|
+
window.addEventListener("resize", update);
|
|
5662
|
+
const vv = window.visualViewport;
|
|
5663
|
+
vv?.addEventListener("resize", update);
|
|
5664
|
+
vv?.addEventListener("scroll", update);
|
|
5665
|
+
const ro = new ResizeObserver(update);
|
|
5666
|
+
for (const id of sectionIds) {
|
|
5667
|
+
const el = document.querySelector(
|
|
5668
|
+
`[data-ohw-section="${CSS.escape(id)}"]`
|
|
5669
|
+
);
|
|
5670
|
+
if (el) ro.observe(el);
|
|
5671
|
+
}
|
|
5672
|
+
return () => {
|
|
5673
|
+
window.removeEventListener("scroll", update, opts);
|
|
5674
|
+
window.removeEventListener("resize", update);
|
|
5675
|
+
vv?.removeEventListener("resize", update);
|
|
5676
|
+
vv?.removeEventListener("scroll", update);
|
|
5677
|
+
ro.disconnect();
|
|
5678
|
+
};
|
|
5679
|
+
}, [sectionIds, enabled]);
|
|
5680
|
+
return rects;
|
|
5681
|
+
}
|
|
5682
|
+
function SectionPickerOverlay({
|
|
5683
|
+
pagePath,
|
|
5684
|
+
sections,
|
|
5685
|
+
onBack,
|
|
5686
|
+
onSelect
|
|
5687
|
+
}) {
|
|
5688
|
+
const router = (0, import_navigation.useRouter)();
|
|
5689
|
+
const pathname = (0, import_navigation.usePathname)();
|
|
5690
|
+
const [selectedId, setSelectedId] = (0, import_react5.useState)(null);
|
|
5691
|
+
const [hoveredId, setHoveredId] = (0, import_react5.useState)(null);
|
|
5692
|
+
const [chromeClip, setChromeClip] = (0, import_react5.useState)(
|
|
5693
|
+
() => ({
|
|
5694
|
+
top: 0,
|
|
5695
|
+
bottom: typeof window !== "undefined" ? window.innerHeight : 0
|
|
5696
|
+
})
|
|
5697
|
+
);
|
|
5698
|
+
const normalizedTarget = normalizePath(pagePath);
|
|
5699
|
+
const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
|
|
5700
|
+
(0, import_react5.useEffect)(() => {
|
|
5701
|
+
if (isOnTargetPage) return;
|
|
5702
|
+
const search = readPreservedSearch();
|
|
5703
|
+
router.push(`${normalizedTarget}${search}`);
|
|
5704
|
+
}, [isOnTargetPage, normalizedTarget, router]);
|
|
5705
|
+
(0, import_react5.useEffect)(() => {
|
|
5706
|
+
document.documentElement.setAttribute("data-ohw-section-picking", "");
|
|
5707
|
+
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
|
|
5708
|
+
el.removeAttribute("data-ohw-hovered");
|
|
5709
|
+
});
|
|
5710
|
+
return () => {
|
|
5711
|
+
document.documentElement.removeAttribute("data-ohw-section-picking");
|
|
5712
|
+
};
|
|
5713
|
+
}, []);
|
|
5714
|
+
(0, import_react5.useEffect)(() => {
|
|
5715
|
+
const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH) => {
|
|
5716
|
+
const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
|
|
5717
|
+
const bottom = Math.min(
|
|
5718
|
+
window.innerHeight,
|
|
5719
|
+
visibleCanvasTop + canvasH - iframeOffsetTop
|
|
5720
|
+
);
|
|
5721
|
+
setChromeClip(
|
|
5722
|
+
(prev) => prev.top === top && prev.bottom === bottom ? prev : { top, bottom: Math.max(top, bottom) }
|
|
5723
|
+
);
|
|
5724
|
+
};
|
|
5725
|
+
const onParentScroll = (e) => {
|
|
5726
|
+
if (e.data?.type !== "ow:parent-scroll") return;
|
|
5727
|
+
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
5728
|
+
applyClip(iframeOffsetTop, headerH, canvasH);
|
|
5729
|
+
};
|
|
5730
|
+
const onResize = () => {
|
|
5731
|
+
setChromeClip((prev) => {
|
|
5732
|
+
const bottom = Math.max(prev.top, window.innerHeight);
|
|
5733
|
+
return prev.bottom === bottom ? prev : { ...prev, bottom };
|
|
5734
|
+
});
|
|
5735
|
+
};
|
|
5736
|
+
window.addEventListener("message", onParentScroll);
|
|
5737
|
+
window.addEventListener("resize", onResize);
|
|
5738
|
+
return () => {
|
|
5739
|
+
window.removeEventListener("message", onParentScroll);
|
|
5740
|
+
window.removeEventListener("resize", onResize);
|
|
5741
|
+
};
|
|
5742
|
+
}, []);
|
|
5743
|
+
const liveSections = (0, import_react5.useMemo)(() => {
|
|
5744
|
+
if (!isOnTargetPage) return sections;
|
|
5745
|
+
const live = collectSectionsFromDom();
|
|
5746
|
+
if (live.length === 0) return sections;
|
|
5747
|
+
const labels = new Map(sections.map((s) => [s.id, s.label]));
|
|
5748
|
+
return live.map((s) => ({ id: s.id, label: labels.get(s.id) ?? s.label }));
|
|
5749
|
+
}, [isOnTargetPage, sections, pathname]);
|
|
5750
|
+
const sectionIdsKey = (0, import_react5.useMemo)(
|
|
5751
|
+
() => liveSections.map((s) => s.id).join("\0"),
|
|
5752
|
+
[liveSections]
|
|
5753
|
+
);
|
|
5754
|
+
const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
|
|
5755
|
+
const handleSelect = (0, import_react5.useCallback)(
|
|
5756
|
+
(section) => {
|
|
5757
|
+
if (selectedId) return;
|
|
5758
|
+
setSelectedId(section.id);
|
|
5759
|
+
onSelect(section);
|
|
5760
|
+
},
|
|
5761
|
+
[selectedId, onSelect]
|
|
5762
|
+
);
|
|
5763
|
+
(0, import_react5.useEffect)(() => {
|
|
5764
|
+
const onKeyDown = (e) => {
|
|
5765
|
+
if (e.key === "Escape") {
|
|
5766
|
+
e.preventDefault();
|
|
5767
|
+
e.stopPropagation();
|
|
5768
|
+
onBack();
|
|
5769
|
+
}
|
|
5770
|
+
};
|
|
5771
|
+
window.addEventListener("keydown", onKeyDown, true);
|
|
5772
|
+
return () => window.removeEventListener("keydown", onKeyDown, true);
|
|
5773
|
+
}, [onBack]);
|
|
5774
|
+
const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
|
|
5775
|
+
if (!portalRoot) return null;
|
|
5776
|
+
return (0, import_react_dom.createPortal)(
|
|
5777
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
5778
|
+
"div",
|
|
5779
|
+
{
|
|
5780
|
+
"data-ohw-section-picker": "",
|
|
5781
|
+
"data-ohw-bridge": "",
|
|
5782
|
+
className: `pointer-events-none fixed inset-0 z-[2147483647] transition-opacity duration-200 ${"opacity-100"}`,
|
|
5783
|
+
"aria-modal": true,
|
|
5784
|
+
role: "dialog",
|
|
5785
|
+
"aria-label": "Choose a section",
|
|
5786
|
+
children: [
|
|
5787
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5788
|
+
"div",
|
|
5789
|
+
{
|
|
5790
|
+
className: "pointer-events-auto fixed left-5 z-[2]",
|
|
5791
|
+
style: { top: chromeClip.top + 20 },
|
|
5792
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
5793
|
+
Button,
|
|
5794
|
+
{
|
|
5795
|
+
type: "button",
|
|
5796
|
+
variant: "outline",
|
|
5797
|
+
size: "sm",
|
|
5798
|
+
className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
|
|
5799
|
+
onClick: onBack,
|
|
5800
|
+
children: [
|
|
5801
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
5802
|
+
"Back"
|
|
5803
|
+
]
|
|
5804
|
+
}
|
|
5805
|
+
)
|
|
5806
|
+
}
|
|
5807
|
+
),
|
|
5808
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5809
|
+
"div",
|
|
5810
|
+
{
|
|
5811
|
+
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",
|
|
5812
|
+
style: {
|
|
5813
|
+
top: chromeClip.bottom - 20,
|
|
5814
|
+
transform: "translate(-50%, -100%)",
|
|
5815
|
+
backgroundColor: "var(--ohw-popover-foreground, #0c0a09)"
|
|
5816
|
+
},
|
|
5817
|
+
"data-ohw-section-picker-hint": "",
|
|
5818
|
+
children: "Click on section to select"
|
|
5819
|
+
}
|
|
5820
|
+
),
|
|
5821
|
+
!isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5822
|
+
"div",
|
|
5823
|
+
{
|
|
5824
|
+
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",
|
|
5825
|
+
style: { top: chromeClip.top + 64 },
|
|
5826
|
+
children: "Loading page preview\u2026"
|
|
5827
|
+
}
|
|
5828
|
+
) : null,
|
|
5829
|
+
isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
|
|
5830
|
+
isOnTargetPage ? liveSections.map((section) => {
|
|
5831
|
+
const rect = rects.get(section.id);
|
|
5832
|
+
if (!rect || rect.width <= 0 || rect.height <= 0) return null;
|
|
5833
|
+
const isSelected = selectedId === section.id;
|
|
5834
|
+
const isLit = isSelected || hoveredId === section.id;
|
|
5835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5836
|
+
"button",
|
|
5837
|
+
{
|
|
5838
|
+
type: "button",
|
|
5839
|
+
className: "pointer-events-auto fixed z-[1] cursor-pointer border-0 bg-transparent p-0 transition-[background-color] duration-150",
|
|
5840
|
+
style: {
|
|
5841
|
+
top: rect.top,
|
|
5842
|
+
left: rect.left,
|
|
5843
|
+
width: rect.width,
|
|
5844
|
+
height: rect.height,
|
|
5845
|
+
backgroundColor: isLit ? "transparent" : DIM_OVERLAY
|
|
5846
|
+
},
|
|
5847
|
+
"aria-label": `Select section ${section.label}`,
|
|
5848
|
+
onMouseEnter: () => setHoveredId(section.id),
|
|
5849
|
+
onMouseLeave: () => setHoveredId((prev) => prev === section.id ? null : prev),
|
|
5850
|
+
onClick: () => handleSelect(section),
|
|
5851
|
+
children: isSelected ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5852
|
+
"span",
|
|
5853
|
+
{
|
|
5854
|
+
className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
|
|
5855
|
+
style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
|
|
5856
|
+
"aria-hidden": true,
|
|
5857
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Check, { className: "size-5" })
|
|
5858
|
+
}
|
|
5859
|
+
) : null
|
|
5860
|
+
},
|
|
5861
|
+
section.id
|
|
5862
|
+
);
|
|
5863
|
+
}) : null
|
|
5864
|
+
]
|
|
5865
|
+
}
|
|
5866
|
+
),
|
|
5867
|
+
portalRoot
|
|
5868
|
+
);
|
|
5869
|
+
}
|
|
5870
|
+
|
|
5871
|
+
// src/ui/link-modal/useLinkModalState.ts
|
|
5872
|
+
var import_react6 = require("react");
|
|
5479
5873
|
function useLinkModalState({
|
|
5480
5874
|
open,
|
|
5481
5875
|
mode,
|
|
@@ -5483,21 +5877,18 @@ function useLinkModalState({
|
|
|
5483
5877
|
sections: _sections,
|
|
5484
5878
|
sectionsByPath,
|
|
5485
5879
|
initialTarget,
|
|
5486
|
-
existingTargets,
|
|
5880
|
+
existingTargets: _existingTargets,
|
|
5487
5881
|
onClose,
|
|
5488
5882
|
onSubmit
|
|
5489
5883
|
}) {
|
|
5490
|
-
const availablePages = (0,
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
);
|
|
5494
|
-
const [
|
|
5495
|
-
const [
|
|
5496
|
-
const [
|
|
5497
|
-
const
|
|
5498
|
-
const [dropdownOpen, setDropdownOpen] = (0, import_react5.useState)(false);
|
|
5499
|
-
const [urlError, setUrlError] = (0, import_react5.useState)("");
|
|
5500
|
-
const reset = (0, import_react5.useCallback)(() => {
|
|
5884
|
+
const availablePages = (0, import_react6.useMemo)(() => pages, [pages]);
|
|
5885
|
+
const [searchValue, setSearchValue] = (0, import_react6.useState)("");
|
|
5886
|
+
const [selectedPage, setSelectedPage] = (0, import_react6.useState)(null);
|
|
5887
|
+
const [selectedSection, setSelectedSection] = (0, import_react6.useState)(null);
|
|
5888
|
+
const [step, setStep] = (0, import_react6.useState)("input");
|
|
5889
|
+
const [dropdownOpen, setDropdownOpen] = (0, import_react6.useState)(false);
|
|
5890
|
+
const [urlError, setUrlError] = (0, import_react6.useState)("");
|
|
5891
|
+
const reset = (0, import_react6.useCallback)(() => {
|
|
5501
5892
|
setSearchValue("");
|
|
5502
5893
|
setSelectedPage(null);
|
|
5503
5894
|
setSelectedSection(null);
|
|
@@ -5505,7 +5896,7 @@ function useLinkModalState({
|
|
|
5505
5896
|
setDropdownOpen(false);
|
|
5506
5897
|
setUrlError("");
|
|
5507
5898
|
}, []);
|
|
5508
|
-
(0,
|
|
5899
|
+
(0, import_react6.useEffect)(() => {
|
|
5509
5900
|
if (!open) return;
|
|
5510
5901
|
if (mode === "edit" && initialTarget) {
|
|
5511
5902
|
const { pageRoute } = parseTarget(initialTarget);
|
|
@@ -5520,12 +5911,12 @@ function useLinkModalState({
|
|
|
5520
5911
|
}
|
|
5521
5912
|
setDropdownOpen(false);
|
|
5522
5913
|
setUrlError("");
|
|
5523
|
-
}, [open, mode, initialTarget,
|
|
5524
|
-
const filteredPages = (0,
|
|
5914
|
+
}, [open, mode, initialTarget, reset]);
|
|
5915
|
+
const filteredPages = (0, import_react6.useMemo)(() => {
|
|
5525
5916
|
if (!searchValue.trim()) return availablePages;
|
|
5526
5917
|
return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
|
|
5527
5918
|
}, [availablePages, searchValue]);
|
|
5528
|
-
const activeSections = (0,
|
|
5919
|
+
const activeSections = (0, import_react6.useMemo)(() => {
|
|
5529
5920
|
if (!selectedPage) return [];
|
|
5530
5921
|
return getSectionsForPath(sectionsByPath, selectedPage.path);
|
|
5531
5922
|
}, [selectedPage, sectionsByPath]);
|
|
@@ -5567,11 +5958,14 @@ function useLinkModalState({
|
|
|
5567
5958
|
const handleBackToSections = () => {
|
|
5568
5959
|
setStep("sectionPicker");
|
|
5569
5960
|
};
|
|
5961
|
+
const handleSectionPickerBack = () => {
|
|
5962
|
+
setStep("input");
|
|
5963
|
+
};
|
|
5570
5964
|
const handleClose = () => {
|
|
5571
5965
|
reset();
|
|
5572
5966
|
onClose();
|
|
5573
5967
|
};
|
|
5574
|
-
const isValid = (0,
|
|
5968
|
+
const isValid = (0, import_react6.useMemo)(() => {
|
|
5575
5969
|
if (urlError) return false;
|
|
5576
5970
|
if (showBreadcrumb) return true;
|
|
5577
5971
|
if (selectedPage) return true;
|
|
@@ -5604,7 +5998,7 @@ function useLinkModalState({
|
|
|
5604
5998
|
onSubmit(normalizeUrl(searchValue));
|
|
5605
5999
|
handleClose();
|
|
5606
6000
|
};
|
|
5607
|
-
const submitLabel = mode === "edit" ? "Save" : "Create";
|
|
6001
|
+
const submitLabel = showBreadcrumb ? "Save" : mode === "edit" ? "Save" : "Create";
|
|
5608
6002
|
const title = mode === "edit" ? "Edit navigation item" : "Create navigation item";
|
|
5609
6003
|
const secondaryLabel = showBreadcrumb ? "Back to sections" : "Cancel";
|
|
5610
6004
|
const handleSecondary = showBreadcrumb ? handleBackToSections : handleClose;
|
|
@@ -5631,23 +6025,29 @@ function useLinkModalState({
|
|
|
5631
6025
|
handleChooseSection,
|
|
5632
6026
|
handleSectionSelect,
|
|
5633
6027
|
handleBackToSections,
|
|
6028
|
+
handleSectionPickerBack,
|
|
5634
6029
|
handleClose,
|
|
5635
6030
|
handleSecondary,
|
|
5636
6031
|
handleSubmit
|
|
5637
6032
|
};
|
|
5638
6033
|
}
|
|
5639
6034
|
|
|
5640
|
-
// src/ui/link-modal/
|
|
5641
|
-
var
|
|
5642
|
-
function
|
|
6035
|
+
// src/ui/link-modal/LinkPopover.tsx
|
|
6036
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
6037
|
+
function postToParent(data) {
|
|
6038
|
+
window.parent?.postMessage(data, "*");
|
|
6039
|
+
}
|
|
6040
|
+
function LinkPopover({
|
|
5643
6041
|
open = true,
|
|
6042
|
+
panelRef,
|
|
6043
|
+
portalContainer,
|
|
6044
|
+
onClose,
|
|
5644
6045
|
mode = "create",
|
|
5645
6046
|
pages,
|
|
5646
6047
|
sections = [],
|
|
5647
6048
|
sectionsByPath,
|
|
5648
6049
|
initialTarget,
|
|
5649
6050
|
existingTargets = [],
|
|
5650
|
-
onClose,
|
|
5651
6051
|
onSubmit
|
|
5652
6052
|
}) {
|
|
5653
6053
|
const state = useLinkModalState({
|
|
@@ -5661,115 +6061,100 @@ function LinkEditorPanel({
|
|
|
5661
6061
|
onClose,
|
|
5662
6062
|
onSubmit
|
|
5663
6063
|
});
|
|
5664
|
-
const
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
6064
|
+
const sectionPickerActive = state.showSectionPicker && Boolean(state.selectedPage);
|
|
6065
|
+
(0, import_react7.useEffect)(() => {
|
|
6066
|
+
if (!open) return;
|
|
6067
|
+
if (sectionPickerActive) {
|
|
6068
|
+
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6069
|
+
postToParent({ type: "ow:section-picker", active: true });
|
|
6070
|
+
document.documentElement.style.overflow = "";
|
|
6071
|
+
document.body.style.overflow = "";
|
|
6072
|
+
return () => {
|
|
6073
|
+
postToParent({ type: "ow:section-picker", active: false });
|
|
6074
|
+
};
|
|
6075
|
+
}
|
|
6076
|
+
postToParent({ type: "ow:section-picker", active: false });
|
|
6077
|
+
postToParent({ type: "ow:link-modal-lock", locked: true });
|
|
6078
|
+
const html = document.documentElement;
|
|
6079
|
+
const body = document.body;
|
|
6080
|
+
const prevHtmlOverflow = html.style.overflow;
|
|
6081
|
+
const prevBodyOverflow = body.style.overflow;
|
|
6082
|
+
const prevHtmlOverscroll = html.style.overscrollBehavior;
|
|
6083
|
+
const prevBodyOverscroll = body.style.overscrollBehavior;
|
|
6084
|
+
html.style.overflow = "hidden";
|
|
6085
|
+
body.style.overflow = "hidden";
|
|
6086
|
+
html.style.overscrollBehavior = "none";
|
|
6087
|
+
body.style.overscrollBehavior = "none";
|
|
6088
|
+
const canScrollElement = (el, deltaY) => {
|
|
6089
|
+
const { overflowY } = getComputedStyle(el);
|
|
6090
|
+
if (overflowY !== "auto" && overflowY !== "scroll") return false;
|
|
6091
|
+
if (el.scrollHeight <= el.clientHeight + 1) return false;
|
|
6092
|
+
if (deltaY < 0) return el.scrollTop > 0;
|
|
6093
|
+
if (deltaY > 0) return el.scrollTop + el.clientHeight < el.scrollHeight - 1;
|
|
6094
|
+
return true;
|
|
6095
|
+
};
|
|
6096
|
+
const allowsInternalScroll = (e) => {
|
|
6097
|
+
const target = e.target;
|
|
6098
|
+
if (!(target instanceof Element)) return false;
|
|
6099
|
+
const scrollRoot = target.closest(
|
|
6100
|
+
"[data-ohw-link-page-dropdown], [data-ohw-allow-scroll]"
|
|
6101
|
+
);
|
|
6102
|
+
if (!scrollRoot) return false;
|
|
6103
|
+
const deltaY = e instanceof WheelEvent ? e.deltaY : 0;
|
|
6104
|
+
return canScrollElement(scrollRoot, deltaY);
|
|
6105
|
+
};
|
|
6106
|
+
const preventBackgroundScroll = (e) => {
|
|
6107
|
+
if (allowsInternalScroll(e)) return;
|
|
6108
|
+
e.preventDefault();
|
|
6109
|
+
};
|
|
6110
|
+
const scrollOpts = { passive: false, capture: true };
|
|
6111
|
+
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6112
|
+
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6113
|
+
return () => {
|
|
6114
|
+
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6115
|
+
html.style.overflow = prevHtmlOverflow;
|
|
6116
|
+
body.style.overflow = prevBodyOverflow;
|
|
6117
|
+
html.style.overscrollBehavior = prevHtmlOverscroll;
|
|
6118
|
+
body.style.overscrollBehavior = prevBodyOverscroll;
|
|
6119
|
+
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6120
|
+
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6121
|
+
};
|
|
6122
|
+
}, [open, sectionPickerActive]);
|
|
6123
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
6124
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6125
|
+
Dialog2,
|
|
5668
6126
|
{
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
6127
|
+
open: open && !sectionPickerActive,
|
|
6128
|
+
onOpenChange: (next) => {
|
|
6129
|
+
if (!next) onClose?.();
|
|
6130
|
+
},
|
|
6131
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6132
|
+
DialogContent,
|
|
6133
|
+
{
|
|
6134
|
+
ref: panelRef,
|
|
6135
|
+
container: portalContainer,
|
|
6136
|
+
"data-ohw-link-popover-root": "",
|
|
6137
|
+
"data-ohw-link-modal-root": "",
|
|
6138
|
+
"data-ohw-bridge": "",
|
|
6139
|
+
showCloseButton: false,
|
|
6140
|
+
className: "gap-0 p-0 w-full md:w-md pointer-events-auto z-[2147483646] overflow-visible",
|
|
6141
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LinkEditorPanel, { state, onClose })
|
|
6142
|
+
}
|
|
6143
|
+
)
|
|
5673
6144
|
}
|
|
5674
|
-
)
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
UrlOrPageInput,
|
|
5685
|
-
{
|
|
5686
|
-
value: state.searchValue,
|
|
5687
|
-
selectedPage: state.selectedPage,
|
|
5688
|
-
dropdownOpen: state.dropdownOpen,
|
|
5689
|
-
onDropdownOpenChange: state.setDropdownOpen,
|
|
5690
|
-
filteredPages: state.filteredPages,
|
|
5691
|
-
onInputChange: state.handleInputChange,
|
|
5692
|
-
onPageSelect: state.handlePageSelect,
|
|
5693
|
-
urlError: state.urlError
|
|
5694
|
-
}
|
|
5695
|
-
),
|
|
5696
|
-
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5697
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
|
|
5698
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5699
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconInfo, { className: "shrink-0", "aria-hidden": true }),
|
|
5700
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
5701
|
-
] })
|
|
5702
|
-
] }) : null,
|
|
5703
|
-
state.showSectionPicker ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5704
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5705
|
-
] }),
|
|
5706
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5707
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5708
|
-
Button,
|
|
5709
|
-
{
|
|
5710
|
-
type: "button",
|
|
5711
|
-
variant: isCancel ? "outline" : "ghost",
|
|
5712
|
-
className: "leading-6 shadow-none cursor-pointer",
|
|
5713
|
-
style: isCancel ? {
|
|
5714
|
-
backgroundColor: "var(--ohw-background)",
|
|
5715
|
-
borderColor: "var(--ohw-border)",
|
|
5716
|
-
color: "var(--ohw-foreground)"
|
|
5717
|
-
} : void 0,
|
|
5718
|
-
onClick: state.handleSecondary,
|
|
5719
|
-
children: state.secondaryLabel
|
|
5720
|
-
}
|
|
5721
|
-
),
|
|
5722
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5723
|
-
Button,
|
|
5724
|
-
{
|
|
5725
|
-
type: "button",
|
|
5726
|
-
className: "border-0 leading-6 shadow-none hover:opacity-90 disabled:opacity-50 cursor-pointer",
|
|
5727
|
-
style: {
|
|
5728
|
-
backgroundColor: "var(--ohw-primary)",
|
|
5729
|
-
color: "var(--ohw-primary-foreground)"
|
|
5730
|
-
},
|
|
5731
|
-
disabled: !state.isValid,
|
|
5732
|
-
onClick: state.handleSubmit,
|
|
5733
|
-
children: state.submitLabel
|
|
5734
|
-
}
|
|
5735
|
-
)
|
|
5736
|
-
] })
|
|
6145
|
+
),
|
|
6146
|
+
sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
6147
|
+
SectionPickerOverlay,
|
|
6148
|
+
{
|
|
6149
|
+
pagePath: state.selectedPage.path,
|
|
6150
|
+
sections: state.activeSections,
|
|
6151
|
+
onBack: state.handleSectionPickerBack,
|
|
6152
|
+
onSelect: state.handleSectionSelect
|
|
6153
|
+
}
|
|
6154
|
+
) : null
|
|
5737
6155
|
] });
|
|
5738
6156
|
}
|
|
5739
6157
|
|
|
5740
|
-
// src/ui/link-modal/LinkPopover.tsx
|
|
5741
|
-
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5742
|
-
function LinkPopover({
|
|
5743
|
-
open = true,
|
|
5744
|
-
panelRef,
|
|
5745
|
-
portalContainer,
|
|
5746
|
-
onClose,
|
|
5747
|
-
...editorProps
|
|
5748
|
-
}) {
|
|
5749
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5750
|
-
Dialog2,
|
|
5751
|
-
{
|
|
5752
|
-
open,
|
|
5753
|
-
onOpenChange: (next) => {
|
|
5754
|
-
if (!next) onClose?.();
|
|
5755
|
-
},
|
|
5756
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5757
|
-
DialogContent,
|
|
5758
|
-
{
|
|
5759
|
-
ref: panelRef,
|
|
5760
|
-
container: portalContainer,
|
|
5761
|
-
"data-ohw-link-popover-root": "",
|
|
5762
|
-
"data-ohw-link-modal-root": "",
|
|
5763
|
-
"data-ohw-bridge": "",
|
|
5764
|
-
showCloseButton: false,
|
|
5765
|
-
className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
|
|
5766
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LinkEditorPanel, { ...editorProps, open, onClose })
|
|
5767
|
-
}
|
|
5768
|
-
)
|
|
5769
|
-
}
|
|
5770
|
-
);
|
|
5771
|
-
}
|
|
5772
|
-
|
|
5773
6158
|
// src/ui/link-modal/devFixtures.ts
|
|
5774
6159
|
var DEV_SITE_PAGES = [
|
|
5775
6160
|
{ path: "/", title: "Home" },
|
|
@@ -5789,16 +6174,21 @@ var DEV_SECTIONS_BY_PATH = {
|
|
|
5789
6174
|
{ id: "founder-teaser", label: "Founder" },
|
|
5790
6175
|
{ id: "plan-form", label: "Plan Form" },
|
|
5791
6176
|
{ id: "testimonials", label: "Testimonials" },
|
|
5792
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
6177
|
+
{ id: "wordmark", label: "Wordmark" },
|
|
6178
|
+
{ id: "footer", label: "Footer" }
|
|
5793
6179
|
],
|
|
5794
6180
|
"/about": [
|
|
5795
6181
|
{ id: "manifesto", label: "Manifesto" },
|
|
5796
6182
|
{ id: "story-letter", label: "Our Story" },
|
|
5797
6183
|
{ id: "lagree-explainer", label: "Lagree Explainer" },
|
|
5798
6184
|
{ id: "waitlist-cta", label: "Waitlist" },
|
|
5799
|
-
{ id: "personal-training", label: "Personal training" }
|
|
6185
|
+
{ id: "personal-training", label: "Personal training" },
|
|
6186
|
+
{ id: "footer", label: "Footer" }
|
|
6187
|
+
],
|
|
6188
|
+
"/classes": [
|
|
6189
|
+
{ id: "class-library", label: "Class Library" },
|
|
6190
|
+
{ id: "footer", label: "Footer" }
|
|
5800
6191
|
],
|
|
5801
|
-
"/classes": [{ id: "class-library", label: "Class Library" }],
|
|
5802
6192
|
"/pricing": [
|
|
5803
6193
|
{ id: "page-header", label: "Page Header" },
|
|
5804
6194
|
{ id: "free-class-cta", label: "Free Class" },
|
|
@@ -5806,19 +6196,25 @@ var DEV_SECTIONS_BY_PATH = {
|
|
|
5806
6196
|
{ id: "monthly-memberships", label: "Memberships" },
|
|
5807
6197
|
{ id: "specialty-programs", label: "Specialty Programs" },
|
|
5808
6198
|
{ id: "package-matcher", label: "Packages" },
|
|
5809
|
-
{ id: "wordmark", label: "Wordmark" }
|
|
6199
|
+
{ id: "wordmark", label: "Wordmark" },
|
|
6200
|
+
{ id: "footer", label: "Footer" }
|
|
5810
6201
|
],
|
|
5811
6202
|
"/studio": [
|
|
5812
6203
|
{ id: "studio-intro", label: "Studio Intro" },
|
|
5813
6204
|
{ id: "studio-features", label: "Studio Features" },
|
|
5814
6205
|
{ id: "studio-gallery", label: "Studio Gallery" },
|
|
5815
|
-
{ id: "studio-visit", label: "Visit Studio" }
|
|
6206
|
+
{ id: "studio-visit", label: "Visit Studio" },
|
|
6207
|
+
{ id: "footer", label: "Footer" }
|
|
6208
|
+
],
|
|
6209
|
+
"/instructors": [
|
|
6210
|
+
{ id: "instructor-grid", label: "Instructors" },
|
|
6211
|
+
{ id: "footer", label: "Footer" }
|
|
5816
6212
|
],
|
|
5817
|
-
"/instructors": [{ id: "instructor-grid", label: "Instructors" }],
|
|
5818
6213
|
"/contact": [
|
|
5819
6214
|
{ id: "hello-hero", label: "Hello" },
|
|
5820
6215
|
{ id: "contact-form", label: "Contact Form" },
|
|
5821
|
-
{ id: "faq", label: "FAQ" }
|
|
6216
|
+
{ id: "faq", label: "FAQ" },
|
|
6217
|
+
{ id: "footer", label: "Footer" }
|
|
5822
6218
|
]
|
|
5823
6219
|
};
|
|
5824
6220
|
function shouldUseDevFixtures() {
|
|
@@ -5828,8 +6224,277 @@ function shouldUseDevFixtures() {
|
|
|
5828
6224
|
return new URLSearchParams(q).get("ohw-fixtures") === "1";
|
|
5829
6225
|
}
|
|
5830
6226
|
|
|
5831
|
-
// src/
|
|
6227
|
+
// src/lib/nav-items.ts
|
|
6228
|
+
var NAV_COUNT_KEY = "__ohw_nav_count";
|
|
6229
|
+
var NAV_ORDER_KEY = "__ohw_nav_order";
|
|
6230
|
+
function getLinkHref(el) {
|
|
6231
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
6232
|
+
if (key) {
|
|
6233
|
+
const stored = getStoredLinkHref(key);
|
|
6234
|
+
if (stored !== void 0) return stored;
|
|
6235
|
+
}
|
|
6236
|
+
return el.getAttribute("href") ?? "";
|
|
6237
|
+
}
|
|
6238
|
+
function isNavbarButton(el) {
|
|
6239
|
+
return el.hasAttribute("data-ohw-role") && el.getAttribute("data-ohw-role") === "navbar-button";
|
|
6240
|
+
}
|
|
6241
|
+
function isNavbarLinkItem(el) {
|
|
6242
|
+
if (!el.matches("[data-ohw-href-key]")) return false;
|
|
6243
|
+
if (isNavbarButton(el)) return false;
|
|
6244
|
+
if (!el.querySelector('[data-ohw-editable="text"]')) return false;
|
|
6245
|
+
return Boolean(el.closest("nav, [data-ohw-nav-container], [data-ohw-nav-drawer]"));
|
|
6246
|
+
}
|
|
6247
|
+
function getNavbarDesktopContainer() {
|
|
6248
|
+
return document.querySelector("[data-ohw-nav-container]");
|
|
6249
|
+
}
|
|
6250
|
+
function getNavbarDrawerContainer() {
|
|
6251
|
+
return document.querySelector("[data-ohw-nav-drawer]");
|
|
6252
|
+
}
|
|
6253
|
+
function listNavbarItems() {
|
|
6254
|
+
const desktop = getNavbarDesktopContainer();
|
|
6255
|
+
if (desktop) {
|
|
6256
|
+
return Array.from(desktop.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6257
|
+
}
|
|
6258
|
+
const drawer = getNavbarDrawerContainer();
|
|
6259
|
+
if (drawer) {
|
|
6260
|
+
return Array.from(drawer.querySelectorAll("[data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6261
|
+
}
|
|
6262
|
+
return Array.from(document.querySelectorAll("nav [data-ohw-href-key]")).filter(isNavbarLinkItem);
|
|
6263
|
+
}
|
|
6264
|
+
function parseNavIndexFromKey(key) {
|
|
6265
|
+
if (!key) return null;
|
|
6266
|
+
const match = key.match(/^nav-(\d+)-href$/);
|
|
6267
|
+
if (!match) return null;
|
|
6268
|
+
return parseInt(match[1], 10);
|
|
6269
|
+
}
|
|
6270
|
+
function getNavbarIndicesInDom() {
|
|
6271
|
+
const indices = /* @__PURE__ */ new Set();
|
|
6272
|
+
for (const item of listNavbarItems()) {
|
|
6273
|
+
const idx = parseNavIndexFromKey(item.getAttribute("data-ohw-href-key"));
|
|
6274
|
+
if (idx !== null) indices.add(idx);
|
|
6275
|
+
}
|
|
6276
|
+
return [...indices].sort((a, b) => a - b);
|
|
6277
|
+
}
|
|
6278
|
+
function getNextNavbarIndex() {
|
|
6279
|
+
const indices = getNavbarIndicesInDom();
|
|
6280
|
+
if (indices.length === 0) return 0;
|
|
6281
|
+
return Math.max(...indices) + 1;
|
|
6282
|
+
}
|
|
6283
|
+
function getNavbarExistingTargets() {
|
|
6284
|
+
return listNavbarItems().map((el) => getLinkHref(el)).filter(Boolean);
|
|
6285
|
+
}
|
|
6286
|
+
function getNavOrderFromDom() {
|
|
6287
|
+
return listNavbarItems().map((el) => el.getAttribute("data-ohw-href-key")).filter((key) => Boolean(key));
|
|
6288
|
+
}
|
|
6289
|
+
function parseNavOrder(content) {
|
|
6290
|
+
const raw = content[NAV_ORDER_KEY];
|
|
6291
|
+
if (!raw) return null;
|
|
6292
|
+
try {
|
|
6293
|
+
const parsed = JSON.parse(raw);
|
|
6294
|
+
if (!Array.isArray(parsed)) return null;
|
|
6295
|
+
return parsed.filter((key) => typeof key === "string" && key.length > 0);
|
|
6296
|
+
} catch {
|
|
6297
|
+
return null;
|
|
6298
|
+
}
|
|
6299
|
+
}
|
|
6300
|
+
function findCounterpartByHrefKey(hrefKey, root) {
|
|
6301
|
+
return root.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
|
|
6302
|
+
}
|
|
6303
|
+
function cloneNavLinkShell(template) {
|
|
6304
|
+
const anchor = document.createElement("a");
|
|
6305
|
+
if (template) {
|
|
6306
|
+
anchor.style.cssText = template.style.cssText;
|
|
6307
|
+
if (template.className) anchor.className = template.className;
|
|
6308
|
+
}
|
|
6309
|
+
anchor.style.cursor = "pointer";
|
|
6310
|
+
anchor.style.textDecoration = "none";
|
|
6311
|
+
return anchor;
|
|
6312
|
+
}
|
|
6313
|
+
function buildNavLink(index, href, label, template) {
|
|
6314
|
+
const anchor = cloneNavLinkShell(template);
|
|
6315
|
+
anchor.href = href;
|
|
6316
|
+
anchor.setAttribute("data-ohw-href-key", `nav-${index}-href`);
|
|
6317
|
+
const span = document.createElement("span");
|
|
6318
|
+
span.setAttribute("data-ohw-editable", "text");
|
|
6319
|
+
span.setAttribute("data-ohw-key", `nav-${index}-label`);
|
|
6320
|
+
span.textContent = label;
|
|
6321
|
+
anchor.appendChild(span);
|
|
6322
|
+
return anchor;
|
|
6323
|
+
}
|
|
6324
|
+
function insertNavLinkInContainer(container, anchor, afterHrefKey) {
|
|
6325
|
+
if (!afterHrefKey) {
|
|
6326
|
+
container.appendChild(anchor);
|
|
6327
|
+
return;
|
|
6328
|
+
}
|
|
6329
|
+
const afterEl = findCounterpartByHrefKey(afterHrefKey, container);
|
|
6330
|
+
if (afterEl?.parentElement === container) {
|
|
6331
|
+
afterEl.insertAdjacentElement("afterend", anchor);
|
|
6332
|
+
return;
|
|
6333
|
+
}
|
|
6334
|
+
container.appendChild(anchor);
|
|
6335
|
+
}
|
|
6336
|
+
function insertNavbarItemDom(index, href, label, afterAnchor) {
|
|
6337
|
+
const afterHrefKey = afterAnchor?.getAttribute("data-ohw-href-key") ?? null;
|
|
6338
|
+
const desktopItems = getNavbarDesktopContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6339
|
+
const drawerItems = getNavbarDrawerContainer()?.querySelectorAll("[data-ohw-href-key]") ?? [];
|
|
6340
|
+
const desktopTemplate = Array.from(desktopItems).find(isNavbarLinkItem) ?? null;
|
|
6341
|
+
const drawerTemplate = Array.from(drawerItems).find(isNavbarLinkItem) ?? null;
|
|
6342
|
+
let primary = null;
|
|
6343
|
+
const desktopContainer = getNavbarDesktopContainer();
|
|
6344
|
+
if (desktopContainer) {
|
|
6345
|
+
const desktopAnchor = buildNavLink(index, href, label, desktopTemplate);
|
|
6346
|
+
insertNavLinkInContainer(desktopContainer, desktopAnchor, afterHrefKey);
|
|
6347
|
+
primary = desktopAnchor;
|
|
6348
|
+
}
|
|
6349
|
+
const drawerContainer = getNavbarDrawerContainer();
|
|
6350
|
+
if (drawerContainer) {
|
|
6351
|
+
const drawerAnchor = buildNavLink(index, href, label, drawerTemplate);
|
|
6352
|
+
insertNavLinkInContainer(drawerContainer, drawerAnchor, afterHrefKey);
|
|
6353
|
+
if (!primary) primary = drawerAnchor;
|
|
6354
|
+
}
|
|
6355
|
+
if (!primary) {
|
|
6356
|
+
const fallback = buildNavLink(index, href, label, listNavbarItems()[0] ?? null);
|
|
6357
|
+
const nav = document.querySelector("nav");
|
|
6358
|
+
nav?.appendChild(fallback);
|
|
6359
|
+
primary = fallback;
|
|
6360
|
+
}
|
|
6361
|
+
return primary;
|
|
6362
|
+
}
|
|
6363
|
+
function applyNavOrderToContainer(container, order) {
|
|
6364
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6365
|
+
for (const hrefKey of order) {
|
|
6366
|
+
if (seen.has(hrefKey)) continue;
|
|
6367
|
+
seen.add(hrefKey);
|
|
6368
|
+
const el = findCounterpartByHrefKey(hrefKey, container);
|
|
6369
|
+
if (el) container.appendChild(el);
|
|
6370
|
+
}
|
|
6371
|
+
for (const el of container.querySelectorAll("[data-ohw-href-key]")) {
|
|
6372
|
+
if (!isNavbarLinkItem(el)) continue;
|
|
6373
|
+
const key = el.getAttribute("data-ohw-href-key");
|
|
6374
|
+
if (!key || seen.has(key)) continue;
|
|
6375
|
+
container.appendChild(el);
|
|
6376
|
+
}
|
|
6377
|
+
}
|
|
6378
|
+
function applyNavOrder(order) {
|
|
6379
|
+
const desktop = getNavbarDesktopContainer();
|
|
6380
|
+
if (desktop) applyNavOrderToContainer(desktop, order);
|
|
6381
|
+
const drawer = getNavbarDrawerContainer();
|
|
6382
|
+
if (drawer) applyNavOrderToContainer(drawer, order);
|
|
6383
|
+
}
|
|
6384
|
+
function collectNavbarIndicesFromContent(content) {
|
|
6385
|
+
const indices = /* @__PURE__ */ new Set();
|
|
6386
|
+
for (const key of Object.keys(content)) {
|
|
6387
|
+
const idx = parseNavIndexFromKey(key);
|
|
6388
|
+
if (idx !== null) indices.add(idx);
|
|
6389
|
+
}
|
|
6390
|
+
const countRaw = content[NAV_COUNT_KEY];
|
|
6391
|
+
if (countRaw) {
|
|
6392
|
+
const count = parseInt(countRaw, 10);
|
|
6393
|
+
if (Number.isFinite(count) && count > 0) {
|
|
6394
|
+
for (let i = 0; i < count; i++) indices.add(i);
|
|
6395
|
+
}
|
|
6396
|
+
}
|
|
6397
|
+
return [...indices].sort((a, b) => a - b);
|
|
6398
|
+
}
|
|
6399
|
+
function navbarIndexExistsInDom(index) {
|
|
6400
|
+
return document.querySelector(`[data-ohw-href-key="nav-${index}-href"]`) !== null;
|
|
6401
|
+
}
|
|
6402
|
+
function reconcileNavbarItemsFromContent(content) {
|
|
6403
|
+
const indices = collectNavbarIndicesFromContent(content);
|
|
6404
|
+
for (const index of indices) {
|
|
6405
|
+
if (navbarIndexExistsInDom(index)) continue;
|
|
6406
|
+
const href = content[`nav-${index}-href`];
|
|
6407
|
+
const label = content[`nav-${index}-label`];
|
|
6408
|
+
if (!href && !label) continue;
|
|
6409
|
+
insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
|
|
6410
|
+
}
|
|
6411
|
+
const order = parseNavOrder(content);
|
|
6412
|
+
if (order?.length) applyNavOrder(order);
|
|
6413
|
+
}
|
|
6414
|
+
function buildNavOrderAfterInsert(afterAnchor, newHrefKey) {
|
|
6415
|
+
const order = getNavOrderFromDom();
|
|
6416
|
+
if (!afterAnchor) {
|
|
6417
|
+
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6418
|
+
return order;
|
|
6419
|
+
}
|
|
6420
|
+
const afterKey = afterAnchor.getAttribute("data-ohw-href-key");
|
|
6421
|
+
if (!afterKey) {
|
|
6422
|
+
if (!order.includes(newHrefKey)) order.push(newHrefKey);
|
|
6423
|
+
return order;
|
|
6424
|
+
}
|
|
6425
|
+
const withoutNew = order.filter((key) => key !== newHrefKey);
|
|
6426
|
+
const pos = withoutNew.indexOf(afterKey);
|
|
6427
|
+
if (pos >= 0) {
|
|
6428
|
+
withoutNew.splice(pos + 1, 0, newHrefKey);
|
|
6429
|
+
return withoutNew;
|
|
6430
|
+
}
|
|
6431
|
+
withoutNew.push(newHrefKey);
|
|
6432
|
+
return withoutNew;
|
|
6433
|
+
}
|
|
6434
|
+
function insertNavbarItem(href, label, afterAnchor = null) {
|
|
6435
|
+
const index = getNextNavbarIndex();
|
|
6436
|
+
const anchor = insertNavbarItemDom(index, href, label, afterAnchor);
|
|
6437
|
+
if (!anchor) throw new Error("Failed to insert navbar item");
|
|
6438
|
+
const hrefKey = `nav-${index}-href`;
|
|
6439
|
+
const order = buildNavOrderAfterInsert(afterAnchor, hrefKey);
|
|
6440
|
+
applyNavOrder(order);
|
|
6441
|
+
return {
|
|
6442
|
+
anchor,
|
|
6443
|
+
index,
|
|
6444
|
+
hrefKey,
|
|
6445
|
+
labelKey: `nav-${index}-label`,
|
|
6446
|
+
href,
|
|
6447
|
+
label,
|
|
6448
|
+
order
|
|
6449
|
+
};
|
|
6450
|
+
}
|
|
6451
|
+
|
|
6452
|
+
// src/ui/navbar-container-chrome.tsx
|
|
6453
|
+
var import_lucide_react10 = require("lucide-react");
|
|
5832
6454
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
6455
|
+
function NavbarContainerChrome({
|
|
6456
|
+
rect,
|
|
6457
|
+
onAdd
|
|
6458
|
+
}) {
|
|
6459
|
+
const chromeGap = 6;
|
|
6460
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6461
|
+
"div",
|
|
6462
|
+
{
|
|
6463
|
+
"data-ohw-navbar-container-chrome": "",
|
|
6464
|
+
"data-ohw-bridge": "",
|
|
6465
|
+
className: "pointer-events-none fixed z-[2147483647]",
|
|
6466
|
+
style: {
|
|
6467
|
+
top: rect.top - chromeGap,
|
|
6468
|
+
left: rect.left - chromeGap,
|
|
6469
|
+
width: rect.width + chromeGap * 2,
|
|
6470
|
+
height: rect.height + chromeGap * 2
|
|
6471
|
+
},
|
|
6472
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6473
|
+
"button",
|
|
6474
|
+
{
|
|
6475
|
+
type: "button",
|
|
6476
|
+
"data-ohw-navbar-add-button": "",
|
|
6477
|
+
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",
|
|
6478
|
+
style: { top: "70%" },
|
|
6479
|
+
"aria-label": "Add item",
|
|
6480
|
+
onMouseDown: (e) => {
|
|
6481
|
+
e.preventDefault();
|
|
6482
|
+
e.stopPropagation();
|
|
6483
|
+
},
|
|
6484
|
+
onClick: (e) => {
|
|
6485
|
+
e.preventDefault();
|
|
6486
|
+
e.stopPropagation();
|
|
6487
|
+
onAdd();
|
|
6488
|
+
},
|
|
6489
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
6490
|
+
}
|
|
6491
|
+
)
|
|
6492
|
+
}
|
|
6493
|
+
);
|
|
6494
|
+
}
|
|
6495
|
+
|
|
6496
|
+
// src/ui/badge.tsx
|
|
6497
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
5833
6498
|
var badgeVariants = cva(
|
|
5834
6499
|
"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",
|
|
5835
6500
|
{
|
|
@@ -5847,12 +6512,12 @@ var badgeVariants = cva(
|
|
|
5847
6512
|
}
|
|
5848
6513
|
);
|
|
5849
6514
|
function Badge({ className, variant, ...props }) {
|
|
5850
|
-
return /* @__PURE__ */ (0,
|
|
6515
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
5851
6516
|
}
|
|
5852
6517
|
|
|
5853
6518
|
// src/OhhwellsBridge.tsx
|
|
5854
|
-
var
|
|
5855
|
-
var
|
|
6519
|
+
var import_lucide_react11 = require("lucide-react");
|
|
6520
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
5856
6521
|
var PRIMARY2 = "#0885FE";
|
|
5857
6522
|
var IMAGE_FADE_MS = 300;
|
|
5858
6523
|
function runOpacityFade(el, onDone) {
|
|
@@ -6024,9 +6689,9 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
6024
6689
|
tail.insertAdjacentElement("afterend", container);
|
|
6025
6690
|
}
|
|
6026
6691
|
const root = (0, import_client.createRoot)(container);
|
|
6027
|
-
(0,
|
|
6692
|
+
(0, import_react_dom2.flushSync)(() => {
|
|
6028
6693
|
root.render(
|
|
6029
|
-
/* @__PURE__ */ (0,
|
|
6694
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6030
6695
|
SchedulingWidget,
|
|
6031
6696
|
{
|
|
6032
6697
|
notifyOnConnect,
|
|
@@ -6066,7 +6731,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
6066
6731
|
}
|
|
6067
6732
|
}
|
|
6068
6733
|
}
|
|
6069
|
-
function
|
|
6734
|
+
function getLinkHref2(el) {
|
|
6070
6735
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
6071
6736
|
return anchor?.getAttribute("href") ?? "";
|
|
6072
6737
|
}
|
|
@@ -6103,7 +6768,7 @@ function collectEditableNodes() {
|
|
|
6103
6768
|
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
6104
6769
|
}
|
|
6105
6770
|
if (el.dataset.ohwEditable === "link") {
|
|
6106
|
-
return { key: el.dataset.ohwKey ?? "", type: "link", text:
|
|
6771
|
+
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref2(el) };
|
|
6107
6772
|
}
|
|
6108
6773
|
return {
|
|
6109
6774
|
key: el.dataset.ohwKey ?? "",
|
|
@@ -6114,7 +6779,7 @@ function collectEditableNodes() {
|
|
|
6114
6779
|
document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
|
|
6115
6780
|
const key = el.getAttribute("data-ohw-href-key") ?? "";
|
|
6116
6781
|
if (!key) return;
|
|
6117
|
-
nodes.push({ key, type: "link", text:
|
|
6782
|
+
nodes.push({ key, type: "link", text: getLinkHref2(el) });
|
|
6118
6783
|
});
|
|
6119
6784
|
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
6120
6785
|
const key = el.dataset.ohwKey ?? "";
|
|
@@ -6184,7 +6849,7 @@ function applyLinkByKey(key, val) {
|
|
|
6184
6849
|
}
|
|
6185
6850
|
function isInsideLinkEditor(target) {
|
|
6186
6851
|
return Boolean(
|
|
6187
|
-
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"]')
|
|
6852
|
+
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"]')
|
|
6188
6853
|
);
|
|
6189
6854
|
}
|
|
6190
6855
|
function getHrefKeyFromElement(el) {
|
|
@@ -6195,7 +6860,7 @@ function getHrefKeyFromElement(el) {
|
|
|
6195
6860
|
if (!key) return null;
|
|
6196
6861
|
return { anchor, key };
|
|
6197
6862
|
}
|
|
6198
|
-
function
|
|
6863
|
+
function isNavbarButton2(el) {
|
|
6199
6864
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
6200
6865
|
}
|
|
6201
6866
|
function getNavigationItemAnchor(el) {
|
|
@@ -6207,19 +6872,8 @@ function getNavigationItemAnchor(el) {
|
|
|
6207
6872
|
function isNavigationItem(el) {
|
|
6208
6873
|
return getNavigationItemAnchor(el) !== null;
|
|
6209
6874
|
}
|
|
6210
|
-
function getNavigationItemAddHintTarget(anchor) {
|
|
6211
|
-
const items = listNavigationItems();
|
|
6212
|
-
const idx = items.indexOf(anchor);
|
|
6213
|
-
if (idx >= 0 && idx < items.length - 1) return items[idx + 1];
|
|
6214
|
-
return anchor;
|
|
6215
|
-
}
|
|
6216
|
-
function listNavigationItems() {
|
|
6217
|
-
return Array.from(
|
|
6218
|
-
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
6219
|
-
).filter((el) => isNavigationItem(el));
|
|
6220
|
-
}
|
|
6221
6875
|
function getNavigationItemReorderState(anchor) {
|
|
6222
|
-
if (
|
|
6876
|
+
if (isNavbarButton2(anchor)) return { key: null, disabled: false };
|
|
6223
6877
|
return getReorderHandleStateFromAnchor(anchor);
|
|
6224
6878
|
}
|
|
6225
6879
|
function getReorderHandleState(el) {
|
|
@@ -6270,6 +6924,39 @@ function isInferredFooterGroup(el) {
|
|
|
6270
6924
|
function isNavigationContainer(el) {
|
|
6271
6925
|
return el.hasAttribute("data-ohw-nav-container") || isNavigationRoot(el) || isInferredFooterGroup(el);
|
|
6272
6926
|
}
|
|
6927
|
+
function isPointOverNavigation(x, y) {
|
|
6928
|
+
const navRoot = document.querySelector("[data-ohw-nav-root]") ?? document.querySelector("nav");
|
|
6929
|
+
if (!navRoot) return false;
|
|
6930
|
+
const r2 = navRoot.getBoundingClientRect();
|
|
6931
|
+
return x >= r2.left && x <= r2.right && y >= r2.top && y <= r2.bottom;
|
|
6932
|
+
}
|
|
6933
|
+
function isPointOverNavItem(container, x, y) {
|
|
6934
|
+
return Array.from(container.querySelectorAll("[data-ohw-href-key]")).some((el) => {
|
|
6935
|
+
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
6936
|
+
const itemRect = el.getBoundingClientRect();
|
|
6937
|
+
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
6938
|
+
});
|
|
6939
|
+
}
|
|
6940
|
+
function resolveNavContainerSelectionTarget(target, clientX, clientY) {
|
|
6941
|
+
if (getNavigationItemAnchor(target)) return null;
|
|
6942
|
+
if (target.closest('[data-ohw-role="navbar-button"]')) return null;
|
|
6943
|
+
const plainLink = target.closest("a");
|
|
6944
|
+
if (plainLink && !plainLink.hasAttribute("data-ohw-href-key") && !plainLink.closest("[data-ohw-nav-container]")) {
|
|
6945
|
+
return null;
|
|
6946
|
+
}
|
|
6947
|
+
const fromClosest = target.closest("[data-ohw-nav-container]");
|
|
6948
|
+
if (fromClosest && !isPointOverNavItem(fromClosest, clientX, clientY)) {
|
|
6949
|
+
return fromClosest;
|
|
6950
|
+
}
|
|
6951
|
+
const navRoot = target.closest("[data-ohw-nav-root]");
|
|
6952
|
+
if (!navRoot) return null;
|
|
6953
|
+
const container = navRoot.querySelector("[data-ohw-nav-container]");
|
|
6954
|
+
if (!container || isPointOverNavItem(container, clientX, clientY)) return null;
|
|
6955
|
+
if (target === navRoot || target.hasAttribute("data-ohw-nav-root")) {
|
|
6956
|
+
return container;
|
|
6957
|
+
}
|
|
6958
|
+
return null;
|
|
6959
|
+
}
|
|
6273
6960
|
function getNavigationSelectionParent(el) {
|
|
6274
6961
|
if (isNavigationItem(el)) {
|
|
6275
6962
|
const explicit = el.closest("[data-ohw-nav-container]");
|
|
@@ -6471,7 +7158,7 @@ function EditGlowChrome({
|
|
|
6471
7158
|
dragDisabled = false
|
|
6472
7159
|
}) {
|
|
6473
7160
|
const GAP = 6;
|
|
6474
|
-
return /* @__PURE__ */ (0,
|
|
7161
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
6475
7162
|
"div",
|
|
6476
7163
|
{
|
|
6477
7164
|
ref: elRef,
|
|
@@ -6486,7 +7173,7 @@ function EditGlowChrome({
|
|
|
6486
7173
|
zIndex: 2147483646
|
|
6487
7174
|
},
|
|
6488
7175
|
children: [
|
|
6489
|
-
/* @__PURE__ */ (0,
|
|
7176
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6490
7177
|
"div",
|
|
6491
7178
|
{
|
|
6492
7179
|
style: {
|
|
@@ -6499,7 +7186,7 @@ function EditGlowChrome({
|
|
|
6499
7186
|
}
|
|
6500
7187
|
}
|
|
6501
7188
|
),
|
|
6502
|
-
reorderHrefKey && /* @__PURE__ */ (0,
|
|
7189
|
+
reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6503
7190
|
"div",
|
|
6504
7191
|
{
|
|
6505
7192
|
"data-ohw-drag-handle-container": "",
|
|
@@ -6511,7 +7198,7 @@ function EditGlowChrome({
|
|
|
6511
7198
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
6512
7199
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
6513
7200
|
},
|
|
6514
|
-
children: /* @__PURE__ */ (0,
|
|
7201
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6515
7202
|
DragHandle,
|
|
6516
7203
|
{
|
|
6517
7204
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -6615,7 +7302,7 @@ function FloatingToolbar({
|
|
|
6615
7302
|
onEditLink
|
|
6616
7303
|
}) {
|
|
6617
7304
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
6618
|
-
return /* @__PURE__ */ (0,
|
|
7305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6619
7306
|
"div",
|
|
6620
7307
|
{
|
|
6621
7308
|
ref: elRef,
|
|
@@ -6636,12 +7323,12 @@ function FloatingToolbar({
|
|
|
6636
7323
|
fontFamily: "sans-serif",
|
|
6637
7324
|
pointerEvents: "auto"
|
|
6638
7325
|
},
|
|
6639
|
-
children: /* @__PURE__ */ (0,
|
|
6640
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
6641
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
7326
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(CustomToolbar, { children: [
|
|
7327
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_react8.default.Fragment, { children: [
|
|
7328
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CustomToolbarDivider, {}),
|
|
6642
7329
|
btns.map((btn) => {
|
|
6643
7330
|
const isActive = activeCommands.has(btn.cmd);
|
|
6644
|
-
return /* @__PURE__ */ (0,
|
|
7331
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6645
7332
|
CustomToolbarButton,
|
|
6646
7333
|
{
|
|
6647
7334
|
title: btn.title,
|
|
@@ -6650,7 +7337,7 @@ function FloatingToolbar({
|
|
|
6650
7337
|
e.preventDefault();
|
|
6651
7338
|
onCommand(btn.cmd);
|
|
6652
7339
|
},
|
|
6653
|
-
children: /* @__PURE__ */ (0,
|
|
7340
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6654
7341
|
"svg",
|
|
6655
7342
|
{
|
|
6656
7343
|
width: "16",
|
|
@@ -6671,7 +7358,7 @@ function FloatingToolbar({
|
|
|
6671
7358
|
);
|
|
6672
7359
|
})
|
|
6673
7360
|
] }, gi)),
|
|
6674
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
7361
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6675
7362
|
CustomToolbarButton,
|
|
6676
7363
|
{
|
|
6677
7364
|
type: "button",
|
|
@@ -6685,7 +7372,7 @@ function FloatingToolbar({
|
|
|
6685
7372
|
e.preventDefault();
|
|
6686
7373
|
e.stopPropagation();
|
|
6687
7374
|
},
|
|
6688
|
-
children: /* @__PURE__ */ (0,
|
|
7375
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
6689
7376
|
}
|
|
6690
7377
|
) : null
|
|
6691
7378
|
] })
|
|
@@ -6702,7 +7389,7 @@ function StateToggle({
|
|
|
6702
7389
|
states,
|
|
6703
7390
|
onStateChange
|
|
6704
7391
|
}) {
|
|
6705
|
-
return /* @__PURE__ */ (0,
|
|
7392
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6706
7393
|
ToggleGroup,
|
|
6707
7394
|
{
|
|
6708
7395
|
"data-ohw-state-toggle": "",
|
|
@@ -6716,7 +7403,7 @@ function StateToggle({
|
|
|
6716
7403
|
left: rect.right - 8,
|
|
6717
7404
|
transform: "translateX(-100%)"
|
|
6718
7405
|
},
|
|
6719
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
7406
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
6720
7407
|
}
|
|
6721
7408
|
);
|
|
6722
7409
|
}
|
|
@@ -6739,12 +7426,12 @@ function resolveSubdomain(subdomainFromQuery) {
|
|
|
6739
7426
|
return "";
|
|
6740
7427
|
}
|
|
6741
7428
|
function OhhwellsBridge() {
|
|
6742
|
-
const pathname = (0,
|
|
6743
|
-
const router = (0,
|
|
6744
|
-
const searchParams = (0,
|
|
7429
|
+
const pathname = (0, import_navigation2.usePathname)();
|
|
7430
|
+
const router = (0, import_navigation2.useRouter)();
|
|
7431
|
+
const searchParams = (0, import_navigation2.useSearchParams)();
|
|
6745
7432
|
const isEditMode = isEditSessionActive();
|
|
6746
|
-
const [bridgeRoot, setBridgeRoot] = (0,
|
|
6747
|
-
(0,
|
|
7433
|
+
const [bridgeRoot, setBridgeRoot] = (0, import_react8.useState)(null);
|
|
7434
|
+
(0, import_react8.useEffect)(() => {
|
|
6748
7435
|
const figtreeFontId = "ohw-figtree-font";
|
|
6749
7436
|
if (!document.getElementById(figtreeFontId)) {
|
|
6750
7437
|
const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
|
|
@@ -6772,84 +7459,90 @@ function OhhwellsBridge() {
|
|
|
6772
7459
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
6773
7460
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
6774
7461
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
6775
|
-
const
|
|
7462
|
+
const postToParent2 = (0, import_react8.useCallback)((data) => {
|
|
6776
7463
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
6777
7464
|
window.parent.postMessage(data, "*");
|
|
6778
7465
|
}
|
|
6779
7466
|
}, []);
|
|
6780
|
-
const [fetchState, setFetchState] = (0,
|
|
6781
|
-
const autoSaveTimers = (0,
|
|
6782
|
-
const activeElRef = (0,
|
|
6783
|
-
const selectedElRef = (0,
|
|
6784
|
-
const originalContentRef = (0,
|
|
6785
|
-
const activeStateElRef = (0,
|
|
6786
|
-
const parentScrollRef = (0,
|
|
6787
|
-
const visibleViewportRef = (0,
|
|
6788
|
-
const [dialogPortalContainer, setDialogPortalContainer] = (0,
|
|
6789
|
-
const attachVisibleViewport = (0,
|
|
7467
|
+
const [fetchState, setFetchState] = (0, import_react8.useState)("idle");
|
|
7468
|
+
const autoSaveTimers = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
|
|
7469
|
+
const activeElRef = (0, import_react8.useRef)(null);
|
|
7470
|
+
const selectedElRef = (0, import_react8.useRef)(null);
|
|
7471
|
+
const originalContentRef = (0, import_react8.useRef)(null);
|
|
7472
|
+
const activeStateElRef = (0, import_react8.useRef)(null);
|
|
7473
|
+
const parentScrollRef = (0, import_react8.useRef)(null);
|
|
7474
|
+
const visibleViewportRef = (0, import_react8.useRef)(null);
|
|
7475
|
+
const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react8.useState)(null);
|
|
7476
|
+
const attachVisibleViewport = (0, import_react8.useCallback)((node) => {
|
|
6790
7477
|
visibleViewportRef.current = node;
|
|
6791
7478
|
setDialogPortalContainer(node);
|
|
6792
7479
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
6793
7480
|
}, []);
|
|
6794
|
-
const toolbarElRef = (0,
|
|
6795
|
-
const glowElRef = (0,
|
|
6796
|
-
const hoveredImageRef = (0,
|
|
6797
|
-
const hoveredImageHasTextOverlapRef = (0,
|
|
6798
|
-
const [mediaHover, setMediaHover] = (0,
|
|
6799
|
-
const [uploadingRects, setUploadingRects] = (0,
|
|
6800
|
-
const hoveredGapRef = (0,
|
|
6801
|
-
const imageUnhoverTimerRef = (0,
|
|
6802
|
-
const imageShowTimerRef = (0,
|
|
6803
|
-
const editStylesRef = (0,
|
|
6804
|
-
const activateRef = (0,
|
|
7481
|
+
const toolbarElRef = (0, import_react8.useRef)(null);
|
|
7482
|
+
const glowElRef = (0, import_react8.useRef)(null);
|
|
7483
|
+
const hoveredImageRef = (0, import_react8.useRef)(null);
|
|
7484
|
+
const hoveredImageHasTextOverlapRef = (0, import_react8.useRef)(false);
|
|
7485
|
+
const [mediaHover, setMediaHover] = (0, import_react8.useState)(null);
|
|
7486
|
+
const [uploadingRects, setUploadingRects] = (0, import_react8.useState)({});
|
|
7487
|
+
const hoveredGapRef = (0, import_react8.useRef)(null);
|
|
7488
|
+
const imageUnhoverTimerRef = (0, import_react8.useRef)(null);
|
|
7489
|
+
const imageShowTimerRef = (0, import_react8.useRef)(null);
|
|
7490
|
+
const editStylesRef = (0, import_react8.useRef)(null);
|
|
7491
|
+
const activateRef = (0, import_react8.useRef)(() => {
|
|
6805
7492
|
});
|
|
6806
|
-
const deactivateRef = (0,
|
|
7493
|
+
const deactivateRef = (0, import_react8.useRef)(() => {
|
|
6807
7494
|
});
|
|
6808
|
-
const selectRef = (0,
|
|
7495
|
+
const selectRef = (0, import_react8.useRef)(() => {
|
|
6809
7496
|
});
|
|
6810
|
-
const selectFrameRef = (0,
|
|
7497
|
+
const selectFrameRef = (0, import_react8.useRef)(() => {
|
|
6811
7498
|
});
|
|
6812
|
-
const deselectRef = (0,
|
|
7499
|
+
const deselectRef = (0, import_react8.useRef)(() => {
|
|
6813
7500
|
});
|
|
6814
|
-
const reselectNavigationItemRef = (0,
|
|
7501
|
+
const reselectNavigationItemRef = (0, import_react8.useRef)(() => {
|
|
6815
7502
|
});
|
|
6816
|
-
const commitNavigationTextEditRef = (0,
|
|
7503
|
+
const commitNavigationTextEditRef = (0, import_react8.useRef)(() => {
|
|
6817
7504
|
});
|
|
6818
|
-
const refreshActiveCommandsRef = (0,
|
|
7505
|
+
const refreshActiveCommandsRef = (0, import_react8.useRef)(() => {
|
|
6819
7506
|
});
|
|
6820
|
-
const postToParentRef = (0,
|
|
6821
|
-
postToParentRef.current =
|
|
6822
|
-
const sectionsLoadedRef = (0,
|
|
6823
|
-
const pendingScheduleConfigRequests = (0,
|
|
6824
|
-
const [toolbarRect, setToolbarRect] = (0,
|
|
6825
|
-
const [toolbarVariant, setToolbarVariant] = (0,
|
|
6826
|
-
const toolbarVariantRef = (0,
|
|
7507
|
+
const postToParentRef = (0, import_react8.useRef)(postToParent2);
|
|
7508
|
+
postToParentRef.current = postToParent2;
|
|
7509
|
+
const sectionsLoadedRef = (0, import_react8.useRef)(false);
|
|
7510
|
+
const pendingScheduleConfigRequests = (0, import_react8.useRef)([]);
|
|
7511
|
+
const [toolbarRect, setToolbarRect] = (0, import_react8.useState)(null);
|
|
7512
|
+
const [toolbarVariant, setToolbarVariant] = (0, import_react8.useState)("none");
|
|
7513
|
+
const toolbarVariantRef = (0, import_react8.useRef)("none");
|
|
6827
7514
|
toolbarVariantRef.current = toolbarVariant;
|
|
6828
|
-
const [reorderHrefKey, setReorderHrefKey] = (0,
|
|
6829
|
-
const [reorderDragDisabled, setReorderDragDisabled] = (0,
|
|
6830
|
-
const [toggleState, setToggleState] = (0,
|
|
6831
|
-
const [maxBadge, setMaxBadge] = (0,
|
|
6832
|
-
const [activeCommands, setActiveCommands] = (0,
|
|
6833
|
-
const [sectionGap, setSectionGap] = (0,
|
|
6834
|
-
const [toolbarShowEditLink, setToolbarShowEditLink] = (0,
|
|
6835
|
-
const
|
|
6836
|
-
const [
|
|
6837
|
-
const
|
|
6838
|
-
const [
|
|
6839
|
-
const
|
|
6840
|
-
const [
|
|
6841
|
-
const [
|
|
6842
|
-
const [
|
|
6843
|
-
const
|
|
6844
|
-
const
|
|
6845
|
-
const
|
|
6846
|
-
const
|
|
6847
|
-
const
|
|
7515
|
+
const [reorderHrefKey, setReorderHrefKey] = (0, import_react8.useState)(null);
|
|
7516
|
+
const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react8.useState)(false);
|
|
7517
|
+
const [toggleState, setToggleState] = (0, import_react8.useState)(null);
|
|
7518
|
+
const [maxBadge, setMaxBadge] = (0, import_react8.useState)(null);
|
|
7519
|
+
const [activeCommands, setActiveCommands] = (0, import_react8.useState)(/* @__PURE__ */ new Set());
|
|
7520
|
+
const [sectionGap, setSectionGap] = (0, import_react8.useState)(null);
|
|
7521
|
+
const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react8.useState)(false);
|
|
7522
|
+
const hoveredNavContainerRef = (0, import_react8.useRef)(null);
|
|
7523
|
+
const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react8.useState)(null);
|
|
7524
|
+
const hoveredItemElRef = (0, import_react8.useRef)(null);
|
|
7525
|
+
const [hoveredItemRect, setHoveredItemRect] = (0, import_react8.useState)(null);
|
|
7526
|
+
const siblingHintElRef = (0, import_react8.useRef)(null);
|
|
7527
|
+
const [siblingHintRect, setSiblingHintRect] = (0, import_react8.useState)(null);
|
|
7528
|
+
const [isItemDragging, setIsItemDragging] = (0, import_react8.useState)(false);
|
|
7529
|
+
const [linkPopover, setLinkPopover] = (0, import_react8.useState)(null);
|
|
7530
|
+
const linkPopoverSessionRef = (0, import_react8.useRef)(null);
|
|
7531
|
+
const addNavAfterAnchorRef = (0, import_react8.useRef)(null);
|
|
7532
|
+
const editContentRef = (0, import_react8.useRef)({});
|
|
7533
|
+
const [sitePages, setSitePages] = (0, import_react8.useState)([]);
|
|
7534
|
+
const [sectionsByPath, setSectionsByPath] = (0, import_react8.useState)({});
|
|
7535
|
+
const sectionsPrefetchGenRef = (0, import_react8.useRef)(0);
|
|
7536
|
+
const setLinkPopoverRef = (0, import_react8.useRef)(setLinkPopover);
|
|
7537
|
+
const linkPopoverPanelRef = (0, import_react8.useRef)(null);
|
|
7538
|
+
const linkPopoverOpenRef = (0, import_react8.useRef)(false);
|
|
7539
|
+
const linkPopoverGraceUntilRef = (0, import_react8.useRef)(0);
|
|
6848
7540
|
setLinkPopoverRef.current = setLinkPopover;
|
|
7541
|
+
linkPopoverSessionRef.current = linkPopover;
|
|
6849
7542
|
const bumpLinkPopoverGrace = () => {
|
|
6850
7543
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
6851
7544
|
};
|
|
6852
|
-
const runSectionsPrefetch = (0,
|
|
7545
|
+
const runSectionsPrefetch = (0, import_react8.useCallback)((pages) => {
|
|
6853
7546
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
6854
7547
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
6855
7548
|
const paths = pages.map((p) => p.path);
|
|
@@ -6868,9 +7561,9 @@ function OhhwellsBridge() {
|
|
|
6868
7561
|
);
|
|
6869
7562
|
});
|
|
6870
7563
|
}, [isEditMode, pathname]);
|
|
6871
|
-
const runSectionsPrefetchRef = (0,
|
|
7564
|
+
const runSectionsPrefetchRef = (0, import_react8.useRef)(runSectionsPrefetch);
|
|
6872
7565
|
runSectionsPrefetchRef.current = runSectionsPrefetch;
|
|
6873
|
-
(0,
|
|
7566
|
+
(0, import_react8.useEffect)(() => {
|
|
6874
7567
|
if (!linkPopover) return;
|
|
6875
7568
|
if (hoveredImageRef.current) {
|
|
6876
7569
|
hoveredImageRef.current = null;
|
|
@@ -6878,33 +7571,9 @@ function OhhwellsBridge() {
|
|
|
6878
7571
|
}
|
|
6879
7572
|
hoveredGapRef.current = null;
|
|
6880
7573
|
setSectionGap(null);
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
const body = document.body;
|
|
6885
|
-
const prevHtmlOverflow = html.style.overflow;
|
|
6886
|
-
const prevBodyOverflow = body.style.overflow;
|
|
6887
|
-
html.style.overflow = "hidden";
|
|
6888
|
-
body.style.overflow = "hidden";
|
|
6889
|
-
const preventBackgroundScroll = (e) => {
|
|
6890
|
-
const target = e.target;
|
|
6891
|
-
if (target instanceof Element && target.closest('[data-ohw-link-modal-root], [data-slot="dialog-overlay"]')) {
|
|
6892
|
-
return;
|
|
6893
|
-
}
|
|
6894
|
-
e.preventDefault();
|
|
6895
|
-
};
|
|
6896
|
-
const scrollOpts = { passive: false, capture: true };
|
|
6897
|
-
document.addEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6898
|
-
document.addEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6899
|
-
return () => {
|
|
6900
|
-
postToParent({ type: "ow:link-modal-lock", locked: false });
|
|
6901
|
-
html.style.overflow = prevHtmlOverflow;
|
|
6902
|
-
body.style.overflow = prevBodyOverflow;
|
|
6903
|
-
document.removeEventListener("wheel", preventBackgroundScroll, scrollOpts);
|
|
6904
|
-
document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
|
|
6905
|
-
};
|
|
6906
|
-
}, [linkPopover, postToParent]);
|
|
6907
|
-
(0, import_react6.useEffect)(() => {
|
|
7574
|
+
postToParent2({ type: "ow:image-unhover" });
|
|
7575
|
+
}, [linkPopover, postToParent2]);
|
|
7576
|
+
(0, import_react8.useEffect)(() => {
|
|
6908
7577
|
if (!isEditMode) return;
|
|
6909
7578
|
const useFixtures = shouldUseDevFixtures();
|
|
6910
7579
|
if (useFixtures) {
|
|
@@ -6925,17 +7594,17 @@ function OhhwellsBridge() {
|
|
|
6925
7594
|
runSectionsPrefetchRef.current(mapped);
|
|
6926
7595
|
};
|
|
6927
7596
|
window.addEventListener("message", onSitePages);
|
|
6928
|
-
if (!useFixtures)
|
|
7597
|
+
if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
|
|
6929
7598
|
return () => window.removeEventListener("message", onSitePages);
|
|
6930
|
-
}, [isEditMode,
|
|
6931
|
-
(0,
|
|
7599
|
+
}, [isEditMode, postToParent2]);
|
|
7600
|
+
(0, import_react8.useEffect)(() => {
|
|
6932
7601
|
if (!isEditMode || shouldUseDevFixtures()) return;
|
|
6933
7602
|
void loadAllSectionsManifest().then((manifest) => {
|
|
6934
7603
|
if (Object.keys(manifest).length === 0) return;
|
|
6935
7604
|
setSectionsByPath((prev) => ({ ...manifest, ...prev }));
|
|
6936
7605
|
});
|
|
6937
7606
|
}, [isEditMode]);
|
|
6938
|
-
(0,
|
|
7607
|
+
(0, import_react8.useEffect)(() => {
|
|
6939
7608
|
const update = () => {
|
|
6940
7609
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
6941
7610
|
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
@@ -6959,10 +7628,10 @@ function OhhwellsBridge() {
|
|
|
6959
7628
|
vvp.removeEventListener("resize", update);
|
|
6960
7629
|
};
|
|
6961
7630
|
}, []);
|
|
6962
|
-
const refreshStateRules = (0,
|
|
7631
|
+
const refreshStateRules = (0, import_react8.useCallback)(() => {
|
|
6963
7632
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
6964
7633
|
}, []);
|
|
6965
|
-
const processConfigRequest = (0,
|
|
7634
|
+
const processConfigRequest = (0, import_react8.useCallback)((insertAfterVal) => {
|
|
6966
7635
|
const tracker = getSectionsTracker();
|
|
6967
7636
|
let entries = [];
|
|
6968
7637
|
try {
|
|
@@ -6985,7 +7654,7 @@ function OhhwellsBridge() {
|
|
|
6985
7654
|
}
|
|
6986
7655
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
6987
7656
|
}, [isEditMode]);
|
|
6988
|
-
const deactivate = (0,
|
|
7657
|
+
const deactivate = (0, import_react8.useCallback)(() => {
|
|
6989
7658
|
const el = activeElRef.current;
|
|
6990
7659
|
if (!el) return;
|
|
6991
7660
|
const key = el.dataset.ohwKey;
|
|
@@ -7014,21 +7683,23 @@ function OhhwellsBridge() {
|
|
|
7014
7683
|
setMaxBadge(null);
|
|
7015
7684
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7016
7685
|
setToolbarShowEditLink(false);
|
|
7017
|
-
|
|
7018
|
-
}, [
|
|
7019
|
-
const deselect = (0,
|
|
7686
|
+
postToParent2({ type: "ow:exit-edit" });
|
|
7687
|
+
}, [postToParent2]);
|
|
7688
|
+
const deselect = (0, import_react8.useCallback)(() => {
|
|
7020
7689
|
selectedElRef.current = null;
|
|
7021
7690
|
setReorderHrefKey(null);
|
|
7022
7691
|
setReorderDragDisabled(false);
|
|
7023
7692
|
siblingHintElRef.current = null;
|
|
7024
7693
|
setSiblingHintRect(null);
|
|
7025
7694
|
setIsItemDragging(false);
|
|
7695
|
+
hoveredNavContainerRef.current = null;
|
|
7696
|
+
setHoveredNavContainerRect(null);
|
|
7026
7697
|
if (!activeElRef.current) {
|
|
7027
7698
|
setToolbarRect(null);
|
|
7028
7699
|
setToolbarVariant("none");
|
|
7029
7700
|
}
|
|
7030
7701
|
}, []);
|
|
7031
|
-
const reselectNavigationItem = (0,
|
|
7702
|
+
const reselectNavigationItem = (0, import_react8.useCallback)((navAnchor) => {
|
|
7032
7703
|
selectedElRef.current = navAnchor;
|
|
7033
7704
|
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
7034
7705
|
setReorderHrefKey(key);
|
|
@@ -7038,7 +7709,7 @@ function OhhwellsBridge() {
|
|
|
7038
7709
|
setToolbarShowEditLink(false);
|
|
7039
7710
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7040
7711
|
}, []);
|
|
7041
|
-
const commitNavigationTextEdit = (0,
|
|
7712
|
+
const commitNavigationTextEdit = (0, import_react8.useCallback)((navAnchor) => {
|
|
7042
7713
|
const el = activeElRef.current;
|
|
7043
7714
|
if (!el) return;
|
|
7044
7715
|
const key = el.dataset.ohwKey;
|
|
@@ -7051,9 +7722,9 @@ function OhhwellsBridge() {
|
|
|
7051
7722
|
const html = sanitizeHtml(el.innerHTML);
|
|
7052
7723
|
const original = originalContentRef.current ?? "";
|
|
7053
7724
|
if (html !== sanitizeHtml(original)) {
|
|
7054
|
-
|
|
7725
|
+
postToParent2({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
7055
7726
|
const h = document.documentElement.scrollHeight;
|
|
7056
|
-
if (h > 50)
|
|
7727
|
+
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
7057
7728
|
}
|
|
7058
7729
|
}
|
|
7059
7730
|
el.removeAttribute("contenteditable");
|
|
@@ -7061,31 +7732,38 @@ function OhhwellsBridge() {
|
|
|
7061
7732
|
setMaxBadge(null);
|
|
7062
7733
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7063
7734
|
setToolbarShowEditLink(false);
|
|
7064
|
-
|
|
7735
|
+
postToParent2({ type: "ow:exit-edit" });
|
|
7065
7736
|
reselectNavigationItem(navAnchor);
|
|
7066
|
-
}, [
|
|
7067
|
-
const
|
|
7068
|
-
const
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7737
|
+
}, [postToParent2, reselectNavigationItem]);
|
|
7738
|
+
const handleAddTopLevelNavItem = (0, import_react8.useCallback)(() => {
|
|
7739
|
+
const items = listNavbarItems();
|
|
7740
|
+
addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
|
|
7741
|
+
deselectRef.current();
|
|
7742
|
+
deactivateRef.current();
|
|
7743
|
+
bumpLinkPopoverGrace();
|
|
7744
|
+
setLinkPopover({
|
|
7745
|
+
key: "__add-nav__",
|
|
7746
|
+
mode: "create",
|
|
7747
|
+
intent: "add-nav"
|
|
7748
|
+
});
|
|
7073
7749
|
}, []);
|
|
7074
|
-
const handleItemDragStart = (0,
|
|
7750
|
+
const handleItemDragStart = (0, import_react8.useCallback)(() => {
|
|
7075
7751
|
siblingHintElRef.current = null;
|
|
7076
7752
|
setSiblingHintRect(null);
|
|
7077
7753
|
setIsItemDragging(true);
|
|
7078
7754
|
}, []);
|
|
7079
|
-
const handleItemDragEnd = (0,
|
|
7755
|
+
const handleItemDragEnd = (0, import_react8.useCallback)(() => {
|
|
7080
7756
|
setIsItemDragging(false);
|
|
7081
7757
|
}, []);
|
|
7082
7758
|
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
7083
7759
|
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
7084
|
-
const select = (0,
|
|
7760
|
+
const select = (0, import_react8.useCallback)((anchor) => {
|
|
7085
7761
|
if (!isNavigationItem(anchor)) return;
|
|
7086
7762
|
if (activeElRef.current) deactivate();
|
|
7087
7763
|
selectedElRef.current = anchor;
|
|
7088
7764
|
clearHrefKeyHover(anchor);
|
|
7765
|
+
hoveredNavContainerRef.current = null;
|
|
7766
|
+
setHoveredNavContainerRect(null);
|
|
7089
7767
|
setHoveredItemRect(null);
|
|
7090
7768
|
hoveredItemElRef.current = null;
|
|
7091
7769
|
siblingHintElRef.current = null;
|
|
@@ -7099,11 +7777,13 @@ function OhhwellsBridge() {
|
|
|
7099
7777
|
setToolbarShowEditLink(false);
|
|
7100
7778
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7101
7779
|
}, [deactivate]);
|
|
7102
|
-
const selectFrame = (0,
|
|
7780
|
+
const selectFrame = (0, import_react8.useCallback)((el) => {
|
|
7103
7781
|
if (!isNavigationContainer(el)) return;
|
|
7104
7782
|
if (activeElRef.current) deactivate();
|
|
7105
7783
|
selectedElRef.current = el;
|
|
7106
7784
|
clearHrefKeyHover(el);
|
|
7785
|
+
hoveredNavContainerRef.current = null;
|
|
7786
|
+
setHoveredNavContainerRect(null);
|
|
7107
7787
|
setHoveredItemRect(null);
|
|
7108
7788
|
hoveredItemElRef.current = null;
|
|
7109
7789
|
siblingHintElRef.current = null;
|
|
@@ -7116,7 +7796,7 @@ function OhhwellsBridge() {
|
|
|
7116
7796
|
setToolbarShowEditLink(false);
|
|
7117
7797
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7118
7798
|
}, [deactivate]);
|
|
7119
|
-
const activate = (0,
|
|
7799
|
+
const activate = (0, import_react8.useCallback)((el, options) => {
|
|
7120
7800
|
if (activeElRef.current === el) return;
|
|
7121
7801
|
selectedElRef.current = null;
|
|
7122
7802
|
deactivate();
|
|
@@ -7148,15 +7828,15 @@ function OhhwellsBridge() {
|
|
|
7148
7828
|
setReorderDragDisabled(reorderDisabled);
|
|
7149
7829
|
}
|
|
7150
7830
|
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
7151
|
-
|
|
7831
|
+
postToParent2({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
7152
7832
|
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
7153
|
-
}, [deactivate,
|
|
7833
|
+
}, [deactivate, postToParent2]);
|
|
7154
7834
|
activateRef.current = activate;
|
|
7155
7835
|
deactivateRef.current = deactivate;
|
|
7156
7836
|
selectRef.current = select;
|
|
7157
7837
|
selectFrameRef.current = selectFrame;
|
|
7158
7838
|
deselectRef.current = deselect;
|
|
7159
|
-
(0,
|
|
7839
|
+
(0, import_react8.useLayoutEffect)(() => {
|
|
7160
7840
|
if (!subdomain || isEditMode) {
|
|
7161
7841
|
setFetchState("done");
|
|
7162
7842
|
return;
|
|
@@ -7224,7 +7904,7 @@ function OhhwellsBridge() {
|
|
|
7224
7904
|
cancelled = true;
|
|
7225
7905
|
};
|
|
7226
7906
|
}, [subdomain, isEditMode]);
|
|
7227
|
-
(0,
|
|
7907
|
+
(0, import_react8.useEffect)(() => {
|
|
7228
7908
|
if (!subdomain || isEditMode) return;
|
|
7229
7909
|
let debounceTimer = null;
|
|
7230
7910
|
let observer = null;
|
|
@@ -7272,26 +7952,40 @@ function OhhwellsBridge() {
|
|
|
7272
7952
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
7273
7953
|
};
|
|
7274
7954
|
}, [subdomain, isEditMode, pathname]);
|
|
7275
|
-
(0,
|
|
7955
|
+
(0, import_react8.useLayoutEffect)(() => {
|
|
7276
7956
|
const el = document.getElementById("ohw-loader");
|
|
7277
7957
|
if (!el) return;
|
|
7278
7958
|
const visible = Boolean(subdomain) && fetchState !== "done";
|
|
7279
7959
|
el.style.display = visible ? "flex" : "none";
|
|
7280
7960
|
}, [subdomain, fetchState]);
|
|
7281
|
-
(0,
|
|
7282
|
-
|
|
7283
|
-
}, [pathname,
|
|
7284
|
-
(0,
|
|
7961
|
+
(0, import_react8.useEffect)(() => {
|
|
7962
|
+
postToParent2({ type: "ow:navigation", path: pathname });
|
|
7963
|
+
}, [pathname, postToParent2]);
|
|
7964
|
+
(0, import_react8.useEffect)(() => {
|
|
7285
7965
|
if (!isEditMode) return;
|
|
7966
|
+
if (linkPopoverSessionRef.current?.intent === "add-nav") return;
|
|
7967
|
+
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
7286
7968
|
setLinkPopover(null);
|
|
7287
7969
|
deselectRef.current();
|
|
7288
7970
|
deactivateRef.current();
|
|
7289
7971
|
}, [pathname, isEditMode]);
|
|
7290
|
-
(0,
|
|
7972
|
+
(0, import_react8.useEffect)(() => {
|
|
7973
|
+
if (!isEditMode) return;
|
|
7974
|
+
const run = () => reconcileNavbarItemsFromContent(editContentRef.current);
|
|
7975
|
+
run();
|
|
7976
|
+
const nav = document.querySelector("nav");
|
|
7977
|
+
if (!nav) return;
|
|
7978
|
+
const observer = new MutationObserver(() => {
|
|
7979
|
+
requestAnimationFrame(run);
|
|
7980
|
+
});
|
|
7981
|
+
observer.observe(nav, { childList: true, subtree: true });
|
|
7982
|
+
return () => observer.disconnect();
|
|
7983
|
+
}, [isEditMode, pathname]);
|
|
7984
|
+
(0, import_react8.useEffect)(() => {
|
|
7291
7985
|
if (!isEditMode) return;
|
|
7292
7986
|
const measure = () => {
|
|
7293
7987
|
const h = document.body.scrollHeight;
|
|
7294
|
-
if (h > 50)
|
|
7988
|
+
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
7295
7989
|
};
|
|
7296
7990
|
const t1 = setTimeout(measure, 50);
|
|
7297
7991
|
const t2 = setTimeout(measure, 500);
|
|
@@ -7310,8 +8004,8 @@ function OhhwellsBridge() {
|
|
|
7310
8004
|
if (resizeTimer) clearTimeout(resizeTimer);
|
|
7311
8005
|
window.removeEventListener("resize", handleResize);
|
|
7312
8006
|
};
|
|
7313
|
-
}, [pathname, isEditMode,
|
|
7314
|
-
(0,
|
|
8007
|
+
}, [pathname, isEditMode, postToParent2]);
|
|
8008
|
+
(0, import_react8.useEffect)(() => {
|
|
7315
8009
|
if (!subdomainFromQuery || isEditMode) return;
|
|
7316
8010
|
const handleClick = (e) => {
|
|
7317
8011
|
const anchor = e.target.closest("a");
|
|
@@ -7327,7 +8021,7 @@ function OhhwellsBridge() {
|
|
|
7327
8021
|
document.addEventListener("click", handleClick, true);
|
|
7328
8022
|
return () => document.removeEventListener("click", handleClick, true);
|
|
7329
8023
|
}, [subdomainFromQuery, isEditMode, router]);
|
|
7330
|
-
(0,
|
|
8024
|
+
(0, import_react8.useEffect)(() => {
|
|
7331
8025
|
if (!isEditMode) {
|
|
7332
8026
|
editStylesRef.current?.base.remove();
|
|
7333
8027
|
editStylesRef.current?.forceHover.remove();
|
|
@@ -7401,6 +8095,13 @@ function OhhwellsBridge() {
|
|
|
7401
8095
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
7402
8096
|
if (isInsideLinkEditor(target)) return;
|
|
7403
8097
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
8098
|
+
const navFromChrome = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8099
|
+
if (navFromChrome) {
|
|
8100
|
+
e.preventDefault();
|
|
8101
|
+
e.stopPropagation();
|
|
8102
|
+
selectFrameRef.current(navFromChrome);
|
|
8103
|
+
return;
|
|
8104
|
+
}
|
|
7404
8105
|
e.preventDefault();
|
|
7405
8106
|
e.stopPropagation();
|
|
7406
8107
|
return;
|
|
@@ -7415,7 +8116,8 @@ function OhhwellsBridge() {
|
|
|
7415
8116
|
bumpLinkPopoverGrace();
|
|
7416
8117
|
setLinkPopoverRef.current({
|
|
7417
8118
|
key: editable.dataset.ohwKey ?? "",
|
|
7418
|
-
|
|
8119
|
+
mode: "edit",
|
|
8120
|
+
target: getLinkHref2(editable)
|
|
7419
8121
|
});
|
|
7420
8122
|
return;
|
|
7421
8123
|
}
|
|
@@ -7451,6 +8153,13 @@ function OhhwellsBridge() {
|
|
|
7451
8153
|
selectRef.current(hrefAnchor);
|
|
7452
8154
|
return;
|
|
7453
8155
|
}
|
|
8156
|
+
const navContainerToSelect = resolveNavContainerSelectionTarget(target, e.clientX, e.clientY);
|
|
8157
|
+
if (navContainerToSelect) {
|
|
8158
|
+
e.preventDefault();
|
|
8159
|
+
e.stopPropagation();
|
|
8160
|
+
selectFrameRef.current(navContainerToSelect);
|
|
8161
|
+
return;
|
|
8162
|
+
}
|
|
7454
8163
|
const selectedContainer = selectedElRef.current;
|
|
7455
8164
|
if (selectedContainer && isNavigationContainer(selectedContainer)) {
|
|
7456
8165
|
const navItem = getNavigationItemAnchor(target);
|
|
@@ -7509,8 +8218,24 @@ function OhhwellsBridge() {
|
|
|
7509
8218
|
};
|
|
7510
8219
|
const handleMouseOver = (e) => {
|
|
7511
8220
|
const target = e.target;
|
|
8221
|
+
if (toolbarVariantRef.current !== "select-frame") {
|
|
8222
|
+
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
8223
|
+
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
8224
|
+
hoveredNavContainerRef.current = navContainer;
|
|
8225
|
+
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
8226
|
+
hoveredItemElRef.current = null;
|
|
8227
|
+
setHoveredItemRect(null);
|
|
8228
|
+
return;
|
|
8229
|
+
}
|
|
8230
|
+
if (!target.closest("[data-ohw-nav-container]")) {
|
|
8231
|
+
hoveredNavContainerRef.current = null;
|
|
8232
|
+
setHoveredNavContainerRect(null);
|
|
8233
|
+
}
|
|
8234
|
+
}
|
|
7512
8235
|
const navAnchor = getNavigationItemAnchor(target);
|
|
7513
8236
|
if (navAnchor) {
|
|
8237
|
+
hoveredNavContainerRef.current = null;
|
|
8238
|
+
setHoveredNavContainerRect(null);
|
|
7514
8239
|
const selected2 = selectedElRef.current;
|
|
7515
8240
|
if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
|
|
7516
8241
|
clearHrefKeyHover(navAnchor);
|
|
@@ -7535,6 +8260,14 @@ function OhhwellsBridge() {
|
|
|
7535
8260
|
};
|
|
7536
8261
|
const handleMouseOut = (e) => {
|
|
7537
8262
|
const target = e.target;
|
|
8263
|
+
if (target.closest("[data-ohw-nav-container]")) {
|
|
8264
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
8265
|
+
if (related2?.closest("[data-ohw-nav-container], [data-ohw-navbar-container-chrome], [data-ohw-navbar-add-button]")) {
|
|
8266
|
+
return;
|
|
8267
|
+
}
|
|
8268
|
+
hoveredNavContainerRef.current = null;
|
|
8269
|
+
setHoveredNavContainerRect(null);
|
|
8270
|
+
}
|
|
7538
8271
|
const navAnchor = getNavigationItemAnchor(target);
|
|
7539
8272
|
if (navAnchor) {
|
|
7540
8273
|
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -7656,42 +8389,85 @@ function OhhwellsBridge() {
|
|
|
7656
8389
|
}
|
|
7657
8390
|
return smallest;
|
|
7658
8391
|
};
|
|
8392
|
+
const dismissImageHover = () => {
|
|
8393
|
+
if (hoveredImageRef.current) {
|
|
8394
|
+
hoveredImageRef.current = null;
|
|
8395
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
8396
|
+
resumeAnimTracks();
|
|
8397
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
8398
|
+
}
|
|
8399
|
+
clearImageHover();
|
|
8400
|
+
};
|
|
8401
|
+
const probeNavigationHoverAt = (x, y) => {
|
|
8402
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
8403
|
+
hoveredNavContainerRef.current = null;
|
|
8404
|
+
setHoveredNavContainerRect(null);
|
|
8405
|
+
return;
|
|
8406
|
+
}
|
|
8407
|
+
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
8408
|
+
if (!navContainer) {
|
|
8409
|
+
hoveredNavContainerRef.current = null;
|
|
8410
|
+
setHoveredNavContainerRect(null);
|
|
8411
|
+
return;
|
|
8412
|
+
}
|
|
8413
|
+
const containerRect = navContainer.getBoundingClientRect();
|
|
8414
|
+
const overContainer = x >= containerRect.left && x <= containerRect.right && y >= containerRect.top && y <= containerRect.bottom;
|
|
8415
|
+
if (!overContainer) {
|
|
8416
|
+
hoveredNavContainerRef.current = null;
|
|
8417
|
+
setHoveredNavContainerRect(null);
|
|
8418
|
+
return;
|
|
8419
|
+
}
|
|
8420
|
+
const navItemHit = Array.from(
|
|
8421
|
+
navContainer.querySelectorAll("[data-ohw-href-key]")
|
|
8422
|
+
).find((el) => {
|
|
8423
|
+
if (!isNavigationItem(el) || isNavbarButton2(el)) return false;
|
|
8424
|
+
const itemRect = el.getBoundingClientRect();
|
|
8425
|
+
return x >= itemRect.left && x <= itemRect.right && y >= itemRect.top && y <= itemRect.bottom;
|
|
8426
|
+
});
|
|
8427
|
+
if (navItemHit) {
|
|
8428
|
+
hoveredNavContainerRef.current = null;
|
|
8429
|
+
setHoveredNavContainerRect(null);
|
|
8430
|
+
const selected = selectedElRef.current;
|
|
8431
|
+
if (selected !== navItemHit && !selected?.contains(navItemHit)) {
|
|
8432
|
+
clearHrefKeyHover(navItemHit);
|
|
8433
|
+
hoveredItemElRef.current = navItemHit;
|
|
8434
|
+
setHoveredItemRect(navItemHit.getBoundingClientRect());
|
|
8435
|
+
}
|
|
8436
|
+
return;
|
|
8437
|
+
}
|
|
8438
|
+
hoveredNavContainerRef.current = navContainer;
|
|
8439
|
+
setHoveredNavContainerRect(containerRect);
|
|
8440
|
+
hoveredItemElRef.current = null;
|
|
8441
|
+
setHoveredItemRect(null);
|
|
8442
|
+
};
|
|
7659
8443
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
7660
8444
|
if (linkPopoverOpenRef.current) {
|
|
7661
|
-
|
|
7662
|
-
|
|
7663
|
-
|
|
7664
|
-
|
|
7665
|
-
|
|
7666
|
-
|
|
8445
|
+
dismissImageHover();
|
|
8446
|
+
return;
|
|
8447
|
+
}
|
|
8448
|
+
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8449
|
+
if (isPointOverNavigation(x, y)) {
|
|
8450
|
+
dismissImageHover();
|
|
8451
|
+
probeNavigationHoverAt(x, y);
|
|
7667
8452
|
return;
|
|
7668
8453
|
}
|
|
8454
|
+
hoveredNavContainerRef.current = null;
|
|
8455
|
+
setHoveredNavContainerRect(null);
|
|
7669
8456
|
const toggleEl = document.querySelector("[data-ohw-state-toggle]");
|
|
7670
8457
|
if (toggleEl) {
|
|
7671
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7672
8458
|
const tr = toggleEl.getBoundingClientRect();
|
|
7673
8459
|
if (x >= tr.left && x <= tr.right && y >= tr.top && y <= tr.bottom) {
|
|
7674
|
-
|
|
7675
|
-
hoveredImageRef.current = null;
|
|
7676
|
-
resumeAnimTracks();
|
|
7677
|
-
clearImageHover();
|
|
7678
|
-
}
|
|
8460
|
+
dismissImageHover();
|
|
7679
8461
|
return;
|
|
7680
8462
|
}
|
|
7681
8463
|
}
|
|
7682
8464
|
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
7683
8465
|
const activeEl = activeElRef.current;
|
|
7684
8466
|
if (activeEl && (!imgEl || imgEl.contains(activeEl))) {
|
|
7685
|
-
|
|
7686
|
-
hoveredImageRef.current = null;
|
|
7687
|
-
hoveredImageHasTextOverlapRef.current = false;
|
|
7688
|
-
resumeAnimTracks();
|
|
7689
|
-
clearImageHover();
|
|
7690
|
-
}
|
|
8467
|
+
dismissImageHover();
|
|
7691
8468
|
return;
|
|
7692
8469
|
}
|
|
7693
8470
|
if (imgEl) {
|
|
7694
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7695
8471
|
const topEl = document.elementFromPoint(x, y);
|
|
7696
8472
|
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
7697
8473
|
if (hoveredImageRef.current) {
|
|
@@ -7791,12 +8567,12 @@ function OhhwellsBridge() {
|
|
|
7791
8567
|
resumeAnimTracks();
|
|
7792
8568
|
clearImageHover();
|
|
7793
8569
|
}
|
|
7794
|
-
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
8570
|
+
const { x: x2, y: y2 } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7795
8571
|
const textEl = Array.from(
|
|
7796
8572
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7797
8573
|
).find((el) => {
|
|
7798
8574
|
const er = el.getBoundingClientRect();
|
|
7799
|
-
return
|
|
8575
|
+
return x2 >= er.left && x2 <= er.right && y2 >= er.top && y2 <= er.bottom;
|
|
7800
8576
|
});
|
|
7801
8577
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7802
8578
|
if (textEl && !textEl.hasAttribute("contenteditable")) {
|
|
@@ -8093,6 +8869,8 @@ function OhhwellsBridge() {
|
|
|
8093
8869
|
sectionsLoadedRef.current = true;
|
|
8094
8870
|
pendingScheduleConfigRequests.current.splice(0).forEach(processConfigRequest);
|
|
8095
8871
|
}
|
|
8872
|
+
editContentRef.current = { ...editContentRef.current, ...content };
|
|
8873
|
+
reconcileNavbarItemsFromContent(editContentRef.current);
|
|
8096
8874
|
enforceLinkHrefs();
|
|
8097
8875
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
8098
8876
|
};
|
|
@@ -8100,6 +8878,7 @@ function OhhwellsBridge() {
|
|
|
8100
8878
|
const handleDeactivate = (e) => {
|
|
8101
8879
|
if (e.data?.type !== "ow:deactivate") return;
|
|
8102
8880
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
8881
|
+
if (document.querySelector("[data-ohw-section-picker]")) return;
|
|
8103
8882
|
if (linkPopoverOpenRef.current) {
|
|
8104
8883
|
setLinkPopoverRef.current(null);
|
|
8105
8884
|
return;
|
|
@@ -8109,6 +8888,7 @@ function OhhwellsBridge() {
|
|
|
8109
8888
|
};
|
|
8110
8889
|
window.addEventListener("message", handleDeactivate);
|
|
8111
8890
|
const handleKeyDown = (e) => {
|
|
8891
|
+
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
8112
8892
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
8113
8893
|
const navAnchor = getNavigationItemAnchor(activeElRef.current);
|
|
8114
8894
|
if (navAnchor) {
|
|
@@ -8123,8 +8903,13 @@ function OhhwellsBridge() {
|
|
|
8123
8903
|
return;
|
|
8124
8904
|
}
|
|
8125
8905
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
8906
|
+
if (toolbarVariantRef.current === "select-frame") {
|
|
8907
|
+
deselectRef.current();
|
|
8908
|
+
return;
|
|
8909
|
+
}
|
|
8126
8910
|
const parent = getNavigationSelectionParent(selectedElRef.current);
|
|
8127
8911
|
if (parent) {
|
|
8912
|
+
e.preventDefault();
|
|
8128
8913
|
selectFrameRef.current(parent);
|
|
8129
8914
|
} else {
|
|
8130
8915
|
deselectRef.current();
|
|
@@ -8186,6 +8971,9 @@ function OhhwellsBridge() {
|
|
|
8186
8971
|
if (hoveredItemElRef.current) {
|
|
8187
8972
|
setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
|
|
8188
8973
|
}
|
|
8974
|
+
if (hoveredNavContainerRef.current) {
|
|
8975
|
+
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
8976
|
+
}
|
|
8189
8977
|
if (siblingHintElRef.current) {
|
|
8190
8978
|
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
8191
8979
|
}
|
|
@@ -8395,6 +9183,32 @@ function OhhwellsBridge() {
|
|
|
8395
9183
|
activateRef.current(textEditable, { caretX: clientX, caretY: clientY });
|
|
8396
9184
|
return;
|
|
8397
9185
|
}
|
|
9186
|
+
const navContainer = document.querySelector("[data-ohw-nav-container]");
|
|
9187
|
+
if (navContainer) {
|
|
9188
|
+
const r2 = navContainer.getBoundingClientRect();
|
|
9189
|
+
const pad = 8;
|
|
9190
|
+
const over = clientX >= r2.left - pad && clientX <= r2.right + pad && clientY >= r2.top - pad && clientY <= r2.bottom + pad;
|
|
9191
|
+
if (over && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
9192
|
+
selectFrameRef.current(navContainer);
|
|
9193
|
+
return;
|
|
9194
|
+
}
|
|
9195
|
+
}
|
|
9196
|
+
const navRoot = document.querySelector("[data-ohw-nav-root]");
|
|
9197
|
+
if (navRoot && navContainer) {
|
|
9198
|
+
const rr = navRoot.getBoundingClientRect();
|
|
9199
|
+
if (clientX >= rr.left && clientX <= rr.right && clientY >= rr.top && clientY <= rr.bottom && !isPointOverNavItem(navContainer, clientX, clientY)) {
|
|
9200
|
+
const book = navRoot.querySelector('[data-ohw-role="navbar-button"]');
|
|
9201
|
+
if (book) {
|
|
9202
|
+
const br = book.getBoundingClientRect();
|
|
9203
|
+
if (clientX >= br.left && clientX <= br.right && clientY >= br.top && clientY <= br.bottom) {
|
|
9204
|
+
deactivateRef.current();
|
|
9205
|
+
return;
|
|
9206
|
+
}
|
|
9207
|
+
}
|
|
9208
|
+
selectFrameRef.current(navContainer);
|
|
9209
|
+
return;
|
|
9210
|
+
}
|
|
9211
|
+
}
|
|
8398
9212
|
deactivateRef.current();
|
|
8399
9213
|
};
|
|
8400
9214
|
window.addEventListener("message", handleSave);
|
|
@@ -8465,7 +9279,7 @@ function OhhwellsBridge() {
|
|
|
8465
9279
|
if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
|
|
8466
9280
|
};
|
|
8467
9281
|
}, [isEditMode, refreshStateRules]);
|
|
8468
|
-
(0,
|
|
9282
|
+
(0, import_react8.useEffect)(() => {
|
|
8469
9283
|
const handler = (e) => {
|
|
8470
9284
|
if (e.data?.type !== "ow:request-schedule-config") return;
|
|
8471
9285
|
const insertAfterVal = e.data.insertAfter;
|
|
@@ -8481,7 +9295,7 @@ function OhhwellsBridge() {
|
|
|
8481
9295
|
window.addEventListener("message", handler);
|
|
8482
9296
|
return () => window.removeEventListener("message", handler);
|
|
8483
9297
|
}, [processConfigRequest]);
|
|
8484
|
-
(0,
|
|
9298
|
+
(0, import_react8.useEffect)(() => {
|
|
8485
9299
|
if (!isEditMode) return;
|
|
8486
9300
|
document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
|
|
8487
9301
|
el.removeAttribute("data-ohw-active-state");
|
|
@@ -8502,27 +9316,27 @@ function OhhwellsBridge() {
|
|
|
8502
9316
|
const next = { ...prev, [pathKey]: sections };
|
|
8503
9317
|
return shouldUseDevFixtures() ? { ...DEV_SECTIONS_BY_PATH, ...next } : next;
|
|
8504
9318
|
});
|
|
8505
|
-
|
|
8506
|
-
|
|
9319
|
+
postToParent2({ type: "ow:ready", version: "1", path: pathname, nodes: collectEditableNodes(), sections });
|
|
9320
|
+
postToParent2({ type: "ow:request-site-pages" });
|
|
8507
9321
|
}, 150);
|
|
8508
9322
|
return () => {
|
|
8509
9323
|
cancelAnimationFrame(raf);
|
|
8510
9324
|
clearTimeout(timer);
|
|
8511
9325
|
};
|
|
8512
|
-
}, [pathname, isEditMode, refreshStateRules,
|
|
8513
|
-
(0,
|
|
9326
|
+
}, [pathname, isEditMode, refreshStateRules, postToParent2]);
|
|
9327
|
+
(0, import_react8.useEffect)(() => {
|
|
8514
9328
|
scrollToHashSectionWhenReady();
|
|
8515
9329
|
const onHashChange = () => scrollToHashSectionWhenReady();
|
|
8516
9330
|
window.addEventListener("hashchange", onHashChange);
|
|
8517
9331
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
8518
9332
|
}, [pathname]);
|
|
8519
|
-
const handleCommand = (0,
|
|
9333
|
+
const handleCommand = (0, import_react8.useCallback)((cmd) => {
|
|
8520
9334
|
document.execCommand(cmd, false);
|
|
8521
9335
|
activeElRef.current?.focus();
|
|
8522
9336
|
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
8523
9337
|
refreshActiveCommandsRef.current();
|
|
8524
9338
|
}, []);
|
|
8525
|
-
const handleStateChange = (0,
|
|
9339
|
+
const handleStateChange = (0, import_react8.useCallback)((state) => {
|
|
8526
9340
|
if (!activeStateElRef.current) return;
|
|
8527
9341
|
const el = activeStateElRef.current;
|
|
8528
9342
|
if (state === "Default") {
|
|
@@ -8535,18 +9349,22 @@ function OhhwellsBridge() {
|
|
|
8535
9349
|
}
|
|
8536
9350
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
8537
9351
|
}, [deactivate]);
|
|
8538
|
-
const closeLinkPopover = (0,
|
|
8539
|
-
|
|
9352
|
+
const closeLinkPopover = (0, import_react8.useCallback)(() => {
|
|
9353
|
+
addNavAfterAnchorRef.current = null;
|
|
9354
|
+
setLinkPopover(null);
|
|
9355
|
+
}, []);
|
|
9356
|
+
const openLinkPopoverForActive = (0, import_react8.useCallback)(() => {
|
|
8540
9357
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
8541
9358
|
if (!hrefCtx) return;
|
|
8542
9359
|
bumpLinkPopoverGrace();
|
|
8543
9360
|
setLinkPopover({
|
|
8544
9361
|
key: hrefCtx.key,
|
|
8545
|
-
|
|
9362
|
+
mode: "edit",
|
|
9363
|
+
target: getLinkHref2(hrefCtx.anchor)
|
|
8546
9364
|
});
|
|
8547
9365
|
deactivate();
|
|
8548
9366
|
}, [deactivate]);
|
|
8549
|
-
const openLinkPopoverForSelected = (0,
|
|
9367
|
+
const openLinkPopoverForSelected = (0, import_react8.useCallback)(() => {
|
|
8550
9368
|
const anchor = selectedElRef.current;
|
|
8551
9369
|
if (!anchor) return;
|
|
8552
9370
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -8554,30 +9372,70 @@ function OhhwellsBridge() {
|
|
|
8554
9372
|
bumpLinkPopoverGrace();
|
|
8555
9373
|
setLinkPopover({
|
|
8556
9374
|
key,
|
|
8557
|
-
|
|
9375
|
+
mode: "edit",
|
|
9376
|
+
target: getLinkHref2(anchor)
|
|
8558
9377
|
});
|
|
8559
9378
|
deselect();
|
|
8560
9379
|
}, [deselect]);
|
|
8561
|
-
const handleLinkPopoverSubmit = (0,
|
|
9380
|
+
const handleLinkPopoverSubmit = (0, import_react8.useCallback)(
|
|
8562
9381
|
(target) => {
|
|
8563
|
-
|
|
8564
|
-
|
|
9382
|
+
const session = linkPopoverSessionRef.current;
|
|
9383
|
+
if (!session) return;
|
|
9384
|
+
if (session.intent === "add-nav") {
|
|
9385
|
+
const { pageRoute, sectionId } = parseTarget(target);
|
|
9386
|
+
const page = resolvePage(pageRoute, sitePages);
|
|
9387
|
+
const pageSections = getSectionsForPath(sectionsByPath, pageRoute);
|
|
9388
|
+
const section = sectionId ? pageSections.find((s) => s.id === sectionId) : void 0;
|
|
9389
|
+
const label = section?.label ?? page.title;
|
|
9390
|
+
const afterAnchor = addNavAfterAnchorRef.current;
|
|
9391
|
+
const { anchor, hrefKey, labelKey, index, order } = insertNavbarItem(target, label, afterAnchor);
|
|
9392
|
+
applyLinkByKey(hrefKey, target);
|
|
9393
|
+
document.querySelectorAll(`[data-ohw-key="${labelKey}"]`).forEach((el) => {
|
|
9394
|
+
el.textContent = label;
|
|
9395
|
+
});
|
|
9396
|
+
const navCount = String(index + 1);
|
|
9397
|
+
const orderJson = JSON.stringify(order);
|
|
9398
|
+
editContentRef.current = {
|
|
9399
|
+
...editContentRef.current,
|
|
9400
|
+
[hrefKey]: target,
|
|
9401
|
+
[labelKey]: label,
|
|
9402
|
+
[NAV_COUNT_KEY]: navCount,
|
|
9403
|
+
[NAV_ORDER_KEY]: orderJson
|
|
9404
|
+
};
|
|
9405
|
+
postToParent2({
|
|
9406
|
+
type: "ow:change",
|
|
9407
|
+
nodes: [
|
|
9408
|
+
{ key: hrefKey, text: target },
|
|
9409
|
+
{ key: labelKey, text: label },
|
|
9410
|
+
{ key: NAV_COUNT_KEY, text: navCount },
|
|
9411
|
+
{ key: NAV_ORDER_KEY, text: orderJson }
|
|
9412
|
+
]
|
|
9413
|
+
});
|
|
9414
|
+
addNavAfterAnchorRef.current = null;
|
|
9415
|
+
setLinkPopover(null);
|
|
9416
|
+
enforceLinkHrefs();
|
|
9417
|
+
requestAnimationFrame(() => {
|
|
9418
|
+
selectRef.current(anchor);
|
|
9419
|
+
});
|
|
9420
|
+
return;
|
|
9421
|
+
}
|
|
9422
|
+
const { key } = session;
|
|
8565
9423
|
applyLinkByKey(key, target);
|
|
8566
|
-
|
|
9424
|
+
postToParent2({ type: "ow:change", nodes: [{ key, text: target }] });
|
|
8567
9425
|
setLinkPopover(null);
|
|
8568
9426
|
},
|
|
8569
|
-
[
|
|
9427
|
+
[postToParent2, sitePages, sectionsByPath]
|
|
8570
9428
|
);
|
|
8571
9429
|
const showEditLink = toolbarShowEditLink;
|
|
8572
9430
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
8573
9431
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
8574
|
-
const handleMediaReplace = (0,
|
|
9432
|
+
const handleMediaReplace = (0, import_react8.useCallback)(
|
|
8575
9433
|
(key) => {
|
|
8576
|
-
|
|
9434
|
+
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
8577
9435
|
},
|
|
8578
|
-
[
|
|
9436
|
+
[postToParent2, mediaHover?.elementType]
|
|
8579
9437
|
);
|
|
8580
|
-
const handleVideoSettingsChange = (0,
|
|
9438
|
+
const handleVideoSettingsChange = (0, import_react8.useCallback)(
|
|
8581
9439
|
(key, settings) => {
|
|
8582
9440
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8583
9441
|
const video = getVideoEl(el);
|
|
@@ -8585,7 +9443,7 @@ function OhhwellsBridge() {
|
|
|
8585
9443
|
if (typeof settings.autoplay === "boolean") video.autoplay = settings.autoplay;
|
|
8586
9444
|
if (typeof settings.muted === "boolean") video.muted = settings.muted;
|
|
8587
9445
|
syncVideoPlayback(video);
|
|
8588
|
-
|
|
9446
|
+
postToParent2({
|
|
8589
9447
|
type: "ow:change",
|
|
8590
9448
|
nodes: [
|
|
8591
9449
|
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
@@ -8597,9 +9455,9 @@ function OhhwellsBridge() {
|
|
|
8597
9455
|
);
|
|
8598
9456
|
});
|
|
8599
9457
|
},
|
|
8600
|
-
[
|
|
9458
|
+
[postToParent2]
|
|
8601
9459
|
);
|
|
8602
|
-
const handleMediaFadeOutComplete = (0,
|
|
9460
|
+
const handleMediaFadeOutComplete = (0, import_react8.useCallback)((key) => {
|
|
8603
9461
|
setUploadingRects((prev) => {
|
|
8604
9462
|
if (!(key in prev)) return prev;
|
|
8605
9463
|
const next = { ...prev };
|
|
@@ -8607,10 +9465,10 @@ function OhhwellsBridge() {
|
|
|
8607
9465
|
return next;
|
|
8608
9466
|
});
|
|
8609
9467
|
}, []);
|
|
8610
|
-
return bridgeRoot ? (0,
|
|
8611
|
-
/* @__PURE__ */ (0,
|
|
8612
|
-
/* @__PURE__ */ (0,
|
|
8613
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0,
|
|
9468
|
+
return bridgeRoot ? (0, import_react_dom3.createPortal)(
|
|
9469
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
9470
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
9471
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8614
9472
|
MediaOverlay,
|
|
8615
9473
|
{
|
|
8616
9474
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -8621,7 +9479,7 @@ function OhhwellsBridge() {
|
|
|
8621
9479
|
},
|
|
8622
9480
|
`uploading-${key}`
|
|
8623
9481
|
)),
|
|
8624
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0,
|
|
9482
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8625
9483
|
MediaOverlay,
|
|
8626
9484
|
{
|
|
8627
9485
|
hover: mediaHover,
|
|
@@ -8630,9 +9488,17 @@ function OhhwellsBridge() {
|
|
|
8630
9488
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
8631
9489
|
}
|
|
8632
9490
|
),
|
|
8633
|
-
siblingHintRect && !isItemDragging && /* @__PURE__ */ (0,
|
|
8634
|
-
|
|
8635
|
-
|
|
9491
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
9492
|
+
hoveredNavContainerRect && toolbarVariant !== "select-frame" && !linkPopover && !isItemDragging && !siblingHintRect && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
9493
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
9494
|
+
NavbarContainerChrome,
|
|
9495
|
+
{
|
|
9496
|
+
rect: toolbarRect,
|
|
9497
|
+
onAdd: handleAddTopLevelNavItem
|
|
9498
|
+
}
|
|
9499
|
+
),
|
|
9500
|
+
hoveredItemRect && !hoveredNavContainerRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
9501
|
+
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8636
9502
|
ItemInteractionLayer,
|
|
8637
9503
|
{
|
|
8638
9504
|
rect: toolbarRect,
|
|
@@ -8643,18 +9509,19 @@ function OhhwellsBridge() {
|
|
|
8643
9509
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
8644
9510
|
onDragHandleDragStart: handleItemDragStart,
|
|
8645
9511
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
8646
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0,
|
|
9512
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8647
9513
|
ItemActionToolbar,
|
|
8648
9514
|
{
|
|
8649
9515
|
onEditLink: openLinkPopoverForSelected,
|
|
8650
|
-
|
|
8651
|
-
|
|
9516
|
+
addItemDisabled: true,
|
|
9517
|
+
editLinkDisabled: false,
|
|
9518
|
+
moreDisabled: true
|
|
8652
9519
|
}
|
|
8653
9520
|
) : void 0
|
|
8654
9521
|
}
|
|
8655
9522
|
),
|
|
8656
|
-
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0,
|
|
8657
|
-
/* @__PURE__ */ (0,
|
|
9523
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
9524
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8658
9525
|
EditGlowChrome,
|
|
8659
9526
|
{
|
|
8660
9527
|
rect: toolbarRect,
|
|
@@ -8663,7 +9530,7 @@ function OhhwellsBridge() {
|
|
|
8663
9530
|
dragDisabled: reorderDragDisabled
|
|
8664
9531
|
}
|
|
8665
9532
|
),
|
|
8666
|
-
/* @__PURE__ */ (0,
|
|
9533
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8667
9534
|
FloatingToolbar,
|
|
8668
9535
|
{
|
|
8669
9536
|
rect: toolbarRect,
|
|
@@ -8676,7 +9543,7 @@ function OhhwellsBridge() {
|
|
|
8676
9543
|
}
|
|
8677
9544
|
)
|
|
8678
9545
|
] }),
|
|
8679
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
9546
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8680
9547
|
"div",
|
|
8681
9548
|
{
|
|
8682
9549
|
"data-ohw-max-badge": "",
|
|
@@ -8702,7 +9569,7 @@ function OhhwellsBridge() {
|
|
|
8702
9569
|
]
|
|
8703
9570
|
}
|
|
8704
9571
|
),
|
|
8705
|
-
toggleState && /* @__PURE__ */ (0,
|
|
9572
|
+
toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8706
9573
|
StateToggle,
|
|
8707
9574
|
{
|
|
8708
9575
|
rect: toggleState.rect,
|
|
@@ -8711,15 +9578,15 @@ function OhhwellsBridge() {
|
|
|
8711
9578
|
onStateChange: handleStateChange
|
|
8712
9579
|
}
|
|
8713
9580
|
),
|
|
8714
|
-
sectionGap && /* @__PURE__ */ (0,
|
|
9581
|
+
sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8715
9582
|
"div",
|
|
8716
9583
|
{
|
|
8717
9584
|
"data-ohw-section-insert-line": "",
|
|
8718
9585
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8719
9586
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8720
9587
|
children: [
|
|
8721
|
-
/* @__PURE__ */ (0,
|
|
8722
|
-
/* @__PURE__ */ (0,
|
|
9588
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9589
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8723
9590
|
Badge,
|
|
8724
9591
|
{
|
|
8725
9592
|
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",
|
|
@@ -8732,35 +9599,36 @@ function OhhwellsBridge() {
|
|
|
8732
9599
|
children: "Add Section"
|
|
8733
9600
|
}
|
|
8734
9601
|
),
|
|
8735
|
-
/* @__PURE__ */ (0,
|
|
9602
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8736
9603
|
]
|
|
8737
9604
|
}
|
|
8738
9605
|
),
|
|
8739
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0,
|
|
9606
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8740
9607
|
LinkPopover,
|
|
8741
9608
|
{
|
|
8742
9609
|
panelRef: linkPopoverPanelRef,
|
|
8743
9610
|
portalContainer: dialogPortalContainer,
|
|
8744
9611
|
open: true,
|
|
8745
|
-
mode: "edit",
|
|
9612
|
+
mode: linkPopover.mode ?? "edit",
|
|
8746
9613
|
pages: sitePages,
|
|
8747
9614
|
sections: currentSections,
|
|
8748
9615
|
sectionsByPath,
|
|
8749
9616
|
initialTarget: linkPopover.target,
|
|
9617
|
+
existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
|
|
8750
9618
|
onClose: closeLinkPopover,
|
|
8751
9619
|
onSubmit: handleLinkPopoverSubmit
|
|
8752
9620
|
},
|
|
8753
|
-
|
|
9621
|
+
linkPopover.key
|
|
8754
9622
|
) : null,
|
|
8755
|
-
sectionGap && /* @__PURE__ */ (0,
|
|
9623
|
+
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
8756
9624
|
"div",
|
|
8757
9625
|
{
|
|
8758
9626
|
"data-ohw-section-insert-line": "",
|
|
8759
9627
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8760
9628
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8761
9629
|
children: [
|
|
8762
|
-
/* @__PURE__ */ (0,
|
|
8763
|
-
/* @__PURE__ */ (0,
|
|
9630
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
9631
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
8764
9632
|
Badge,
|
|
8765
9633
|
{
|
|
8766
9634
|
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",
|
|
@@ -8773,7 +9641,7 @@ function OhhwellsBridge() {
|
|
|
8773
9641
|
children: "Add Section"
|
|
8774
9642
|
}
|
|
8775
9643
|
),
|
|
8776
|
-
/* @__PURE__ */ (0,
|
|
9644
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8777
9645
|
]
|
|
8778
9646
|
}
|
|
8779
9647
|
)
|