@ohhwells/bridge 0.1.34 → 0.1.36-next.45
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/README.md +12 -0
- package/dist/index.cjs +975 -357
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -2
- package/dist/index.d.ts +46 -2
- package/dist/index.js +969 -362
- package/dist/index.js.map +1 -1
- package/dist/styles.css +282 -18
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/OhhwellsBridge.tsx
|
|
4
|
-
import
|
|
4
|
+
import React8, { useCallback as useCallback3, useEffect as useEffect3, useLayoutEffect as useLayoutEffect2, useRef as useRef3, useState as useState5 } from "react";
|
|
5
5
|
import { createRoot } from "react-dom/client";
|
|
6
6
|
import { flushSync } from "react-dom";
|
|
7
7
|
|
|
@@ -45,12 +45,13 @@ function useLinkHrefGuardian(...deps) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// src/ui/SchedulingWidget.tsx
|
|
48
|
-
import { useEffect, useId, useMemo, useRef, useState as useState2 } from "react";
|
|
48
|
+
import { useCallback, useEffect, useId, useMemo, useRef, useState as useState2 } from "react";
|
|
49
49
|
|
|
50
50
|
// src/ui/EmailCaptureModal.tsx
|
|
51
51
|
import { useState } from "react";
|
|
52
52
|
import { Dialog } from "radix-ui";
|
|
53
53
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
54
|
+
var isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
54
55
|
function Spinner() {
|
|
55
56
|
return /* @__PURE__ */ jsxs(
|
|
56
57
|
"svg",
|
|
@@ -84,12 +85,17 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
84
85
|
const [error, setError] = useState(null);
|
|
85
86
|
const isBook = title === "Confirm your spot";
|
|
86
87
|
const handleSubmit = async () => {
|
|
87
|
-
|
|
88
|
+
const trimmed = email.trim();
|
|
89
|
+
if (!trimmed) return;
|
|
90
|
+
if (!isValidEmail(trimmed)) {
|
|
91
|
+
setError("Please enter a valid email address.");
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
88
94
|
setLoading(true);
|
|
89
95
|
setError(null);
|
|
90
96
|
try {
|
|
91
|
-
await onSubmit(
|
|
92
|
-
setSubmittedEmail(
|
|
97
|
+
await onSubmit(trimmed);
|
|
98
|
+
setSubmittedEmail(trimmed);
|
|
93
99
|
setSuccess(true);
|
|
94
100
|
} catch (e) {
|
|
95
101
|
setError(e instanceof Error ? e.message : "Something went wrong. Please try again.");
|
|
@@ -164,7 +170,10 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
164
170
|
{
|
|
165
171
|
type: "email",
|
|
166
172
|
value: email,
|
|
167
|
-
onChange: (e) =>
|
|
173
|
+
onChange: (e) => {
|
|
174
|
+
setEmail(e.target.value);
|
|
175
|
+
if (error) setError(null);
|
|
176
|
+
},
|
|
168
177
|
onKeyDown: handleKeyDown,
|
|
169
178
|
placeholder: "hello@gmail.com",
|
|
170
179
|
autoFocus: true,
|
|
@@ -221,12 +230,20 @@ function formatClassTime(cls) {
|
|
|
221
230
|
const em = endTotal % 60;
|
|
222
231
|
return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
|
|
223
232
|
}
|
|
233
|
+
function formatBookingLabel(cls) {
|
|
234
|
+
const price = cls.price;
|
|
235
|
+
const isFree = price === null || price === void 0 || `${price}` === "" || `${price}` === "0";
|
|
236
|
+
return isFree ? "Book for free" : `Book for ${cls.currency ?? ""} ${price}`.trim();
|
|
237
|
+
}
|
|
224
238
|
function getBookingsOnDate(cls, date) {
|
|
225
239
|
if (!cls.bookings?.length) return 0;
|
|
226
|
-
const
|
|
240
|
+
const target = new Date(date);
|
|
241
|
+
target.setHours(0, 0, 0, 0);
|
|
227
242
|
return cls.bookings.filter((b) => {
|
|
228
243
|
try {
|
|
229
|
-
|
|
244
|
+
const bookingDate = new Date(b.classDate);
|
|
245
|
+
bookingDate.setHours(0, 0, 0, 0);
|
|
246
|
+
return bookingDate.getTime() === target.getTime();
|
|
230
247
|
} catch {
|
|
231
248
|
return false;
|
|
232
249
|
}
|
|
@@ -530,7 +547,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
530
547
|
if (!cls.id) return;
|
|
531
548
|
onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
|
|
532
549
|
},
|
|
533
|
-
children: isFull ? "Join Waitlist" :
|
|
550
|
+
children: isFull ? "Join Waitlist" : formatBookingLabel(cls)
|
|
534
551
|
}
|
|
535
552
|
)
|
|
536
553
|
] })
|
|
@@ -572,6 +589,17 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
572
589
|
const [isHovered, setIsHovered] = useState2(false);
|
|
573
590
|
const [modalState, setModalState] = useState2(null);
|
|
574
591
|
const switchScheduleIdRef = useRef(null);
|
|
592
|
+
const liveScheduleIdRef = useRef(null);
|
|
593
|
+
const refetchLiveSchedule = useCallback(async () => {
|
|
594
|
+
const id = liveScheduleIdRef.current;
|
|
595
|
+
if (!id) return;
|
|
596
|
+
try {
|
|
597
|
+
const res = await fetch(`${API_URL}/api/schedule/id/${id}`);
|
|
598
|
+
const data = await res.json();
|
|
599
|
+
if (data?.id) setSchedule(data);
|
|
600
|
+
} catch {
|
|
601
|
+
}
|
|
602
|
+
}, []);
|
|
575
603
|
const dates = useMemo(() => {
|
|
576
604
|
const today = /* @__PURE__ */ new Date();
|
|
577
605
|
today.setHours(0, 0, 0, 0);
|
|
@@ -591,6 +619,18 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
591
619
|
}
|
|
592
620
|
}
|
|
593
621
|
}, [schedule, dates]);
|
|
622
|
+
useEffect(() => {
|
|
623
|
+
if (typeof window === "undefined") return;
|
|
624
|
+
const onVisible = () => {
|
|
625
|
+
if (!document.hidden) void refetchLiveSchedule();
|
|
626
|
+
};
|
|
627
|
+
window.addEventListener("focus", refetchLiveSchedule);
|
|
628
|
+
document.addEventListener("visibilitychange", onVisible);
|
|
629
|
+
return () => {
|
|
630
|
+
window.removeEventListener("focus", refetchLiveSchedule);
|
|
631
|
+
document.removeEventListener("visibilitychange", onVisible);
|
|
632
|
+
};
|
|
633
|
+
}, [refetchLiveSchedule]);
|
|
594
634
|
useEffect(() => {
|
|
595
635
|
if (typeof window === "undefined") return;
|
|
596
636
|
const isInEditor = window.self !== window.top;
|
|
@@ -652,7 +692,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
652
692
|
setLoading(false);
|
|
653
693
|
return;
|
|
654
694
|
}
|
|
655
|
-
;
|
|
695
|
+
liveScheduleIdRef.current = effectiveId;
|
|
656
696
|
(async () => {
|
|
657
697
|
try {
|
|
658
698
|
const res = await fetch(`${API_URL}/api/schedule/id/${effectiveId}`);
|
|
@@ -709,18 +749,14 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
709
749
|
const data = await res.json().catch(() => ({}));
|
|
710
750
|
throw new Error(data?.message ?? "Something went wrong. Please try again.");
|
|
711
751
|
}
|
|
752
|
+
await refetchLiveSchedule();
|
|
712
753
|
};
|
|
713
754
|
const handleReplaceSchedule = () => {
|
|
714
755
|
setIsHovered(false);
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
insertAfter
|
|
720
|
-
}, "*");
|
|
721
|
-
} else {
|
|
722
|
-
window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
|
|
723
|
-
}
|
|
756
|
+
window.parent.postMessage(
|
|
757
|
+
{ type: "ow:scheduling-not-connected", insertAfter, currentScheduleId: schedule?.id },
|
|
758
|
+
"*"
|
|
759
|
+
);
|
|
724
760
|
};
|
|
725
761
|
if (!inEditor && !loading && !schedule) return null;
|
|
726
762
|
const sectionId = `scheduling-${insertAfter}`;
|
|
@@ -763,7 +799,19 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
763
799
|
),
|
|
764
800
|
/* @__PURE__ */ jsxs2("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
|
|
765
801
|
/* @__PURE__ */ jsxs2("div", { className: "flex flex-col items-center gap-4", children: [
|
|
766
|
-
/* @__PURE__ */ jsx2(
|
|
802
|
+
/* @__PURE__ */ jsx2(
|
|
803
|
+
"h2",
|
|
804
|
+
{
|
|
805
|
+
className: "font-display text-center m-0 text-(--color-dark,#200C02)",
|
|
806
|
+
style: {
|
|
807
|
+
fontSize: "var(--fs-section-h2, clamp(40px, 4.4vw, 64px))",
|
|
808
|
+
fontWeight: "var(--font-weight-heading, 400)",
|
|
809
|
+
lineHeight: 1.05,
|
|
810
|
+
letterSpacing: "-0.02em"
|
|
811
|
+
},
|
|
812
|
+
children: schedule?.name ?? "Book an appointment"
|
|
813
|
+
}
|
|
814
|
+
),
|
|
767
815
|
schedule?.description && /* @__PURE__ */ jsx2("p", { className: "font-body text-body text-center m-0 text-(--color-accent,#A89B83)", children: schedule.description })
|
|
768
816
|
] }),
|
|
769
817
|
/* @__PURE__ */ jsxs2("div", { className: "w-full flex flex-col items-end gap-3", children: [
|
|
@@ -4202,6 +4250,336 @@ function ToggleGroupItem({
|
|
|
4202
4250
|
);
|
|
4203
4251
|
}
|
|
4204
4252
|
|
|
4253
|
+
// src/ui/drag-handle.tsx
|
|
4254
|
+
import * as React3 from "react";
|
|
4255
|
+
import { GripVertical } from "lucide-react";
|
|
4256
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
4257
|
+
var DragHandle = React3.forwardRef(
|
|
4258
|
+
({ className, type = "button", ...props }, ref) => {
|
|
4259
|
+
return /* @__PURE__ */ jsx5(
|
|
4260
|
+
"button",
|
|
4261
|
+
{
|
|
4262
|
+
ref,
|
|
4263
|
+
type,
|
|
4264
|
+
"data-slot": "drag-handle",
|
|
4265
|
+
className: cn(
|
|
4266
|
+
"inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-[30px]",
|
|
4267
|
+
"bg-white border border-transparent text-stone-500 shadow-md cursor-grab",
|
|
4268
|
+
"enabled:hover:border enabled:hover:border-stone-200 enabled:hover:text-stone-950",
|
|
4269
|
+
"enabled:active:border enabled:active:border-primary enabled:active:bg-primary-50 enabled:active:text-stone-950 enabled:active:shadow enabled:active:cursor-grabbing",
|
|
4270
|
+
"disabled:cursor-not-allowed disabled:opacity-40 disabled:text-stone-950 disabled:pointer-events-none",
|
|
4271
|
+
className
|
|
4272
|
+
),
|
|
4273
|
+
...props,
|
|
4274
|
+
children: /* @__PURE__ */ jsx5(GripVertical, { className: "size-4 shrink-0", "aria-hidden": "true" })
|
|
4275
|
+
}
|
|
4276
|
+
);
|
|
4277
|
+
}
|
|
4278
|
+
);
|
|
4279
|
+
DragHandle.displayName = "DragHandle";
|
|
4280
|
+
|
|
4281
|
+
// src/ui/custom-toolbar.tsx
|
|
4282
|
+
import * as React4 from "react";
|
|
4283
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
4284
|
+
var CustomToolbar = React4.forwardRef(({ className, onMouseDown, ...props }, ref) => /* @__PURE__ */ jsx6(
|
|
4285
|
+
"div",
|
|
4286
|
+
{
|
|
4287
|
+
ref,
|
|
4288
|
+
"data-ohw-toolbar": "",
|
|
4289
|
+
className: cn(
|
|
4290
|
+
"inline-flex items-center gap-1 rounded-lg border border-border bg-background p-0.5 font-sans whitespace-nowrap shadow-[0px_2px_4px_-2px_rgba(0,0,0,0.1),0px_4px_6px_-1px_rgba(0,0,0,0.1)]",
|
|
4291
|
+
className
|
|
4292
|
+
),
|
|
4293
|
+
onMouseDown: (e) => {
|
|
4294
|
+
e.stopPropagation();
|
|
4295
|
+
onMouseDown?.(e);
|
|
4296
|
+
},
|
|
4297
|
+
...props
|
|
4298
|
+
}
|
|
4299
|
+
));
|
|
4300
|
+
CustomToolbar.displayName = "CustomToolbar";
|
|
4301
|
+
function CustomToolbarDivider({ className, ...props }) {
|
|
4302
|
+
return /* @__PURE__ */ jsx6(
|
|
4303
|
+
"span",
|
|
4304
|
+
{
|
|
4305
|
+
"aria-hidden": true,
|
|
4306
|
+
className: cn("block h-6 w-px shrink-0 bg-border", className),
|
|
4307
|
+
...props
|
|
4308
|
+
}
|
|
4309
|
+
);
|
|
4310
|
+
}
|
|
4311
|
+
var CustomToolbarButton = React4.forwardRef(
|
|
4312
|
+
({ className, active = false, type = "button", ...props }, ref) => /* @__PURE__ */ jsx6(
|
|
4313
|
+
"button",
|
|
4314
|
+
{
|
|
4315
|
+
ref,
|
|
4316
|
+
type,
|
|
4317
|
+
className: cn(
|
|
4318
|
+
"inline-flex shrink-0 items-center justify-center rounded p-1.5 transition-colors",
|
|
4319
|
+
active ? "bg-primary text-primary-foreground" : "bg-transparent text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
4320
|
+
className
|
|
4321
|
+
),
|
|
4322
|
+
...props
|
|
4323
|
+
}
|
|
4324
|
+
)
|
|
4325
|
+
);
|
|
4326
|
+
CustomToolbarButton.displayName = "CustomToolbarButton";
|
|
4327
|
+
|
|
4328
|
+
// src/ui/item-action-toolbar.tsx
|
|
4329
|
+
import { Link, MoreHorizontal, Plus } from "lucide-react";
|
|
4330
|
+
|
|
4331
|
+
// src/ui/tooltip.tsx
|
|
4332
|
+
import { Tooltip as TooltipPrimitive } from "radix-ui";
|
|
4333
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
4334
|
+
function TooltipProvider({
|
|
4335
|
+
delayDuration = 0,
|
|
4336
|
+
...props
|
|
4337
|
+
}) {
|
|
4338
|
+
return /* @__PURE__ */ jsx7(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delayDuration, ...props });
|
|
4339
|
+
}
|
|
4340
|
+
function Tooltip({ ...props }) {
|
|
4341
|
+
return /* @__PURE__ */ jsx7(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props });
|
|
4342
|
+
}
|
|
4343
|
+
function TooltipTrigger({ ...props }) {
|
|
4344
|
+
return /* @__PURE__ */ jsx7(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
4345
|
+
}
|
|
4346
|
+
var arrowClassBySide = {
|
|
4347
|
+
top: "before:bottom-0 before:left-1/2 before:-translate-x-1/2 before:translate-y-1/2",
|
|
4348
|
+
bottom: "before:top-0 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2",
|
|
4349
|
+
left: "before:right-0 before:top-1/2 before:-translate-y-1/2 before:translate-x-1/2",
|
|
4350
|
+
right: "before:left-0 before:top-1/2 before:-translate-y-1/2 before:-translate-x-1/2"
|
|
4351
|
+
};
|
|
4352
|
+
function TooltipContent({
|
|
4353
|
+
className,
|
|
4354
|
+
sideOffset = 6,
|
|
4355
|
+
side = "bottom",
|
|
4356
|
+
children,
|
|
4357
|
+
...props
|
|
4358
|
+
}) {
|
|
4359
|
+
const resolvedSide = side ?? "bottom";
|
|
4360
|
+
return /* @__PURE__ */ jsx7(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx7(
|
|
4361
|
+
TooltipPrimitive.Content,
|
|
4362
|
+
{
|
|
4363
|
+
"data-slot": "tooltip-content",
|
|
4364
|
+
side,
|
|
4365
|
+
sideOffset,
|
|
4366
|
+
className: cn(
|
|
4367
|
+
"relative z-[2147483647] w-fit max-w-xs rounded-md bg-foreground px-3 py-1.5 text-xs text-background shadow-md",
|
|
4368
|
+
'before:pointer-events-none before:absolute before:size-2 before:rotate-45 before:bg-foreground before:content-[""]',
|
|
4369
|
+
arrowClassBySide[resolvedSide],
|
|
4370
|
+
"animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
4371
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
|
|
4372
|
+
"data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2",
|
|
4373
|
+
className
|
|
4374
|
+
),
|
|
4375
|
+
...props,
|
|
4376
|
+
children
|
|
4377
|
+
}
|
|
4378
|
+
) });
|
|
4379
|
+
}
|
|
4380
|
+
|
|
4381
|
+
// src/ui/item-action-toolbar.tsx
|
|
4382
|
+
import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
4383
|
+
function ToolbarActionTooltip({
|
|
4384
|
+
label,
|
|
4385
|
+
side = "bottom",
|
|
4386
|
+
disabled = false,
|
|
4387
|
+
buttonProps,
|
|
4388
|
+
children
|
|
4389
|
+
}) {
|
|
4390
|
+
const button = /* @__PURE__ */ jsx8(CustomToolbarButton, { type: "button", "aria-label": label, disabled, ...buttonProps, children });
|
|
4391
|
+
return /* @__PURE__ */ jsxs3(Tooltip, { children: [
|
|
4392
|
+
/* @__PURE__ */ jsx8(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ jsx8("span", { className: "inline-flex", children: button }) : button }),
|
|
4393
|
+
/* @__PURE__ */ jsx8(TooltipContent, { side, children: label })
|
|
4394
|
+
] });
|
|
4395
|
+
}
|
|
4396
|
+
function ItemActionToolbar({
|
|
4397
|
+
onEditLink,
|
|
4398
|
+
onAddItem,
|
|
4399
|
+
onMore,
|
|
4400
|
+
addItemDisabled = true,
|
|
4401
|
+
moreDisabled = true,
|
|
4402
|
+
tooltipSide = "bottom"
|
|
4403
|
+
}) {
|
|
4404
|
+
return /* @__PURE__ */ jsx8(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsxs3(CustomToolbar, { children: [
|
|
4405
|
+
/* @__PURE__ */ jsx8(
|
|
4406
|
+
ToolbarActionTooltip,
|
|
4407
|
+
{
|
|
4408
|
+
label: "Add link",
|
|
4409
|
+
side: tooltipSide,
|
|
4410
|
+
buttonProps: {
|
|
4411
|
+
onMouseDown: (e) => {
|
|
4412
|
+
e.preventDefault();
|
|
4413
|
+
e.stopPropagation();
|
|
4414
|
+
onEditLink?.();
|
|
4415
|
+
},
|
|
4416
|
+
onClick: (e) => {
|
|
4417
|
+
e.preventDefault();
|
|
4418
|
+
e.stopPropagation();
|
|
4419
|
+
}
|
|
4420
|
+
},
|
|
4421
|
+
children: /* @__PURE__ */ jsx8(Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4422
|
+
}
|
|
4423
|
+
),
|
|
4424
|
+
/* @__PURE__ */ jsx8(CustomToolbarDivider, {}),
|
|
4425
|
+
/* @__PURE__ */ jsx8(
|
|
4426
|
+
ToolbarActionTooltip,
|
|
4427
|
+
{
|
|
4428
|
+
label: "Add item",
|
|
4429
|
+
side: tooltipSide,
|
|
4430
|
+
disabled: addItemDisabled,
|
|
4431
|
+
buttonProps: {
|
|
4432
|
+
onMouseDown: (e) => {
|
|
4433
|
+
if (addItemDisabled) return;
|
|
4434
|
+
e.preventDefault();
|
|
4435
|
+
e.stopPropagation();
|
|
4436
|
+
onAddItem?.();
|
|
4437
|
+
}
|
|
4438
|
+
},
|
|
4439
|
+
children: /* @__PURE__ */ jsx8(Plus, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4440
|
+
}
|
|
4441
|
+
),
|
|
4442
|
+
/* @__PURE__ */ jsx8(CustomToolbarDivider, {}),
|
|
4443
|
+
/* @__PURE__ */ jsx8(
|
|
4444
|
+
ToolbarActionTooltip,
|
|
4445
|
+
{
|
|
4446
|
+
label: "More",
|
|
4447
|
+
side: tooltipSide,
|
|
4448
|
+
disabled: moreDisabled,
|
|
4449
|
+
buttonProps: {
|
|
4450
|
+
onMouseDown: (e) => {
|
|
4451
|
+
if (moreDisabled) return;
|
|
4452
|
+
e.preventDefault();
|
|
4453
|
+
e.stopPropagation();
|
|
4454
|
+
onMore?.();
|
|
4455
|
+
}
|
|
4456
|
+
},
|
|
4457
|
+
children: /* @__PURE__ */ jsx8(MoreHorizontal, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4458
|
+
}
|
|
4459
|
+
)
|
|
4460
|
+
] }) });
|
|
4461
|
+
}
|
|
4462
|
+
|
|
4463
|
+
// src/ui/item-interaction-layer.tsx
|
|
4464
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
4465
|
+
var PRIMARY = "var(--ohw-primary, #0885FE)";
|
|
4466
|
+
var FOCUS_RING = "0 0 0 4px rgba(8, 133, 254, 0.12)";
|
|
4467
|
+
var DRAG_SHADOW = "0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.1)";
|
|
4468
|
+
function getChromeStyle(state) {
|
|
4469
|
+
switch (state) {
|
|
4470
|
+
case "hover":
|
|
4471
|
+
return {
|
|
4472
|
+
border: `1.5px dashed ${PRIMARY}`,
|
|
4473
|
+
boxShadow: "none"
|
|
4474
|
+
};
|
|
4475
|
+
case "sibling-hint":
|
|
4476
|
+
return {
|
|
4477
|
+
border: `1.5px dashed color-mix(in srgb, ${PRIMARY} 30%, transparent)`,
|
|
4478
|
+
boxShadow: "none"
|
|
4479
|
+
};
|
|
4480
|
+
case "active-top":
|
|
4481
|
+
case "active-bottom":
|
|
4482
|
+
return {
|
|
4483
|
+
border: `2px solid ${PRIMARY}`,
|
|
4484
|
+
boxShadow: FOCUS_RING
|
|
4485
|
+
};
|
|
4486
|
+
case "dragging":
|
|
4487
|
+
return {
|
|
4488
|
+
border: `2px solid ${PRIMARY}`,
|
|
4489
|
+
boxShadow: DRAG_SHADOW
|
|
4490
|
+
};
|
|
4491
|
+
default:
|
|
4492
|
+
return {};
|
|
4493
|
+
}
|
|
4494
|
+
}
|
|
4495
|
+
function ItemInteractionLayer({
|
|
4496
|
+
rect,
|
|
4497
|
+
state,
|
|
4498
|
+
elRef,
|
|
4499
|
+
toolbar,
|
|
4500
|
+
showHandle = false,
|
|
4501
|
+
dragDisabled = false,
|
|
4502
|
+
dragHandleLabel = "Reorder item",
|
|
4503
|
+
onDragHandleDragStart,
|
|
4504
|
+
onDragHandleDragEnd,
|
|
4505
|
+
chromeGap = 6,
|
|
4506
|
+
className
|
|
4507
|
+
}) {
|
|
4508
|
+
if (state === "default") return null;
|
|
4509
|
+
const isActive = state === "active-top" || state === "active-bottom";
|
|
4510
|
+
const isDragging = state === "dragging";
|
|
4511
|
+
const showToolbar = isActive && toolbar;
|
|
4512
|
+
const showDragHandle = isActive && showHandle && !isDragging;
|
|
4513
|
+
return /* @__PURE__ */ jsxs4(
|
|
4514
|
+
"div",
|
|
4515
|
+
{
|
|
4516
|
+
ref: elRef,
|
|
4517
|
+
"data-ohw-item-interaction": "",
|
|
4518
|
+
"data-ohw-item-interaction-state": state,
|
|
4519
|
+
className: cn("pointer-events-none", className),
|
|
4520
|
+
style: {
|
|
4521
|
+
position: "fixed",
|
|
4522
|
+
top: rect.top - chromeGap,
|
|
4523
|
+
left: rect.left - chromeGap,
|
|
4524
|
+
width: rect.width + chromeGap * 2,
|
|
4525
|
+
height: rect.height + chromeGap * 2,
|
|
4526
|
+
zIndex: 2147483646
|
|
4527
|
+
},
|
|
4528
|
+
children: [
|
|
4529
|
+
/* @__PURE__ */ jsx9(
|
|
4530
|
+
"div",
|
|
4531
|
+
{
|
|
4532
|
+
"aria-hidden": true,
|
|
4533
|
+
className: "absolute inset-0 rounded-lg",
|
|
4534
|
+
style: getChromeStyle(state)
|
|
4535
|
+
}
|
|
4536
|
+
),
|
|
4537
|
+
showDragHandle && /* @__PURE__ */ jsx9(
|
|
4538
|
+
"div",
|
|
4539
|
+
{
|
|
4540
|
+
"data-ohw-drag-handle-container": "",
|
|
4541
|
+
className: "pointer-events-auto absolute left-0 top-1/2 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4542
|
+
children: /* @__PURE__ */ jsx9(
|
|
4543
|
+
DragHandle,
|
|
4544
|
+
{
|
|
4545
|
+
draggable: !dragDisabled,
|
|
4546
|
+
"aria-label": dragHandleLabel,
|
|
4547
|
+
disabled: dragDisabled,
|
|
4548
|
+
onDragStart: (e) => {
|
|
4549
|
+
if (dragDisabled) {
|
|
4550
|
+
e.preventDefault();
|
|
4551
|
+
return;
|
|
4552
|
+
}
|
|
4553
|
+
e.dataTransfer?.setData("text/plain", dragHandleLabel);
|
|
4554
|
+
e.dataTransfer.effectAllowed = "move";
|
|
4555
|
+
onDragHandleDragStart?.(e);
|
|
4556
|
+
},
|
|
4557
|
+
onDragEnd: onDragHandleDragEnd
|
|
4558
|
+
}
|
|
4559
|
+
)
|
|
4560
|
+
}
|
|
4561
|
+
),
|
|
4562
|
+
showToolbar && state === "active-top" && /* @__PURE__ */ jsx9(
|
|
4563
|
+
"div",
|
|
4564
|
+
{
|
|
4565
|
+
className: "pointer-events-auto absolute bottom-full left-1/2 mb-2 -translate-x-1/2",
|
|
4566
|
+
"data-ohw-item-toolbar-anchor": "top",
|
|
4567
|
+
children: toolbar
|
|
4568
|
+
}
|
|
4569
|
+
),
|
|
4570
|
+
showToolbar && state === "active-bottom" && /* @__PURE__ */ jsx9(
|
|
4571
|
+
"div",
|
|
4572
|
+
{
|
|
4573
|
+
className: "pointer-events-auto absolute left-1/2 top-full mt-2 -translate-x-1/2",
|
|
4574
|
+
"data-ohw-item-toolbar-anchor": "bottom",
|
|
4575
|
+
children: toolbar
|
|
4576
|
+
}
|
|
4577
|
+
)
|
|
4578
|
+
]
|
|
4579
|
+
}
|
|
4580
|
+
);
|
|
4581
|
+
}
|
|
4582
|
+
|
|
4205
4583
|
// src/OhhwellsBridge.tsx
|
|
4206
4584
|
import { createPortal } from "react-dom";
|
|
4207
4585
|
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
|
@@ -4481,60 +4859,60 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
4481
4859
|
}
|
|
4482
4860
|
|
|
4483
4861
|
// src/ui/dialog.tsx
|
|
4484
|
-
import * as
|
|
4862
|
+
import * as React5 from "react";
|
|
4485
4863
|
import { Dialog as DialogPrimitive } from "radix-ui";
|
|
4486
4864
|
|
|
4487
4865
|
// src/ui/icons.tsx
|
|
4488
|
-
import { jsx as
|
|
4866
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
4489
4867
|
function IconX({ className, ...props }) {
|
|
4490
|
-
return /* @__PURE__ */
|
|
4491
|
-
/* @__PURE__ */
|
|
4492
|
-
/* @__PURE__ */
|
|
4868
|
+
return /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4869
|
+
/* @__PURE__ */ jsx10("path", { d: "M18 6 6 18" }),
|
|
4870
|
+
/* @__PURE__ */ jsx10("path", { d: "m6 6 12 12" })
|
|
4493
4871
|
] });
|
|
4494
4872
|
}
|
|
4495
4873
|
function IconChevronDown({ className, ...props }) {
|
|
4496
|
-
return /* @__PURE__ */
|
|
4874
|
+
return /* @__PURE__ */ jsx10("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ jsx10("path", { d: "m6 9 6 6 6-6" }) });
|
|
4497
4875
|
}
|
|
4498
4876
|
function IconFile({ className, ...props }) {
|
|
4499
|
-
return /* @__PURE__ */
|
|
4500
|
-
/* @__PURE__ */
|
|
4501
|
-
/* @__PURE__ */
|
|
4877
|
+
return /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4878
|
+
/* @__PURE__ */ jsx10("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
4879
|
+
/* @__PURE__ */ jsx10("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
4502
4880
|
] });
|
|
4503
4881
|
}
|
|
4504
4882
|
function IconInfo({ className, ...props }) {
|
|
4505
|
-
return /* @__PURE__ */
|
|
4506
|
-
/* @__PURE__ */
|
|
4507
|
-
/* @__PURE__ */
|
|
4508
|
-
/* @__PURE__ */
|
|
4883
|
+
return /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4884
|
+
/* @__PURE__ */ jsx10("circle", { cx: "12", cy: "12", r: "10" }),
|
|
4885
|
+
/* @__PURE__ */ jsx10("path", { d: "M12 16v-4" }),
|
|
4886
|
+
/* @__PURE__ */ jsx10("path", { d: "M12 8h.01" })
|
|
4509
4887
|
] });
|
|
4510
4888
|
}
|
|
4511
4889
|
function IconArrowRight({ className, ...props }) {
|
|
4512
|
-
return /* @__PURE__ */
|
|
4513
|
-
/* @__PURE__ */
|
|
4514
|
-
/* @__PURE__ */
|
|
4890
|
+
return /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4891
|
+
/* @__PURE__ */ jsx10("path", { d: "M5 12h14" }),
|
|
4892
|
+
/* @__PURE__ */ jsx10("path", { d: "m12 5 7 7-7 7" })
|
|
4515
4893
|
] });
|
|
4516
4894
|
}
|
|
4517
4895
|
function IconSection({ className, ...props }) {
|
|
4518
|
-
return /* @__PURE__ */
|
|
4519
|
-
/* @__PURE__ */
|
|
4520
|
-
/* @__PURE__ */
|
|
4521
|
-
/* @__PURE__ */
|
|
4896
|
+
return /* @__PURE__ */ jsxs5("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4897
|
+
/* @__PURE__ */ jsx10("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
4898
|
+
/* @__PURE__ */ jsx10("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
4899
|
+
/* @__PURE__ */ jsx10("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
4522
4900
|
] });
|
|
4523
4901
|
}
|
|
4524
4902
|
|
|
4525
4903
|
// src/ui/dialog.tsx
|
|
4526
|
-
import { jsx as
|
|
4904
|
+
import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
4527
4905
|
function Dialog2({ ...props }) {
|
|
4528
|
-
return /* @__PURE__ */
|
|
4906
|
+
return /* @__PURE__ */ jsx11(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
|
|
4529
4907
|
}
|
|
4530
4908
|
function DialogPortal({ ...props }) {
|
|
4531
|
-
return /* @__PURE__ */
|
|
4909
|
+
return /* @__PURE__ */ jsx11(DialogPrimitive.Portal, { ...props });
|
|
4532
4910
|
}
|
|
4533
4911
|
function DialogOverlay({
|
|
4534
4912
|
className,
|
|
4535
4913
|
...props
|
|
4536
4914
|
}) {
|
|
4537
|
-
return /* @__PURE__ */
|
|
4915
|
+
return /* @__PURE__ */ jsx11(
|
|
4538
4916
|
DialogPrimitive.Overlay,
|
|
4539
4917
|
{
|
|
4540
4918
|
"data-slot": "dialog-overlay",
|
|
@@ -4544,11 +4922,11 @@ function DialogOverlay({
|
|
|
4544
4922
|
}
|
|
4545
4923
|
);
|
|
4546
4924
|
}
|
|
4547
|
-
var DialogContent =
|
|
4925
|
+
var DialogContent = React5.forwardRef(({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
4548
4926
|
const positionMode = container ? "absolute" : "fixed";
|
|
4549
|
-
return /* @__PURE__ */
|
|
4550
|
-
/* @__PURE__ */
|
|
4551
|
-
/* @__PURE__ */
|
|
4927
|
+
return /* @__PURE__ */ jsxs6(DialogPortal, { container: container ?? void 0, children: [
|
|
4928
|
+
/* @__PURE__ */ jsx11(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
4929
|
+
/* @__PURE__ */ jsxs6(
|
|
4552
4930
|
DialogPrimitive.Content,
|
|
4553
4931
|
{
|
|
4554
4932
|
ref,
|
|
@@ -4564,13 +4942,13 @@ var DialogContent = React3.forwardRef(({ className, children, showCloseButton =
|
|
|
4564
4942
|
...props,
|
|
4565
4943
|
children: [
|
|
4566
4944
|
children,
|
|
4567
|
-
showCloseButton ? /* @__PURE__ */
|
|
4945
|
+
showCloseButton ? /* @__PURE__ */ jsx11(
|
|
4568
4946
|
DialogPrimitive.Close,
|
|
4569
4947
|
{
|
|
4570
4948
|
type: "button",
|
|
4571
4949
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
4572
4950
|
"aria-label": "Close",
|
|
4573
|
-
children: /* @__PURE__ */
|
|
4951
|
+
children: /* @__PURE__ */ jsx11(IconX, { "aria-hidden": true })
|
|
4574
4952
|
}
|
|
4575
4953
|
) : null
|
|
4576
4954
|
]
|
|
@@ -4580,12 +4958,12 @@ var DialogContent = React3.forwardRef(({ className, children, showCloseButton =
|
|
|
4580
4958
|
});
|
|
4581
4959
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
4582
4960
|
function DialogHeader({ className, ...props }) {
|
|
4583
|
-
return /* @__PURE__ */
|
|
4961
|
+
return /* @__PURE__ */ jsx11("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
4584
4962
|
}
|
|
4585
4963
|
function DialogFooter({ className, ...props }) {
|
|
4586
|
-
return /* @__PURE__ */
|
|
4964
|
+
return /* @__PURE__ */ jsx11("div", { className: cn("flex items-center justify-end gap-2", className), ...props });
|
|
4587
4965
|
}
|
|
4588
|
-
var DialogTitle =
|
|
4966
|
+
var DialogTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
|
|
4589
4967
|
DialogPrimitive.Title,
|
|
4590
4968
|
{
|
|
4591
4969
|
ref,
|
|
@@ -4594,7 +4972,7 @@ var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
4594
4972
|
}
|
|
4595
4973
|
));
|
|
4596
4974
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
4597
|
-
var DialogDescription =
|
|
4975
|
+
var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
|
|
4598
4976
|
DialogPrimitive.Description,
|
|
4599
4977
|
{
|
|
4600
4978
|
ref,
|
|
@@ -4606,9 +4984,9 @@ DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
|
4606
4984
|
var DialogClose = DialogPrimitive.Close;
|
|
4607
4985
|
|
|
4608
4986
|
// src/ui/button.tsx
|
|
4609
|
-
import * as
|
|
4987
|
+
import * as React6 from "react";
|
|
4610
4988
|
import { Slot } from "radix-ui";
|
|
4611
|
-
import { jsx as
|
|
4989
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
4612
4990
|
var buttonVariants = cva(
|
|
4613
4991
|
"inline-flex items-center justify-center gap-1 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none disabled:pointer-events-none disabled:opacity-50 min-w-[80px] px-3 py-2",
|
|
4614
4992
|
{
|
|
@@ -4629,10 +5007,10 @@ var buttonVariants = cva(
|
|
|
4629
5007
|
}
|
|
4630
5008
|
}
|
|
4631
5009
|
);
|
|
4632
|
-
var Button =
|
|
5010
|
+
var Button = React6.forwardRef(
|
|
4633
5011
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
4634
5012
|
const Comp = asChild ? Slot.Root : "button";
|
|
4635
|
-
return /* @__PURE__ */
|
|
5013
|
+
return /* @__PURE__ */ jsx12(
|
|
4636
5014
|
Comp,
|
|
4637
5015
|
{
|
|
4638
5016
|
ref,
|
|
@@ -4646,37 +5024,37 @@ var Button = React4.forwardRef(
|
|
|
4646
5024
|
Button.displayName = "Button";
|
|
4647
5025
|
|
|
4648
5026
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
4649
|
-
import { jsx as
|
|
5027
|
+
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
4650
5028
|
function DestinationBreadcrumb({ pageTitle, sectionLabel }) {
|
|
4651
|
-
return /* @__PURE__ */
|
|
4652
|
-
/* @__PURE__ */
|
|
4653
|
-
/* @__PURE__ */
|
|
4654
|
-
/* @__PURE__ */
|
|
4655
|
-
/* @__PURE__ */
|
|
4656
|
-
/* @__PURE__ */
|
|
5029
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5030
|
+
/* @__PURE__ */ jsx13("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
|
|
5031
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3", children: [
|
|
5032
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
5033
|
+
/* @__PURE__ */ jsx13(IconFile, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5034
|
+
/* @__PURE__ */ jsx13("span", { className: "text-sm font-medium leading-none text-foreground", children: pageTitle })
|
|
4657
5035
|
] }),
|
|
4658
|
-
/* @__PURE__ */
|
|
4659
|
-
/* @__PURE__ */
|
|
4660
|
-
/* @__PURE__ */
|
|
4661
|
-
/* @__PURE__ */
|
|
5036
|
+
/* @__PURE__ */ jsx13(IconArrowRight, { className: "shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
5037
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5038
|
+
/* @__PURE__ */ jsx13(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5039
|
+
/* @__PURE__ */ jsx13("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
4662
5040
|
] })
|
|
4663
5041
|
] })
|
|
4664
5042
|
] });
|
|
4665
5043
|
}
|
|
4666
5044
|
|
|
4667
5045
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
4668
|
-
import { jsx as
|
|
5046
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
4669
5047
|
function SectionTreeItem({ section, onSelect, selected }) {
|
|
4670
5048
|
const interactive = Boolean(onSelect);
|
|
4671
|
-
return /* @__PURE__ */
|
|
4672
|
-
/* @__PURE__ */
|
|
5049
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5050
|
+
/* @__PURE__ */ jsx14(
|
|
4673
5051
|
"div",
|
|
4674
5052
|
{
|
|
4675
5053
|
className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
4676
5054
|
"aria-hidden": true
|
|
4677
5055
|
}
|
|
4678
5056
|
),
|
|
4679
|
-
/* @__PURE__ */
|
|
5057
|
+
/* @__PURE__ */ jsxs8(
|
|
4680
5058
|
"div",
|
|
4681
5059
|
{
|
|
4682
5060
|
role: interactive ? "button" : void 0,
|
|
@@ -4694,8 +5072,8 @@ function SectionTreeItem({ section, onSelect, selected }) {
|
|
|
4694
5072
|
interactive && selected && "border-primary"
|
|
4695
5073
|
),
|
|
4696
5074
|
children: [
|
|
4697
|
-
/* @__PURE__ */
|
|
4698
|
-
/* @__PURE__ */
|
|
5075
|
+
/* @__PURE__ */ jsx14(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5076
|
+
/* @__PURE__ */ jsx14("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
4699
5077
|
]
|
|
4700
5078
|
}
|
|
4701
5079
|
)
|
|
@@ -4703,11 +5081,11 @@ function SectionTreeItem({ section, onSelect, selected }) {
|
|
|
4703
5081
|
}
|
|
4704
5082
|
function SectionPickerList({ sections, onSelect }) {
|
|
4705
5083
|
if (sections.length === 0) {
|
|
4706
|
-
return /* @__PURE__ */
|
|
5084
|
+
return /* @__PURE__ */ jsx14("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
|
|
4707
5085
|
}
|
|
4708
|
-
return /* @__PURE__ */
|
|
4709
|
-
/* @__PURE__ */
|
|
4710
|
-
sections.map((section) => /* @__PURE__ */
|
|
5086
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-1", children: [
|
|
5087
|
+
/* @__PURE__ */ jsx14("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
|
|
5088
|
+
sections.map((section) => /* @__PURE__ */ jsx14(SectionTreeItem, { section, onSelect }, section.id))
|
|
4711
5089
|
] });
|
|
4712
5090
|
}
|
|
4713
5091
|
|
|
@@ -4715,11 +5093,11 @@ function SectionPickerList({ sections, onSelect }) {
|
|
|
4715
5093
|
import { useId as useId2, useRef as useRef2, useState as useState3 } from "react";
|
|
4716
5094
|
|
|
4717
5095
|
// src/ui/input.tsx
|
|
4718
|
-
import * as
|
|
4719
|
-
import { jsx as
|
|
4720
|
-
var Input =
|
|
5096
|
+
import * as React7 from "react";
|
|
5097
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
5098
|
+
var Input = React7.forwardRef(
|
|
4721
5099
|
({ className, type, ...props }, ref) => {
|
|
4722
|
-
return /* @__PURE__ */
|
|
5100
|
+
return /* @__PURE__ */ jsx15(
|
|
4723
5101
|
"input",
|
|
4724
5102
|
{
|
|
4725
5103
|
type,
|
|
@@ -4738,9 +5116,9 @@ Input.displayName = "Input";
|
|
|
4738
5116
|
|
|
4739
5117
|
// src/ui/label.tsx
|
|
4740
5118
|
import { Label as LabelPrimitive } from "radix-ui";
|
|
4741
|
-
import { jsx as
|
|
5119
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
4742
5120
|
function Label({ className, ...props }) {
|
|
4743
|
-
return /* @__PURE__ */
|
|
5121
|
+
return /* @__PURE__ */ jsx16(
|
|
4744
5122
|
LabelPrimitive.Root,
|
|
4745
5123
|
{
|
|
4746
5124
|
"data-slot": "label",
|
|
@@ -4751,9 +5129,9 @@ function Label({ className, ...props }) {
|
|
|
4751
5129
|
}
|
|
4752
5130
|
|
|
4753
5131
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
4754
|
-
import { jsx as
|
|
5132
|
+
import { jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4755
5133
|
function FieldChevron({ onClick }) {
|
|
4756
|
-
return /* @__PURE__ */
|
|
5134
|
+
return /* @__PURE__ */ jsx17(
|
|
4757
5135
|
"button",
|
|
4758
5136
|
{
|
|
4759
5137
|
type: "button",
|
|
@@ -4761,7 +5139,7 @@ function FieldChevron({ onClick }) {
|
|
|
4761
5139
|
onClick,
|
|
4762
5140
|
"aria-label": "Open page list",
|
|
4763
5141
|
tabIndex: -1,
|
|
4764
|
-
children: /* @__PURE__ */
|
|
5142
|
+
children: /* @__PURE__ */ jsx17(IconChevronDown, {})
|
|
4765
5143
|
}
|
|
4766
5144
|
);
|
|
4767
5145
|
}
|
|
@@ -4800,12 +5178,12 @@ function UrlOrPageInput({
|
|
|
4800
5178
|
"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]",
|
|
4801
5179
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
4802
5180
|
);
|
|
4803
|
-
return /* @__PURE__ */
|
|
4804
|
-
/* @__PURE__ */
|
|
4805
|
-
/* @__PURE__ */
|
|
4806
|
-
/* @__PURE__ */
|
|
4807
|
-
selectedPage ? /* @__PURE__ */
|
|
4808
|
-
readOnly ? /* @__PURE__ */
|
|
5181
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5182
|
+
/* @__PURE__ */ jsx17(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5183
|
+
/* @__PURE__ */ jsxs9("div", { className: "relative w-full", children: [
|
|
5184
|
+
/* @__PURE__ */ jsxs9("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5185
|
+
selectedPage ? /* @__PURE__ */ jsx17("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ jsx17(IconFile, { className: "text-foreground", "aria-hidden": true }) }) : null,
|
|
5186
|
+
readOnly ? /* @__PURE__ */ jsx17("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ jsx17(
|
|
4809
5187
|
Input,
|
|
4810
5188
|
{
|
|
4811
5189
|
ref: inputRef,
|
|
@@ -4824,7 +5202,7 @@ function UrlOrPageInput({
|
|
|
4824
5202
|
)
|
|
4825
5203
|
}
|
|
4826
5204
|
),
|
|
4827
|
-
selectedPage && !readOnly ? /* @__PURE__ */
|
|
5205
|
+
selectedPage && !readOnly ? /* @__PURE__ */ jsx17(
|
|
4828
5206
|
"button",
|
|
4829
5207
|
{
|
|
4830
5208
|
type: "button",
|
|
@@ -4832,26 +5210,26 @@ function UrlOrPageInput({
|
|
|
4832
5210
|
onMouseDown: clearSelection,
|
|
4833
5211
|
"aria-label": "Clear selected page",
|
|
4834
5212
|
tabIndex: -1,
|
|
4835
|
-
children: /* @__PURE__ */
|
|
5213
|
+
children: /* @__PURE__ */ jsx17(IconX, { "aria-hidden": true })
|
|
4836
5214
|
}
|
|
4837
5215
|
) : null,
|
|
4838
|
-
!readOnly ? /* @__PURE__ */
|
|
5216
|
+
!readOnly ? /* @__PURE__ */ jsx17(FieldChevron, { onClick: toggleDropdown }) : null
|
|
4839
5217
|
] }),
|
|
4840
|
-
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */
|
|
5218
|
+
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ jsx17(
|
|
4841
5219
|
"div",
|
|
4842
5220
|
{
|
|
4843
5221
|
"data-ohw-link-page-dropdown": "",
|
|
4844
5222
|
className: "absolute left-0 right-0 h-20 top-[calc(100%+4px)] z-10 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
|
|
4845
5223
|
onMouseDown: (e) => e.preventDefault(),
|
|
4846
|
-
children: filteredPages.map((page) => /* @__PURE__ */
|
|
5224
|
+
children: filteredPages.map((page) => /* @__PURE__ */ jsxs9(
|
|
4847
5225
|
"button",
|
|
4848
5226
|
{
|
|
4849
5227
|
type: "button",
|
|
4850
5228
|
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",
|
|
4851
5229
|
onClick: () => onPageSelect(page),
|
|
4852
5230
|
children: [
|
|
4853
|
-
/* @__PURE__ */
|
|
4854
|
-
/* @__PURE__ */
|
|
5231
|
+
/* @__PURE__ */ jsx17(IconFile, { className: "shrink-0", "aria-hidden": true }),
|
|
5232
|
+
/* @__PURE__ */ jsx17("span", { className: "truncate", children: page.title })
|
|
4855
5233
|
]
|
|
4856
5234
|
},
|
|
4857
5235
|
page.path
|
|
@@ -4859,12 +5237,12 @@ function UrlOrPageInput({
|
|
|
4859
5237
|
}
|
|
4860
5238
|
) : null
|
|
4861
5239
|
] }),
|
|
4862
|
-
urlError ? /* @__PURE__ */
|
|
5240
|
+
urlError ? /* @__PURE__ */ jsx17("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
|
|
4863
5241
|
] });
|
|
4864
5242
|
}
|
|
4865
5243
|
|
|
4866
5244
|
// src/ui/link-modal/useLinkModalState.ts
|
|
4867
|
-
import { useCallback, useEffect as useEffect2, useMemo as useMemo2, useState as useState4 } from "react";
|
|
5245
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useState as useState4 } from "react";
|
|
4868
5246
|
function useLinkModalState({
|
|
4869
5247
|
open,
|
|
4870
5248
|
mode,
|
|
@@ -4886,7 +5264,7 @@ function useLinkModalState({
|
|
|
4886
5264
|
const [step, setStep] = useState4("input");
|
|
4887
5265
|
const [dropdownOpen, setDropdownOpen] = useState4(false);
|
|
4888
5266
|
const [urlError, setUrlError] = useState4("");
|
|
4889
|
-
const reset =
|
|
5267
|
+
const reset = useCallback2(() => {
|
|
4890
5268
|
setSearchValue("");
|
|
4891
5269
|
setSelectedPage(null);
|
|
4892
5270
|
setSelectedSection(null);
|
|
@@ -5027,7 +5405,7 @@ function useLinkModalState({
|
|
|
5027
5405
|
}
|
|
5028
5406
|
|
|
5029
5407
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5030
|
-
import { Fragment as Fragment2, jsx as
|
|
5408
|
+
import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
5031
5409
|
function LinkEditorPanel({
|
|
5032
5410
|
open = true,
|
|
5033
5411
|
mode = "create",
|
|
@@ -5051,25 +5429,25 @@ function LinkEditorPanel({
|
|
|
5051
5429
|
onSubmit
|
|
5052
5430
|
});
|
|
5053
5431
|
const isCancel = state.secondaryLabel === "Cancel";
|
|
5054
|
-
return /* @__PURE__ */
|
|
5055
|
-
/* @__PURE__ */
|
|
5432
|
+
return /* @__PURE__ */ jsxs10(Fragment2, { children: [
|
|
5433
|
+
/* @__PURE__ */ jsx18(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx18(
|
|
5056
5434
|
"button",
|
|
5057
5435
|
{
|
|
5058
5436
|
type: "button",
|
|
5059
5437
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5060
5438
|
"aria-label": "Close",
|
|
5061
|
-
children: /* @__PURE__ */
|
|
5439
|
+
children: /* @__PURE__ */ jsx18(IconX, { "aria-hidden": true })
|
|
5062
5440
|
}
|
|
5063
5441
|
) }),
|
|
5064
|
-
/* @__PURE__ */
|
|
5065
|
-
/* @__PURE__ */
|
|
5066
|
-
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */
|
|
5442
|
+
/* @__PURE__ */ jsx18(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ jsx18(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5443
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5444
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ jsx18(
|
|
5067
5445
|
DestinationBreadcrumb,
|
|
5068
5446
|
{
|
|
5069
5447
|
pageTitle: state.selectedPage.title,
|
|
5070
5448
|
sectionLabel: state.selectedSection.label
|
|
5071
5449
|
}
|
|
5072
|
-
) : /* @__PURE__ */
|
|
5450
|
+
) : /* @__PURE__ */ jsx18(
|
|
5073
5451
|
UrlOrPageInput,
|
|
5074
5452
|
{
|
|
5075
5453
|
value: state.searchValue,
|
|
@@ -5082,18 +5460,18 @@ function LinkEditorPanel({
|
|
|
5082
5460
|
urlError: state.urlError
|
|
5083
5461
|
}
|
|
5084
5462
|
),
|
|
5085
|
-
state.showChooseSection ? /* @__PURE__ */
|
|
5086
|
-
/* @__PURE__ */
|
|
5087
|
-
/* @__PURE__ */
|
|
5088
|
-
/* @__PURE__ */
|
|
5089
|
-
/* @__PURE__ */
|
|
5463
|
+
state.showChooseSection ? /* @__PURE__ */ jsxs10("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5464
|
+
/* @__PURE__ */ jsx18(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
|
|
5465
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5466
|
+
/* @__PURE__ */ jsx18(IconInfo, { className: "shrink-0", "aria-hidden": true }),
|
|
5467
|
+
/* @__PURE__ */ jsx18("span", { children: "Pick a section this link should scroll to." })
|
|
5090
5468
|
] })
|
|
5091
5469
|
] }) : null,
|
|
5092
|
-
state.showSectionPicker ? /* @__PURE__ */
|
|
5093
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */
|
|
5470
|
+
state.showSectionPicker ? /* @__PURE__ */ jsx18(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5471
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ jsx18(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5094
5472
|
] }),
|
|
5095
|
-
/* @__PURE__ */
|
|
5096
|
-
/* @__PURE__ */
|
|
5473
|
+
/* @__PURE__ */ jsxs10(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5474
|
+
/* @__PURE__ */ jsx18(
|
|
5097
5475
|
Button,
|
|
5098
5476
|
{
|
|
5099
5477
|
type: "button",
|
|
@@ -5108,7 +5486,7 @@ function LinkEditorPanel({
|
|
|
5108
5486
|
children: state.secondaryLabel
|
|
5109
5487
|
}
|
|
5110
5488
|
),
|
|
5111
|
-
/* @__PURE__ */
|
|
5489
|
+
/* @__PURE__ */ jsx18(
|
|
5112
5490
|
Button,
|
|
5113
5491
|
{
|
|
5114
5492
|
type: "button",
|
|
@@ -5127,7 +5505,7 @@ function LinkEditorPanel({
|
|
|
5127
5505
|
}
|
|
5128
5506
|
|
|
5129
5507
|
// src/ui/link-modal/LinkPopover.tsx
|
|
5130
|
-
import { jsx as
|
|
5508
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
5131
5509
|
function LinkPopover({
|
|
5132
5510
|
open = true,
|
|
5133
5511
|
panelRef,
|
|
@@ -5135,14 +5513,14 @@ function LinkPopover({
|
|
|
5135
5513
|
onClose,
|
|
5136
5514
|
...editorProps
|
|
5137
5515
|
}) {
|
|
5138
|
-
return /* @__PURE__ */
|
|
5516
|
+
return /* @__PURE__ */ jsx19(
|
|
5139
5517
|
Dialog2,
|
|
5140
5518
|
{
|
|
5141
5519
|
open,
|
|
5142
5520
|
onOpenChange: (next) => {
|
|
5143
5521
|
if (!next) onClose?.();
|
|
5144
5522
|
},
|
|
5145
|
-
children: /* @__PURE__ */
|
|
5523
|
+
children: /* @__PURE__ */ jsx19(
|
|
5146
5524
|
DialogContent,
|
|
5147
5525
|
{
|
|
5148
5526
|
ref: panelRef,
|
|
@@ -5152,7 +5530,7 @@ function LinkPopover({
|
|
|
5152
5530
|
"data-ohw-bridge": "",
|
|
5153
5531
|
showCloseButton: false,
|
|
5154
5532
|
className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
|
|
5155
|
-
children: /* @__PURE__ */
|
|
5533
|
+
children: /* @__PURE__ */ jsx19(LinkEditorPanel, { ...editorProps, open, onClose })
|
|
5156
5534
|
}
|
|
5157
5535
|
)
|
|
5158
5536
|
}
|
|
@@ -5218,7 +5596,7 @@ function shouldUseDevFixtures() {
|
|
|
5218
5596
|
}
|
|
5219
5597
|
|
|
5220
5598
|
// src/ui/badge.tsx
|
|
5221
|
-
import { jsx as
|
|
5599
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
5222
5600
|
var badgeVariants = cva(
|
|
5223
5601
|
"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",
|
|
5224
5602
|
{
|
|
@@ -5236,12 +5614,13 @@ var badgeVariants = cva(
|
|
|
5236
5614
|
}
|
|
5237
5615
|
);
|
|
5238
5616
|
function Badge({ className, variant, ...props }) {
|
|
5239
|
-
return /* @__PURE__ */
|
|
5617
|
+
return /* @__PURE__ */ jsx20("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
5240
5618
|
}
|
|
5241
5619
|
|
|
5242
5620
|
// src/OhhwellsBridge.tsx
|
|
5243
|
-
import {
|
|
5244
|
-
|
|
5621
|
+
import { Link as Link2 } from "lucide-react";
|
|
5622
|
+
import { Fragment as Fragment3, jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
5623
|
+
var PRIMARY2 = "#0885FE";
|
|
5245
5624
|
var IMAGE_FADE_MS = 300;
|
|
5246
5625
|
function runOpacityFade(el, onDone) {
|
|
5247
5626
|
const anim = el.animate([{ opacity: 0 }, { opacity: 1 }], {
|
|
@@ -5414,7 +5793,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
5414
5793
|
const root = createRoot(container);
|
|
5415
5794
|
flushSync(() => {
|
|
5416
5795
|
root.render(
|
|
5417
|
-
/* @__PURE__ */
|
|
5796
|
+
/* @__PURE__ */ jsx21(
|
|
5418
5797
|
SchedulingWidget,
|
|
5419
5798
|
{
|
|
5420
5799
|
notifyOnConnect,
|
|
@@ -5462,6 +5841,20 @@ function applyLinkHref(el, val) {
|
|
|
5462
5841
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
5463
5842
|
if (anchor) anchor.setAttribute("href", val);
|
|
5464
5843
|
}
|
|
5844
|
+
function getEditMeasureEl(editable) {
|
|
5845
|
+
return editable.closest("[data-ohw-href-key]") ?? editable;
|
|
5846
|
+
}
|
|
5847
|
+
function isDragHandleDisabled(el) {
|
|
5848
|
+
const carriers = [
|
|
5849
|
+
el.closest("[data-ohw-href-key]"),
|
|
5850
|
+
el.closest("[data-ohw-editable]")
|
|
5851
|
+
];
|
|
5852
|
+
return carriers.some((carrier) => {
|
|
5853
|
+
if (!carrier) return false;
|
|
5854
|
+
const raw = carrier.getAttribute("data-ohw-drag-disabled");
|
|
5855
|
+
return raw === "true" || raw === "";
|
|
5856
|
+
});
|
|
5857
|
+
}
|
|
5465
5858
|
function collectEditableNodes() {
|
|
5466
5859
|
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
5467
5860
|
if (el.dataset.ohwEditable === "image") {
|
|
@@ -5515,12 +5908,49 @@ function getHrefKeyFromElement(el) {
|
|
|
5515
5908
|
function isNavbarButton(el) {
|
|
5516
5909
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
5517
5910
|
}
|
|
5911
|
+
function getNavigationItemAnchor(el) {
|
|
5912
|
+
const anchor = el.matches("[data-ohw-href-key]") ? el : el.closest("[data-ohw-href-key]");
|
|
5913
|
+
if (!anchor) return null;
|
|
5914
|
+
if (!anchor.querySelector('[data-ohw-editable="text"]')) return null;
|
|
5915
|
+
return anchor;
|
|
5916
|
+
}
|
|
5917
|
+
function isNavigationItem(el) {
|
|
5918
|
+
return getNavigationItemAnchor(el) !== null;
|
|
5919
|
+
}
|
|
5920
|
+
function getNavigationItemAddHintTarget(anchor) {
|
|
5921
|
+
const items = listNavigationItems();
|
|
5922
|
+
const idx = items.indexOf(anchor);
|
|
5923
|
+
if (idx >= 0 && idx < items.length - 1) return items[idx + 1];
|
|
5924
|
+
return anchor;
|
|
5925
|
+
}
|
|
5926
|
+
function listNavigationItems() {
|
|
5927
|
+
return Array.from(
|
|
5928
|
+
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
5929
|
+
).filter((el) => isNavigationItem(el));
|
|
5930
|
+
}
|
|
5931
|
+
function getNavigationItemReorderState(anchor) {
|
|
5932
|
+
if (isNavbarButton(anchor)) return { key: null, disabled: false };
|
|
5933
|
+
return getReorderHandleStateFromAnchor(anchor);
|
|
5934
|
+
}
|
|
5935
|
+
function getReorderHandleState(el) {
|
|
5936
|
+
const linkEl = el.closest("[data-ohw-href-key]");
|
|
5937
|
+
if (!linkEl || getNavigationItemAnchor(linkEl)) return { key: null, disabled: false };
|
|
5938
|
+
return getReorderHandleStateFromAnchor(linkEl);
|
|
5939
|
+
}
|
|
5940
|
+
function getReorderHandleStateFromAnchor(anchor) {
|
|
5941
|
+
const key = anchor.getAttribute("data-ohw-href-key");
|
|
5942
|
+
if (!key) return { key: null, disabled: false };
|
|
5943
|
+
return { key, disabled: isDragHandleDisabled(anchor) };
|
|
5944
|
+
}
|
|
5518
5945
|
function clearHrefKeyHover(anchor) {
|
|
5519
5946
|
anchor.removeAttribute("data-ohw-hovered");
|
|
5520
5947
|
anchor.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
|
|
5521
5948
|
el.removeAttribute("data-ohw-hovered");
|
|
5522
5949
|
});
|
|
5523
5950
|
}
|
|
5951
|
+
function isInsideNavigationItem(el) {
|
|
5952
|
+
return getNavigationItemAnchor(el) !== null;
|
|
5953
|
+
}
|
|
5524
5954
|
function collectSections() {
|
|
5525
5955
|
return collectSectionsFromDom();
|
|
5526
5956
|
}
|
|
@@ -5644,6 +6074,8 @@ var ICONS = {
|
|
|
5644
6074
|
insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
|
|
5645
6075
|
insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
|
|
5646
6076
|
};
|
|
6077
|
+
var TOOLBAR_PILL_PADDING = 2;
|
|
6078
|
+
var TOOLBAR_TOGGLE_GAP = 4;
|
|
5647
6079
|
var TOOLBAR_GROUPS = [
|
|
5648
6080
|
[
|
|
5649
6081
|
{ cmd: "bold", title: "Bold" },
|
|
@@ -5661,24 +6093,64 @@ var TOOLBAR_GROUPS = [
|
|
|
5661
6093
|
{ cmd: "insertOrderedList", title: "Numbered List" }
|
|
5662
6094
|
]
|
|
5663
6095
|
];
|
|
5664
|
-
function
|
|
6096
|
+
function EditGlowChrome({
|
|
6097
|
+
rect,
|
|
6098
|
+
elRef,
|
|
6099
|
+
reorderHrefKey,
|
|
6100
|
+
dragDisabled = false
|
|
6101
|
+
}) {
|
|
5665
6102
|
const GAP = 6;
|
|
5666
|
-
return /* @__PURE__ */
|
|
6103
|
+
return /* @__PURE__ */ jsxs11(
|
|
5667
6104
|
"div",
|
|
5668
6105
|
{
|
|
5669
6106
|
ref: elRef,
|
|
6107
|
+
"data-ohw-edit-chrome": "",
|
|
5670
6108
|
style: {
|
|
5671
6109
|
position: "fixed",
|
|
5672
6110
|
top: rect.top - GAP,
|
|
5673
6111
|
left: rect.left - GAP,
|
|
5674
6112
|
width: rect.width + GAP * 2,
|
|
5675
6113
|
height: rect.height + GAP * 2,
|
|
5676
|
-
border: "2px solid #0885FE",
|
|
5677
|
-
borderRadius: 8,
|
|
5678
|
-
boxShadow: "0 0 0 4px rgba(8, 133, 254, 0.12)",
|
|
5679
6114
|
pointerEvents: "none",
|
|
5680
6115
|
zIndex: 2147483646
|
|
5681
|
-
}
|
|
6116
|
+
},
|
|
6117
|
+
children: [
|
|
6118
|
+
/* @__PURE__ */ jsx21(
|
|
6119
|
+
"div",
|
|
6120
|
+
{
|
|
6121
|
+
style: {
|
|
6122
|
+
position: "absolute",
|
|
6123
|
+
inset: 0,
|
|
6124
|
+
border: "2px solid var(--ohw-primary, #0885FE)",
|
|
6125
|
+
borderRadius: 8,
|
|
6126
|
+
boxShadow: "0 0 0 4px rgba(8, 133, 254, 0.12)",
|
|
6127
|
+
pointerEvents: "none"
|
|
6128
|
+
}
|
|
6129
|
+
}
|
|
6130
|
+
),
|
|
6131
|
+
reorderHrefKey && /* @__PURE__ */ jsx21(
|
|
6132
|
+
"div",
|
|
6133
|
+
{
|
|
6134
|
+
"data-ohw-drag-handle-container": "",
|
|
6135
|
+
"data-ohw-drag-disabled": dragDisabled ? "" : void 0,
|
|
6136
|
+
style: {
|
|
6137
|
+
position: "absolute",
|
|
6138
|
+
left: 0,
|
|
6139
|
+
top: "50%",
|
|
6140
|
+
transform: "translate(calc(-100% - 7px), -50%)",
|
|
6141
|
+
pointerEvents: dragDisabled ? "none" : "auto"
|
|
6142
|
+
},
|
|
6143
|
+
children: /* @__PURE__ */ jsx21(
|
|
6144
|
+
DragHandle,
|
|
6145
|
+
{
|
|
6146
|
+
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
6147
|
+
disabled: dragDisabled,
|
|
6148
|
+
"aria-disabled": dragDisabled
|
|
6149
|
+
}
|
|
6150
|
+
)
|
|
6151
|
+
}
|
|
6152
|
+
)
|
|
6153
|
+
]
|
|
5682
6154
|
}
|
|
5683
6155
|
);
|
|
5684
6156
|
}
|
|
@@ -5722,9 +6194,9 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
5722
6194
|
const pinnedTop = Math.min(maxBottom - approxH, Math.max(minTop, clip.top + gap));
|
|
5723
6195
|
return { top: pinnedTop + approxH, transform: "translateX(-50%) translateY(-100%)" };
|
|
5724
6196
|
}
|
|
5725
|
-
function calcToolbarPos(rect, parentScroll, approxW =
|
|
6197
|
+
function calcToolbarPos(rect, parentScroll, approxW = 306) {
|
|
5726
6198
|
const GAP = 8;
|
|
5727
|
-
const APPROX_H =
|
|
6199
|
+
const APPROX_H = 32;
|
|
5728
6200
|
const APPROX_W = approxW;
|
|
5729
6201
|
const clip = getIframeVisibleClip(parentScroll);
|
|
5730
6202
|
const clipTop = clip?.top ?? 0;
|
|
@@ -5758,119 +6230,24 @@ function calcToolbarPos(rect, parentScroll, approxW = 330) {
|
|
|
5758
6230
|
const left = Math.max(GAP + APPROX_W / 2, Math.min(rawLeft, window.innerWidth - GAP - APPROX_W / 2));
|
|
5759
6231
|
return { top, left, transform };
|
|
5760
6232
|
}
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
6233
|
+
function resolveItemInteractionState(rect, parentScroll) {
|
|
6234
|
+
const { transform } = calcToolbarPos(rect, parentScroll, 120);
|
|
6235
|
+
return transform.includes("translateY(-100%)") ? "active-top" : "active-bottom";
|
|
6236
|
+
}
|
|
5765
6237
|
function FloatingToolbar({
|
|
5766
6238
|
rect,
|
|
5767
6239
|
parentScroll,
|
|
5768
6240
|
elRef,
|
|
5769
|
-
variant = "rich-text",
|
|
5770
6241
|
onCommand,
|
|
5771
6242
|
activeCommands,
|
|
5772
6243
|
showEditLink,
|
|
5773
6244
|
onEditLink
|
|
5774
6245
|
}) {
|
|
5775
|
-
const
|
|
5776
|
-
|
|
5777
|
-
if (variant === "link-action") {
|
|
5778
|
-
return /* @__PURE__ */ jsxs9(
|
|
5779
|
-
"div",
|
|
5780
|
-
{
|
|
5781
|
-
ref: elRef,
|
|
5782
|
-
"data-ohw-toolbar": "",
|
|
5783
|
-
style: {
|
|
5784
|
-
position: "fixed",
|
|
5785
|
-
top,
|
|
5786
|
-
left,
|
|
5787
|
-
transform,
|
|
5788
|
-
zIndex: 2147483647,
|
|
5789
|
-
background: "#fff",
|
|
5790
|
-
border: "1px solid #E7E5E4",
|
|
5791
|
-
borderRadius: 6,
|
|
5792
|
-
boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
|
|
5793
|
-
display: "flex",
|
|
5794
|
-
alignItems: "center",
|
|
5795
|
-
padding: 4,
|
|
5796
|
-
gap: 6,
|
|
5797
|
-
fontFamily: "sans-serif",
|
|
5798
|
-
pointerEvents: "auto",
|
|
5799
|
-
whiteSpace: "nowrap"
|
|
5800
|
-
},
|
|
5801
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
5802
|
-
children: [
|
|
5803
|
-
/* @__PURE__ */ jsx16(
|
|
5804
|
-
"button",
|
|
5805
|
-
{
|
|
5806
|
-
type: "button",
|
|
5807
|
-
title: "Edit link",
|
|
5808
|
-
onMouseDown: (e) => {
|
|
5809
|
-
e.preventDefault();
|
|
5810
|
-
e.stopPropagation();
|
|
5811
|
-
onEditLink?.();
|
|
5812
|
-
},
|
|
5813
|
-
onClick: (e) => {
|
|
5814
|
-
e.preventDefault();
|
|
5815
|
-
e.stopPropagation();
|
|
5816
|
-
},
|
|
5817
|
-
onMouseEnter: (e) => {
|
|
5818
|
-
e.currentTarget.style.background = "#F5F5F4";
|
|
5819
|
-
},
|
|
5820
|
-
onMouseLeave: (e) => {
|
|
5821
|
-
e.currentTarget.style.background = "transparent";
|
|
5822
|
-
},
|
|
5823
|
-
style: {
|
|
5824
|
-
display: "flex",
|
|
5825
|
-
alignItems: "center",
|
|
5826
|
-
justifyContent: "center",
|
|
5827
|
-
border: "none",
|
|
5828
|
-
background: "transparent",
|
|
5829
|
-
borderRadius: 4,
|
|
5830
|
-
cursor: "pointer",
|
|
5831
|
-
color: "#1C1917",
|
|
5832
|
-
flexShrink: 0,
|
|
5833
|
-
padding: 6
|
|
5834
|
-
},
|
|
5835
|
-
children: EDIT_LINK_ICON
|
|
5836
|
-
}
|
|
5837
|
-
),
|
|
5838
|
-
/* @__PURE__ */ jsx16("span", { style: { display: "block", width: 1, height: 24, background: "#E7E5E4", flexShrink: 0 } }),
|
|
5839
|
-
/* @__PURE__ */ jsx16(
|
|
5840
|
-
"button",
|
|
5841
|
-
{
|
|
5842
|
-
type: "button",
|
|
5843
|
-
title: "Coming soon",
|
|
5844
|
-
disabled: true,
|
|
5845
|
-
style: {
|
|
5846
|
-
display: "flex",
|
|
5847
|
-
alignItems: "center",
|
|
5848
|
-
justifyContent: "center",
|
|
5849
|
-
border: "none",
|
|
5850
|
-
background: "transparent",
|
|
5851
|
-
borderRadius: 4,
|
|
5852
|
-
cursor: "not-allowed",
|
|
5853
|
-
color: "#A8A29E",
|
|
5854
|
-
flexShrink: 0,
|
|
5855
|
-
padding: 6,
|
|
5856
|
-
opacity: 0.6
|
|
5857
|
-
},
|
|
5858
|
-
children: /* @__PURE__ */ jsxs9("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: [
|
|
5859
|
-
/* @__PURE__ */ jsx16("circle", { cx: "5", cy: "12", r: "1.5" }),
|
|
5860
|
-
/* @__PURE__ */ jsx16("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
5861
|
-
/* @__PURE__ */ jsx16("circle", { cx: "19", cy: "12", r: "1.5" })
|
|
5862
|
-
] })
|
|
5863
|
-
}
|
|
5864
|
-
)
|
|
5865
|
-
]
|
|
5866
|
-
}
|
|
5867
|
-
);
|
|
5868
|
-
}
|
|
5869
|
-
return /* @__PURE__ */ jsxs9(
|
|
6246
|
+
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
6247
|
+
return /* @__PURE__ */ jsx21(
|
|
5870
6248
|
"div",
|
|
5871
6249
|
{
|
|
5872
6250
|
ref: elRef,
|
|
5873
|
-
"data-ohw-toolbar": "",
|
|
5874
6251
|
style: {
|
|
5875
6252
|
position: "fixed",
|
|
5876
6253
|
top,
|
|
@@ -5883,57 +6260,39 @@ function FloatingToolbar({
|
|
|
5883
6260
|
boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
|
|
5884
6261
|
display: "flex",
|
|
5885
6262
|
alignItems: "center",
|
|
5886
|
-
padding:
|
|
5887
|
-
gap:
|
|
6263
|
+
padding: TOOLBAR_PILL_PADDING,
|
|
6264
|
+
gap: TOOLBAR_TOGGLE_GAP,
|
|
5888
6265
|
fontFamily: "sans-serif",
|
|
5889
|
-
pointerEvents: "auto"
|
|
5890
|
-
whiteSpace: "nowrap"
|
|
6266
|
+
pointerEvents: "auto"
|
|
5891
6267
|
},
|
|
5892
|
-
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
gi > 0 && /* @__PURE__ */ jsx16("span", { style: { display: "block", width: 1, height: 24, background: "#E7E5E4", flexShrink: 0 } }),
|
|
6268
|
+
children: /* @__PURE__ */ jsxs11(CustomToolbar, { children: [
|
|
6269
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs11(React8.Fragment, { children: [
|
|
6270
|
+
gi > 0 && /* @__PURE__ */ jsx21(CustomToolbarDivider, {}),
|
|
5896
6271
|
btns.map((btn) => {
|
|
5897
6272
|
const isActive = activeCommands.has(btn.cmd);
|
|
5898
|
-
return /* @__PURE__ */
|
|
5899
|
-
|
|
6273
|
+
return /* @__PURE__ */ jsx21(
|
|
6274
|
+
CustomToolbarButton,
|
|
5900
6275
|
{
|
|
5901
6276
|
title: btn.title,
|
|
6277
|
+
active: isActive,
|
|
5902
6278
|
onMouseDown: (e) => {
|
|
5903
6279
|
e.preventDefault();
|
|
5904
6280
|
onCommand(btn.cmd);
|
|
5905
6281
|
},
|
|
5906
|
-
|
|
5907
|
-
if (!isActive) e.currentTarget.style.background = "#F5F5F4";
|
|
5908
|
-
},
|
|
5909
|
-
onMouseLeave: (e) => {
|
|
5910
|
-
if (!isActive) e.currentTarget.style.background = "transparent";
|
|
5911
|
-
},
|
|
5912
|
-
style: {
|
|
5913
|
-
display: "flex",
|
|
5914
|
-
alignItems: "center",
|
|
5915
|
-
justifyContent: "center",
|
|
5916
|
-
border: "none",
|
|
5917
|
-
background: isActive ? PRIMARY : "transparent",
|
|
5918
|
-
borderRadius: 4,
|
|
5919
|
-
cursor: "pointer",
|
|
5920
|
-
color: isActive ? "#FFFFFF" : "#1C1917",
|
|
5921
|
-
flexShrink: 0,
|
|
5922
|
-
padding: 6
|
|
5923
|
-
},
|
|
5924
|
-
children: /* @__PURE__ */ jsx16(
|
|
6282
|
+
children: /* @__PURE__ */ jsx21(
|
|
5925
6283
|
"svg",
|
|
5926
6284
|
{
|
|
5927
6285
|
width: "16",
|
|
5928
6286
|
height: "16",
|
|
5929
6287
|
viewBox: "0 0 24 24",
|
|
5930
6288
|
fill: "none",
|
|
5931
|
-
stroke:
|
|
6289
|
+
stroke: "currentColor",
|
|
5932
6290
|
strokeWidth: "2.5",
|
|
5933
6291
|
strokeLinecap: "round",
|
|
5934
6292
|
strokeLinejoin: "round",
|
|
5935
|
-
style: isActive && gi > 0 ? { filter: "drop-shadow(0 0 0.5px
|
|
5936
|
-
dangerouslySetInnerHTML: { __html: ICONS[btn.cmd] }
|
|
6293
|
+
style: isActive && gi > 0 ? { filter: "drop-shadow(0 0 0.5px currentColor)" } : void 0,
|
|
6294
|
+
dangerouslySetInnerHTML: { __html: ICONS[btn.cmd] },
|
|
6295
|
+
"aria-hidden": true
|
|
5937
6296
|
}
|
|
5938
6297
|
)
|
|
5939
6298
|
},
|
|
@@ -5941,8 +6300,8 @@ function FloatingToolbar({
|
|
|
5941
6300
|
);
|
|
5942
6301
|
})
|
|
5943
6302
|
] }, gi)),
|
|
5944
|
-
showEditLink ? /* @__PURE__ */
|
|
5945
|
-
|
|
6303
|
+
showEditLink ? /* @__PURE__ */ jsx21(
|
|
6304
|
+
CustomToolbarButton,
|
|
5946
6305
|
{
|
|
5947
6306
|
type: "button",
|
|
5948
6307
|
title: "Edit link",
|
|
@@ -5955,28 +6314,10 @@ function FloatingToolbar({
|
|
|
5955
6314
|
e.preventDefault();
|
|
5956
6315
|
e.stopPropagation();
|
|
5957
6316
|
},
|
|
5958
|
-
|
|
5959
|
-
e.currentTarget.style.background = "#F5F5F4";
|
|
5960
|
-
},
|
|
5961
|
-
onMouseLeave: (e) => {
|
|
5962
|
-
e.currentTarget.style.background = "transparent";
|
|
5963
|
-
},
|
|
5964
|
-
style: {
|
|
5965
|
-
display: "flex",
|
|
5966
|
-
alignItems: "center",
|
|
5967
|
-
justifyContent: "center",
|
|
5968
|
-
border: "none",
|
|
5969
|
-
background: "transparent",
|
|
5970
|
-
borderRadius: 4,
|
|
5971
|
-
cursor: "pointer",
|
|
5972
|
-
color: "#1C1917",
|
|
5973
|
-
flexShrink: 0,
|
|
5974
|
-
padding: 6
|
|
5975
|
-
},
|
|
5976
|
-
children: EDIT_LINK_ICON
|
|
6317
|
+
children: /* @__PURE__ */ jsx21(Link2, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
5977
6318
|
}
|
|
5978
6319
|
) : null
|
|
5979
|
-
]
|
|
6320
|
+
] })
|
|
5980
6321
|
}
|
|
5981
6322
|
);
|
|
5982
6323
|
}
|
|
@@ -5990,7 +6331,7 @@ function StateToggle({
|
|
|
5990
6331
|
states,
|
|
5991
6332
|
onStateChange
|
|
5992
6333
|
}) {
|
|
5993
|
-
return /* @__PURE__ */
|
|
6334
|
+
return /* @__PURE__ */ jsx21(
|
|
5994
6335
|
ToggleGroup,
|
|
5995
6336
|
{
|
|
5996
6337
|
"data-ohw-state-toggle": "",
|
|
@@ -6004,7 +6345,7 @@ function StateToggle({
|
|
|
6004
6345
|
left: rect.right - 8,
|
|
6005
6346
|
transform: "translateX(-100%)"
|
|
6006
6347
|
},
|
|
6007
|
-
children: states.map((state) => /* @__PURE__ */
|
|
6348
|
+
children: states.map((state) => /* @__PURE__ */ jsx21(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
6008
6349
|
}
|
|
6009
6350
|
);
|
|
6010
6351
|
}
|
|
@@ -6057,7 +6398,7 @@ function OhhwellsBridge() {
|
|
|
6057
6398
|
const subdomainFromQuery = searchParams.get("subdomain");
|
|
6058
6399
|
const subdomain = resolveSubdomain(subdomainFromQuery);
|
|
6059
6400
|
useLinkHrefGuardian(pathname, subdomain, isEditMode);
|
|
6060
|
-
const postToParent =
|
|
6401
|
+
const postToParent = useCallback3((data) => {
|
|
6061
6402
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
6062
6403
|
window.parent.postMessage(data, "*");
|
|
6063
6404
|
}
|
|
@@ -6071,7 +6412,7 @@ function OhhwellsBridge() {
|
|
|
6071
6412
|
const parentScrollRef = useRef3(null);
|
|
6072
6413
|
const visibleViewportRef = useRef3(null);
|
|
6073
6414
|
const [dialogPortalContainer, setDialogPortalContainer] = useState5(null);
|
|
6074
|
-
const attachVisibleViewport =
|
|
6415
|
+
const attachVisibleViewport = useCallback3((node) => {
|
|
6075
6416
|
visibleViewportRef.current = node;
|
|
6076
6417
|
setDialogPortalContainer(node);
|
|
6077
6418
|
if (node) applyVisibleViewport(node, parentScrollRef.current);
|
|
@@ -6092,6 +6433,10 @@ function OhhwellsBridge() {
|
|
|
6092
6433
|
});
|
|
6093
6434
|
const deselectRef = useRef3(() => {
|
|
6094
6435
|
});
|
|
6436
|
+
const reselectNavigationItemRef = useRef3(() => {
|
|
6437
|
+
});
|
|
6438
|
+
const commitNavigationTextEditRef = useRef3(() => {
|
|
6439
|
+
});
|
|
6095
6440
|
const refreshActiveCommandsRef = useRef3(() => {
|
|
6096
6441
|
});
|
|
6097
6442
|
const postToParentRef = useRef3(postToParent);
|
|
@@ -6102,11 +6447,18 @@ function OhhwellsBridge() {
|
|
|
6102
6447
|
const [toolbarVariant, setToolbarVariant] = useState5("none");
|
|
6103
6448
|
const toolbarVariantRef = useRef3("none");
|
|
6104
6449
|
toolbarVariantRef.current = toolbarVariant;
|
|
6450
|
+
const [reorderHrefKey, setReorderHrefKey] = useState5(null);
|
|
6451
|
+
const [reorderDragDisabled, setReorderDragDisabled] = useState5(false);
|
|
6105
6452
|
const [toggleState, setToggleState] = useState5(null);
|
|
6106
6453
|
const [maxBadge, setMaxBadge] = useState5(null);
|
|
6107
6454
|
const [activeCommands, setActiveCommands] = useState5(/* @__PURE__ */ new Set());
|
|
6108
6455
|
const [sectionGap, setSectionGap] = useState5(null);
|
|
6109
6456
|
const [toolbarShowEditLink, setToolbarShowEditLink] = useState5(false);
|
|
6457
|
+
const hoveredItemElRef = useRef3(null);
|
|
6458
|
+
const [hoveredItemRect, setHoveredItemRect] = useState5(null);
|
|
6459
|
+
const siblingHintElRef = useRef3(null);
|
|
6460
|
+
const [siblingHintRect, setSiblingHintRect] = useState5(null);
|
|
6461
|
+
const [isItemDragging, setIsItemDragging] = useState5(false);
|
|
6110
6462
|
const [linkPopover, setLinkPopover] = useState5(null);
|
|
6111
6463
|
const [sitePages, setSitePages] = useState5([]);
|
|
6112
6464
|
const [sectionsByPath, setSectionsByPath] = useState5({});
|
|
@@ -6119,7 +6471,7 @@ function OhhwellsBridge() {
|
|
|
6119
6471
|
const bumpLinkPopoverGrace = () => {
|
|
6120
6472
|
linkPopoverGraceUntilRef.current = Date.now() + 350;
|
|
6121
6473
|
};
|
|
6122
|
-
const runSectionsPrefetch =
|
|
6474
|
+
const runSectionsPrefetch = useCallback3((pages) => {
|
|
6123
6475
|
if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
|
|
6124
6476
|
const gen = ++sectionsPrefetchGenRef.current;
|
|
6125
6477
|
const paths = pages.map((p) => p.path);
|
|
@@ -6208,7 +6560,7 @@ function OhhwellsBridge() {
|
|
|
6208
6560
|
useEffect3(() => {
|
|
6209
6561
|
const update = () => {
|
|
6210
6562
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
6211
|
-
if (el) setToolbarRect(el.getBoundingClientRect());
|
|
6563
|
+
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
6212
6564
|
setToggleState((prev) => {
|
|
6213
6565
|
if (!prev || !activeStateElRef.current) return prev;
|
|
6214
6566
|
return { ...prev, rect: activeStateElRef.current.getBoundingClientRect() };
|
|
@@ -6229,10 +6581,10 @@ function OhhwellsBridge() {
|
|
|
6229
6581
|
vvp.removeEventListener("resize", update);
|
|
6230
6582
|
};
|
|
6231
6583
|
}, []);
|
|
6232
|
-
const refreshStateRules =
|
|
6584
|
+
const refreshStateRules = useCallback3(() => {
|
|
6233
6585
|
editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
|
|
6234
6586
|
}, []);
|
|
6235
|
-
const processConfigRequest =
|
|
6587
|
+
const processConfigRequest = useCallback3((insertAfterVal) => {
|
|
6236
6588
|
const tracker = getSectionsTracker();
|
|
6237
6589
|
let entries = [];
|
|
6238
6590
|
try {
|
|
@@ -6255,7 +6607,7 @@ function OhhwellsBridge() {
|
|
|
6255
6607
|
}
|
|
6256
6608
|
window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
|
|
6257
6609
|
}, [isEditMode]);
|
|
6258
|
-
const deactivate =
|
|
6610
|
+
const deactivate = useCallback3(() => {
|
|
6259
6611
|
const el = activeElRef.current;
|
|
6260
6612
|
if (!el) return;
|
|
6261
6613
|
const key = el.dataset.ohwKey;
|
|
@@ -6275,6 +6627,8 @@ function OhhwellsBridge() {
|
|
|
6275
6627
|
}
|
|
6276
6628
|
el.removeAttribute("contenteditable");
|
|
6277
6629
|
activeElRef.current = null;
|
|
6630
|
+
setReorderHrefKey(null);
|
|
6631
|
+
setReorderDragDisabled(false);
|
|
6278
6632
|
if (!selectedElRef.current) {
|
|
6279
6633
|
setToolbarRect(null);
|
|
6280
6634
|
setToolbarVariant("none");
|
|
@@ -6284,24 +6638,90 @@ function OhhwellsBridge() {
|
|
|
6284
6638
|
setToolbarShowEditLink(false);
|
|
6285
6639
|
postToParent({ type: "ow:exit-edit" });
|
|
6286
6640
|
}, [postToParent]);
|
|
6287
|
-
const deselect =
|
|
6641
|
+
const deselect = useCallback3(() => {
|
|
6288
6642
|
selectedElRef.current = null;
|
|
6643
|
+
setReorderHrefKey(null);
|
|
6644
|
+
setReorderDragDisabled(false);
|
|
6645
|
+
siblingHintElRef.current = null;
|
|
6646
|
+
setSiblingHintRect(null);
|
|
6647
|
+
setIsItemDragging(false);
|
|
6289
6648
|
if (!activeElRef.current) {
|
|
6290
6649
|
setToolbarRect(null);
|
|
6291
6650
|
setToolbarVariant("none");
|
|
6292
6651
|
}
|
|
6293
6652
|
}, []);
|
|
6294
|
-
const
|
|
6295
|
-
|
|
6653
|
+
const reselectNavigationItem = useCallback3((navAnchor) => {
|
|
6654
|
+
selectedElRef.current = navAnchor;
|
|
6655
|
+
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
6656
|
+
setReorderHrefKey(key);
|
|
6657
|
+
setReorderDragDisabled(disabled);
|
|
6658
|
+
setToolbarVariant("link-action");
|
|
6659
|
+
setToolbarRect(navAnchor.getBoundingClientRect());
|
|
6660
|
+
setToolbarShowEditLink(false);
|
|
6661
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6662
|
+
}, []);
|
|
6663
|
+
const commitNavigationTextEdit = useCallback3((navAnchor) => {
|
|
6664
|
+
const el = activeElRef.current;
|
|
6665
|
+
if (!el) return;
|
|
6666
|
+
const key = el.dataset.ohwKey;
|
|
6667
|
+
if (key) {
|
|
6668
|
+
const timer = autoSaveTimers.current.get(key);
|
|
6669
|
+
if (timer !== void 0) {
|
|
6670
|
+
clearTimeout(timer);
|
|
6671
|
+
autoSaveTimers.current.delete(key);
|
|
6672
|
+
}
|
|
6673
|
+
const html = sanitizeHtml(el.innerHTML);
|
|
6674
|
+
const original = originalContentRef.current ?? "";
|
|
6675
|
+
if (html !== sanitizeHtml(original)) {
|
|
6676
|
+
postToParent({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
6677
|
+
const h = document.documentElement.scrollHeight;
|
|
6678
|
+
if (h > 50) postToParent({ type: "ow:height", height: h });
|
|
6679
|
+
}
|
|
6680
|
+
}
|
|
6681
|
+
el.removeAttribute("contenteditable");
|
|
6682
|
+
activeElRef.current = null;
|
|
6683
|
+
setMaxBadge(null);
|
|
6684
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6685
|
+
setToolbarShowEditLink(false);
|
|
6686
|
+
postToParent({ type: "ow:exit-edit" });
|
|
6687
|
+
reselectNavigationItem(navAnchor);
|
|
6688
|
+
}, [postToParent, reselectNavigationItem]);
|
|
6689
|
+
const handleAddNavigationItem = useCallback3(() => {
|
|
6690
|
+
const selected = selectedElRef.current;
|
|
6691
|
+
if (!selected) return;
|
|
6692
|
+
const target = getNavigationItemAddHintTarget(selected);
|
|
6693
|
+
siblingHintElRef.current = target;
|
|
6694
|
+
setSiblingHintRect(target.getBoundingClientRect());
|
|
6695
|
+
}, []);
|
|
6696
|
+
const handleItemDragStart = useCallback3(() => {
|
|
6697
|
+
siblingHintElRef.current = null;
|
|
6698
|
+
setSiblingHintRect(null);
|
|
6699
|
+
setIsItemDragging(true);
|
|
6700
|
+
}, []);
|
|
6701
|
+
const handleItemDragEnd = useCallback3(() => {
|
|
6702
|
+
setIsItemDragging(false);
|
|
6703
|
+
}, []);
|
|
6704
|
+
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
6705
|
+
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
6706
|
+
const select = useCallback3((anchor) => {
|
|
6707
|
+
if (!isNavigationItem(anchor)) return;
|
|
6296
6708
|
if (activeElRef.current) deactivate();
|
|
6297
6709
|
selectedElRef.current = anchor;
|
|
6298
6710
|
clearHrefKeyHover(anchor);
|
|
6711
|
+
setHoveredItemRect(null);
|
|
6712
|
+
hoveredItemElRef.current = null;
|
|
6713
|
+
siblingHintElRef.current = null;
|
|
6714
|
+
setSiblingHintRect(null);
|
|
6715
|
+
setIsItemDragging(false);
|
|
6716
|
+
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
6717
|
+
setReorderHrefKey(key);
|
|
6718
|
+
setReorderDragDisabled(disabled);
|
|
6299
6719
|
setToolbarVariant("link-action");
|
|
6300
6720
|
setToolbarRect(anchor.getBoundingClientRect());
|
|
6301
6721
|
setToolbarShowEditLink(false);
|
|
6302
6722
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6303
6723
|
}, [deactivate]);
|
|
6304
|
-
const activate =
|
|
6724
|
+
const activate = useCallback3((el) => {
|
|
6305
6725
|
if (activeElRef.current === el) return;
|
|
6306
6726
|
selectedElRef.current = null;
|
|
6307
6727
|
deactivate();
|
|
@@ -6310,13 +6730,26 @@ function OhhwellsBridge() {
|
|
|
6310
6730
|
postToParentRef.current({ type: "ow:image-unhover" });
|
|
6311
6731
|
}
|
|
6312
6732
|
setToolbarVariant("rich-text");
|
|
6733
|
+
siblingHintElRef.current = null;
|
|
6734
|
+
setSiblingHintRect(null);
|
|
6735
|
+
setIsItemDragging(false);
|
|
6313
6736
|
el.setAttribute("contenteditable", "true");
|
|
6314
6737
|
el.removeAttribute("data-ohw-hovered");
|
|
6738
|
+
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
6315
6739
|
activeElRef.current = el;
|
|
6316
6740
|
originalContentRef.current = el.innerHTML;
|
|
6317
6741
|
el.focus();
|
|
6318
|
-
setToolbarRect(el.getBoundingClientRect());
|
|
6319
6742
|
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
6743
|
+
const navAnchor = getNavigationItemAnchor(el);
|
|
6744
|
+
if (navAnchor) {
|
|
6745
|
+
setReorderHrefKey(null);
|
|
6746
|
+
setReorderDragDisabled(false);
|
|
6747
|
+
} else {
|
|
6748
|
+
const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
|
|
6749
|
+
setReorderHrefKey(reorderKey);
|
|
6750
|
+
setReorderDragDisabled(reorderDisabled);
|
|
6751
|
+
}
|
|
6752
|
+
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
6320
6753
|
postToParent({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
6321
6754
|
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
6322
6755
|
}, [deactivate, postToParent]);
|
|
@@ -6508,18 +6941,25 @@ function OhhwellsBridge() {
|
|
|
6508
6941
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
6509
6942
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
6510
6943
|
[data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
|
|
6511
|
-
[data-ohw-hovered]:not([contenteditable]) {
|
|
6512
|
-
outline: 2px dashed ${
|
|
6944
|
+
[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
|
|
6945
|
+
outline: 2px dashed ${PRIMARY2} !important;
|
|
6513
6946
|
outline-offset: 4px;
|
|
6514
6947
|
border-radius: 2px;
|
|
6515
6948
|
}
|
|
6949
|
+
[data-ohw-href-key] [data-ohw-hovered],
|
|
6950
|
+
[data-ohw-href-key][data-ohw-hovered],
|
|
6951
|
+
nav [data-ohw-href-key] [data-ohw-hovered],
|
|
6952
|
+
footer [data-ohw-href-key] [data-ohw-hovered] {
|
|
6953
|
+
outline: none !important;
|
|
6954
|
+
outline-offset: 0 !important;
|
|
6955
|
+
}
|
|
6516
6956
|
[data-ohw-editable][contenteditable] {
|
|
6517
6957
|
outline: none !important;
|
|
6518
|
-
caret-color: ${
|
|
6958
|
+
caret-color: ${PRIMARY2};
|
|
6519
6959
|
cursor: text !important;
|
|
6520
6960
|
}
|
|
6521
6961
|
[data-ohw-editable][contenteditable]::selection,
|
|
6522
|
-
[data-ohw-editable][contenteditable] *::selection { background: ${
|
|
6962
|
+
[data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY2}59 !important; }
|
|
6523
6963
|
[data-ohw-editable-state], [data-ohw-editable-state] * { pointer-events: none !important; }
|
|
6524
6964
|
[data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
|
|
6525
6965
|
[data-ohw-editable-state][data-ohw-active-state][data-ohw-editable] { pointer-events: auto !important; }
|
|
@@ -6531,7 +6971,7 @@ function OhhwellsBridge() {
|
|
|
6531
6971
|
stateViews.textContent = `
|
|
6532
6972
|
[data-ohw-state-view]:not([data-ohw-state-view="default"]) { display: none; }
|
|
6533
6973
|
[data-ohw-state-view="default"] [data-ohw-editable] { pointer-events: auto !important; }
|
|
6534
|
-
[data-ohw-state-hovered] { outline: 2px dashed ${
|
|
6974
|
+
[data-ohw-state-hovered] { outline: 2px dashed ${PRIMARY2} !important; outline-offset: 4px; border-radius: 2px; }
|
|
6535
6975
|
[data-ohw-state-hovered]:has([data-ohw-hovered]) { outline: none !important; }
|
|
6536
6976
|
`;
|
|
6537
6977
|
document.head.appendChild(base);
|
|
@@ -6546,6 +6986,11 @@ function OhhwellsBridge() {
|
|
|
6546
6986
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
6547
6987
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
6548
6988
|
if (isInsideLinkEditor(target)) return;
|
|
6989
|
+
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
6990
|
+
e.preventDefault();
|
|
6991
|
+
e.stopPropagation();
|
|
6992
|
+
return;
|
|
6993
|
+
}
|
|
6549
6994
|
const editable = target.closest("[data-ohw-editable]");
|
|
6550
6995
|
if (editable) {
|
|
6551
6996
|
if (editable.dataset.ohwEditable === "link") {
|
|
@@ -6567,15 +7012,15 @@ function OhhwellsBridge() {
|
|
|
6567
7012
|
return;
|
|
6568
7013
|
}
|
|
6569
7014
|
const hrefCtx = getHrefKeyFromElement(editable);
|
|
6570
|
-
|
|
7015
|
+
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
7016
|
+
if (navAnchor) {
|
|
6571
7017
|
e.preventDefault();
|
|
6572
7018
|
e.stopPropagation();
|
|
6573
|
-
|
|
6574
|
-
if (selectedElRef.current === anchor2) {
|
|
7019
|
+
if (selectedElRef.current === navAnchor) {
|
|
6575
7020
|
activateRef.current(editable);
|
|
6576
7021
|
return;
|
|
6577
7022
|
}
|
|
6578
|
-
selectRef.current(
|
|
7023
|
+
selectRef.current(navAnchor);
|
|
6579
7024
|
return;
|
|
6580
7025
|
}
|
|
6581
7026
|
e.preventDefault();
|
|
@@ -6583,8 +7028,8 @@ function OhhwellsBridge() {
|
|
|
6583
7028
|
activateRef.current(editable);
|
|
6584
7029
|
return;
|
|
6585
7030
|
}
|
|
6586
|
-
const hrefAnchor = target
|
|
6587
|
-
if (hrefAnchor
|
|
7031
|
+
const hrefAnchor = getNavigationItemAnchor(target);
|
|
7032
|
+
if (hrefAnchor) {
|
|
6588
7033
|
e.preventDefault();
|
|
6589
7034
|
e.stopPropagation();
|
|
6590
7035
|
if (selectedElRef.current === hrefAnchor) return;
|
|
@@ -6617,19 +7062,58 @@ function OhhwellsBridge() {
|
|
|
6617
7062
|
deactivateRef.current();
|
|
6618
7063
|
};
|
|
6619
7064
|
const handleMouseOver = (e) => {
|
|
6620
|
-
const
|
|
7065
|
+
const target = e.target;
|
|
7066
|
+
const navAnchor = getNavigationItemAnchor(target);
|
|
7067
|
+
if (navAnchor) {
|
|
7068
|
+
const selected2 = selectedElRef.current;
|
|
7069
|
+
if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
|
|
7070
|
+
clearHrefKeyHover(navAnchor);
|
|
7071
|
+
hoveredItemElRef.current = navAnchor;
|
|
7072
|
+
setHoveredItemRect(navAnchor.getBoundingClientRect());
|
|
7073
|
+
return;
|
|
7074
|
+
}
|
|
7075
|
+
const editable = target.closest("[data-ohw-editable]");
|
|
6621
7076
|
if (!editable) return;
|
|
6622
7077
|
const selected = selectedElRef.current;
|
|
6623
7078
|
if (selected && (selected === editable || selected.contains(editable))) return;
|
|
6624
7079
|
if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image" && !editable.hasAttribute("contenteditable")) {
|
|
6625
|
-
editable.
|
|
7080
|
+
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
7081
|
+
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
7082
|
+
clearHrefKeyHover(hoverTarget);
|
|
7083
|
+
hoveredItemElRef.current = hoverTarget;
|
|
7084
|
+
setHoveredItemRect(hoverTarget.getBoundingClientRect());
|
|
7085
|
+
} else if (!isInsideNavigationItem(editable)) {
|
|
7086
|
+
hoverTarget.setAttribute("data-ohw-hovered", "");
|
|
7087
|
+
}
|
|
6626
7088
|
}
|
|
6627
7089
|
};
|
|
6628
7090
|
const handleMouseOut = (e) => {
|
|
6629
|
-
const
|
|
7091
|
+
const target = e.target;
|
|
7092
|
+
const navAnchor = getNavigationItemAnchor(target);
|
|
7093
|
+
if (navAnchor) {
|
|
7094
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
7095
|
+
if (related2?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
7096
|
+
if (related2 && navAnchor.contains(related2)) return;
|
|
7097
|
+
if (hoveredItemElRef.current === navAnchor) {
|
|
7098
|
+
hoveredItemElRef.current = null;
|
|
7099
|
+
setHoveredItemRect(null);
|
|
7100
|
+
}
|
|
7101
|
+
return;
|
|
7102
|
+
}
|
|
7103
|
+
const editable = target.closest("[data-ohw-editable]");
|
|
6630
7104
|
if (!editable) return;
|
|
7105
|
+
const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
7106
|
+
if (related?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
6631
7107
|
if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image") {
|
|
6632
|
-
editable.
|
|
7108
|
+
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
7109
|
+
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
7110
|
+
if (!related?.closest("[data-ohw-href-key]")) {
|
|
7111
|
+
hoveredItemElRef.current = null;
|
|
7112
|
+
setHoveredItemRect(null);
|
|
7113
|
+
}
|
|
7114
|
+
} else {
|
|
7115
|
+
hoverTarget.removeAttribute("data-ohw-hovered");
|
|
7116
|
+
}
|
|
6633
7117
|
}
|
|
6634
7118
|
};
|
|
6635
7119
|
const toProbeCoords = (clientX, clientY, fromParentViewport) => {
|
|
@@ -6744,11 +7228,20 @@ function OhhwellsBridge() {
|
|
|
6744
7228
|
return;
|
|
6745
7229
|
}
|
|
6746
7230
|
}
|
|
7231
|
+
if (activeElRef.current) {
|
|
7232
|
+
if (hoveredImageRef.current) {
|
|
7233
|
+
hoveredImageRef.current = null;
|
|
7234
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
7235
|
+
resumeAnimTracks();
|
|
7236
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
7237
|
+
}
|
|
7238
|
+
return;
|
|
7239
|
+
}
|
|
6747
7240
|
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
6748
7241
|
if (imgEl) {
|
|
6749
7242
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
6750
7243
|
const topEl = document.elementFromPoint(x, y);
|
|
6751
|
-
if (topEl?.closest(
|
|
7244
|
+
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
6752
7245
|
if (hoveredImageRef.current) {
|
|
6753
7246
|
hoveredImageRef.current = null;
|
|
6754
7247
|
resumeAnimTracks();
|
|
@@ -6796,7 +7289,9 @@ function OhhwellsBridge() {
|
|
|
6796
7289
|
postImageHover(imgEl, isDragOver, true);
|
|
6797
7290
|
}
|
|
6798
7291
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
6799
|
-
textEditable
|
|
7292
|
+
if (textEditable && !isInsideNavigationItem(textEditable)) {
|
|
7293
|
+
textEditable.setAttribute("data-ohw-hovered", "");
|
|
7294
|
+
}
|
|
6800
7295
|
return;
|
|
6801
7296
|
}
|
|
6802
7297
|
if (hoveredImageRef.current) {
|
|
@@ -6806,7 +7301,9 @@ function OhhwellsBridge() {
|
|
|
6806
7301
|
postToParentRef.current({ type: "ow:image-unhover" });
|
|
6807
7302
|
}
|
|
6808
7303
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
6809
|
-
textEditable
|
|
7304
|
+
if (textEditable && !isInsideNavigationItem(textEditable)) {
|
|
7305
|
+
textEditable.setAttribute("data-ohw-hovered", "");
|
|
7306
|
+
}
|
|
6810
7307
|
return;
|
|
6811
7308
|
}
|
|
6812
7309
|
if (hoveredGapRef.current) {
|
|
@@ -6850,7 +7347,24 @@ function OhhwellsBridge() {
|
|
|
6850
7347
|
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
6851
7348
|
});
|
|
6852
7349
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
6853
|
-
if (textEl && !textEl.hasAttribute("contenteditable"))
|
|
7350
|
+
if (textEl && !textEl.hasAttribute("contenteditable")) {
|
|
7351
|
+
const navAnchor = getNavigationItemAnchor(textEl);
|
|
7352
|
+
if (navAnchor) {
|
|
7353
|
+
const selected = selectedElRef.current;
|
|
7354
|
+
if (selected !== navAnchor && !selected?.contains(navAnchor)) {
|
|
7355
|
+
clearHrefKeyHover(navAnchor);
|
|
7356
|
+
hoveredItemElRef.current = navAnchor;
|
|
7357
|
+
setHoveredItemRect(navAnchor.getBoundingClientRect());
|
|
7358
|
+
}
|
|
7359
|
+
} else {
|
|
7360
|
+
hoveredItemElRef.current = null;
|
|
7361
|
+
setHoveredItemRect(null);
|
|
7362
|
+
textEl.setAttribute("data-ohw-hovered", "");
|
|
7363
|
+
}
|
|
7364
|
+
} else {
|
|
7365
|
+
hoveredItemElRef.current = null;
|
|
7366
|
+
setHoveredItemRect(null);
|
|
7367
|
+
}
|
|
6854
7368
|
}
|
|
6855
7369
|
};
|
|
6856
7370
|
const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
|
|
@@ -7041,7 +7555,7 @@ function OhhwellsBridge() {
|
|
|
7041
7555
|
const el = e.target;
|
|
7042
7556
|
const key = el.dataset.ohwKey;
|
|
7043
7557
|
if (!key) return;
|
|
7044
|
-
if (el === activeElRef.current) setToolbarRect(el.getBoundingClientRect());
|
|
7558
|
+
if (el === activeElRef.current) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
7045
7559
|
const maxLen = el.dataset.ohwMaxLength ? parseInt(el.dataset.ohwMaxLength, 10) : null;
|
|
7046
7560
|
if (maxLen) {
|
|
7047
7561
|
const current = el.innerText.replace(/\n$/, "").length;
|
|
@@ -7128,6 +7642,33 @@ function OhhwellsBridge() {
|
|
|
7128
7642
|
deselectRef.current();
|
|
7129
7643
|
return;
|
|
7130
7644
|
}
|
|
7645
|
+
if (e.key === "Escape" && activeElRef.current) {
|
|
7646
|
+
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
7647
|
+
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
7648
|
+
if (navAnchor) {
|
|
7649
|
+
e.preventDefault();
|
|
7650
|
+
const el2 = activeElRef.current;
|
|
7651
|
+
if (originalContentRef.current !== null) {
|
|
7652
|
+
el2.innerHTML = originalContentRef.current;
|
|
7653
|
+
}
|
|
7654
|
+
el2.removeAttribute("contenteditable");
|
|
7655
|
+
activeElRef.current = null;
|
|
7656
|
+
setMaxBadge(null);
|
|
7657
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7658
|
+
setToolbarShowEditLink(false);
|
|
7659
|
+
postToParentRef.current({ type: "ow:exit-edit" });
|
|
7660
|
+
reselectNavigationItemRef.current(navAnchor);
|
|
7661
|
+
return;
|
|
7662
|
+
}
|
|
7663
|
+
}
|
|
7664
|
+
if (e.key === "Enter" && !e.shiftKey && activeElRef.current) {
|
|
7665
|
+
const navAnchor = getNavigationItemAnchor(activeElRef.current);
|
|
7666
|
+
if (navAnchor) {
|
|
7667
|
+
e.preventDefault();
|
|
7668
|
+
commitNavigationTextEditRef.current(navAnchor);
|
|
7669
|
+
return;
|
|
7670
|
+
}
|
|
7671
|
+
}
|
|
7131
7672
|
if (e.key !== "Escape") return;
|
|
7132
7673
|
const el = activeElRef.current;
|
|
7133
7674
|
if (el && originalContentRef.current !== null) {
|
|
@@ -7143,7 +7684,8 @@ function OhhwellsBridge() {
|
|
|
7143
7684
|
const handleScroll = () => {
|
|
7144
7685
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
7145
7686
|
if (focusEl) {
|
|
7146
|
-
const
|
|
7687
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
|
|
7688
|
+
const r2 = measureEl.getBoundingClientRect();
|
|
7147
7689
|
applyToolbarPos(r2);
|
|
7148
7690
|
setToolbarRect(r2);
|
|
7149
7691
|
setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
|
|
@@ -7152,6 +7694,12 @@ function OhhwellsBridge() {
|
|
|
7152
7694
|
const rect = activeStateElRef.current.getBoundingClientRect();
|
|
7153
7695
|
setToggleState((prev) => prev ? { ...prev, rect } : null);
|
|
7154
7696
|
}
|
|
7697
|
+
if (hoveredItemElRef.current) {
|
|
7698
|
+
setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
|
|
7699
|
+
}
|
|
7700
|
+
if (siblingHintElRef.current) {
|
|
7701
|
+
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
7702
|
+
}
|
|
7155
7703
|
if (hoveredImageRef.current) {
|
|
7156
7704
|
const el = hoveredImageRef.current;
|
|
7157
7705
|
const r2 = el.getBoundingClientRect();
|
|
@@ -7271,7 +7819,7 @@ function OhhwellsBridge() {
|
|
|
7271
7819
|
};
|
|
7272
7820
|
const applyToolbarPos = (rect) => {
|
|
7273
7821
|
const ps = parentScrollRef.current;
|
|
7274
|
-
const approxW =
|
|
7822
|
+
const approxW = 330;
|
|
7275
7823
|
if (toolbarElRef.current) {
|
|
7276
7824
|
const { top, left, transform } = calcToolbarPos(rect, ps, approxW);
|
|
7277
7825
|
toolbarElRef.current.style.top = `${top}px`;
|
|
@@ -7282,6 +7830,8 @@ function OhhwellsBridge() {
|
|
|
7282
7830
|
const GAP = 6;
|
|
7283
7831
|
glowElRef.current.style.top = `${rect.top - GAP}px`;
|
|
7284
7832
|
glowElRef.current.style.left = `${rect.left - GAP}px`;
|
|
7833
|
+
glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
|
|
7834
|
+
glowElRef.current.style.height = `${rect.height + GAP * 2}px`;
|
|
7285
7835
|
}
|
|
7286
7836
|
};
|
|
7287
7837
|
const handleParentScroll = (e) => {
|
|
@@ -7292,7 +7842,10 @@ function OhhwellsBridge() {
|
|
|
7292
7842
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
7293
7843
|
}
|
|
7294
7844
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
7295
|
-
if (focusEl)
|
|
7845
|
+
if (focusEl) {
|
|
7846
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
|
|
7847
|
+
applyToolbarPos(measureEl.getBoundingClientRect());
|
|
7848
|
+
}
|
|
7296
7849
|
};
|
|
7297
7850
|
const handleClickAt = (e) => {
|
|
7298
7851
|
if (e.data?.type !== "ow:click-at") return;
|
|
@@ -7447,13 +8000,13 @@ function OhhwellsBridge() {
|
|
|
7447
8000
|
window.addEventListener("hashchange", onHashChange);
|
|
7448
8001
|
return () => window.removeEventListener("hashchange", onHashChange);
|
|
7449
8002
|
}, [pathname]);
|
|
7450
|
-
const handleCommand =
|
|
8003
|
+
const handleCommand = useCallback3((cmd) => {
|
|
7451
8004
|
document.execCommand(cmd, false);
|
|
7452
8005
|
activeElRef.current?.focus();
|
|
7453
|
-
if (activeElRef.current) setToolbarRect(activeElRef.current.getBoundingClientRect());
|
|
8006
|
+
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
7454
8007
|
refreshActiveCommandsRef.current();
|
|
7455
8008
|
}, []);
|
|
7456
|
-
const handleStateChange =
|
|
8009
|
+
const handleStateChange = useCallback3((state) => {
|
|
7457
8010
|
if (!activeStateElRef.current) return;
|
|
7458
8011
|
const el = activeStateElRef.current;
|
|
7459
8012
|
if (state === "Default") {
|
|
@@ -7466,8 +8019,8 @@ function OhhwellsBridge() {
|
|
|
7466
8019
|
}
|
|
7467
8020
|
setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
|
|
7468
8021
|
}, [deactivate]);
|
|
7469
|
-
const closeLinkPopover =
|
|
7470
|
-
const openLinkPopoverForActive =
|
|
8022
|
+
const closeLinkPopover = useCallback3(() => setLinkPopover(null), []);
|
|
8023
|
+
const openLinkPopoverForActive = useCallback3(() => {
|
|
7471
8024
|
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
7472
8025
|
if (!hrefCtx) return;
|
|
7473
8026
|
bumpLinkPopoverGrace();
|
|
@@ -7477,7 +8030,7 @@ function OhhwellsBridge() {
|
|
|
7477
8030
|
});
|
|
7478
8031
|
deactivate();
|
|
7479
8032
|
}, [deactivate]);
|
|
7480
|
-
const openLinkPopoverForSelected =
|
|
8033
|
+
const openLinkPopoverForSelected = useCallback3(() => {
|
|
7481
8034
|
const anchor = selectedElRef.current;
|
|
7482
8035
|
if (!anchor) return;
|
|
7483
8036
|
const key = anchor.getAttribute("data-ohw-href-key");
|
|
@@ -7489,7 +8042,7 @@ function OhhwellsBridge() {
|
|
|
7489
8042
|
});
|
|
7490
8043
|
deselect();
|
|
7491
8044
|
}, [deselect]);
|
|
7492
|
-
const handleLinkPopoverSubmit =
|
|
8045
|
+
const handleLinkPopoverSubmit = useCallback3(
|
|
7493
8046
|
(target) => {
|
|
7494
8047
|
if (!linkPopover) return;
|
|
7495
8048
|
const { key } = linkPopover;
|
|
@@ -7503,37 +8056,55 @@ function OhhwellsBridge() {
|
|
|
7503
8056
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
7504
8057
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
7505
8058
|
return bridgeRoot ? createPortal(
|
|
7506
|
-
/* @__PURE__ */
|
|
7507
|
-
/* @__PURE__ */
|
|
7508
|
-
|
|
7509
|
-
|
|
7510
|
-
|
|
7511
|
-
|
|
8059
|
+
/* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
8060
|
+
/* @__PURE__ */ jsx21("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
8061
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ jsx21(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
8062
|
+
hoveredItemRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx21(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
8063
|
+
toolbarRect && toolbarVariant === "link-action" && /* @__PURE__ */ jsx21(
|
|
8064
|
+
ItemInteractionLayer,
|
|
8065
|
+
{
|
|
8066
|
+
rect: toolbarRect,
|
|
8067
|
+
elRef: glowElRef,
|
|
8068
|
+
state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
|
|
8069
|
+
showHandle: Boolean(reorderHrefKey),
|
|
8070
|
+
dragDisabled: reorderDragDisabled,
|
|
8071
|
+
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
8072
|
+
onDragHandleDragStart: handleItemDragStart,
|
|
8073
|
+
onDragHandleDragEnd: handleItemDragEnd,
|
|
8074
|
+
toolbar: isItemDragging ? void 0 : /* @__PURE__ */ jsx21(
|
|
8075
|
+
ItemActionToolbar,
|
|
8076
|
+
{
|
|
8077
|
+
onEditLink: openLinkPopoverForSelected,
|
|
8078
|
+
onAddItem: handleAddNavigationItem,
|
|
8079
|
+
addItemDisabled: false
|
|
8080
|
+
}
|
|
8081
|
+
)
|
|
8082
|
+
}
|
|
8083
|
+
),
|
|
8084
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
8085
|
+
/* @__PURE__ */ jsx21(
|
|
8086
|
+
EditGlowChrome,
|
|
7512
8087
|
{
|
|
7513
|
-
variant: "rich-text",
|
|
7514
8088
|
rect: toolbarRect,
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
activeCommands,
|
|
7519
|
-
showEditLink,
|
|
7520
|
-
onEditLink: openLinkPopoverForActive
|
|
8089
|
+
elRef: glowElRef,
|
|
8090
|
+
reorderHrefKey,
|
|
8091
|
+
dragDisabled: reorderDragDisabled
|
|
7521
8092
|
}
|
|
7522
8093
|
),
|
|
7523
|
-
|
|
8094
|
+
/* @__PURE__ */ jsx21(
|
|
7524
8095
|
FloatingToolbar,
|
|
7525
8096
|
{
|
|
7526
|
-
variant: "link-action",
|
|
7527
8097
|
rect: toolbarRect,
|
|
7528
8098
|
parentScroll: parentScrollRef.current,
|
|
7529
8099
|
elRef: toolbarElRef,
|
|
7530
8100
|
onCommand: handleCommand,
|
|
7531
8101
|
activeCommands,
|
|
7532
|
-
|
|
8102
|
+
showEditLink,
|
|
8103
|
+
onEditLink: openLinkPopoverForActive
|
|
7533
8104
|
}
|
|
7534
8105
|
)
|
|
7535
8106
|
] }),
|
|
7536
|
-
maxBadge && /* @__PURE__ */
|
|
8107
|
+
maxBadge && /* @__PURE__ */ jsxs11(
|
|
7537
8108
|
"div",
|
|
7538
8109
|
{
|
|
7539
8110
|
"data-ohw-max-badge": "",
|
|
@@ -7559,7 +8130,7 @@ function OhhwellsBridge() {
|
|
|
7559
8130
|
]
|
|
7560
8131
|
}
|
|
7561
8132
|
),
|
|
7562
|
-
toggleState && /* @__PURE__ */
|
|
8133
|
+
toggleState && /* @__PURE__ */ jsx21(
|
|
7563
8134
|
StateToggle,
|
|
7564
8135
|
{
|
|
7565
8136
|
rect: toggleState.rect,
|
|
@@ -7568,15 +8139,15 @@ function OhhwellsBridge() {
|
|
|
7568
8139
|
onStateChange: handleStateChange
|
|
7569
8140
|
}
|
|
7570
8141
|
),
|
|
7571
|
-
sectionGap && /* @__PURE__ */
|
|
8142
|
+
sectionGap && /* @__PURE__ */ jsxs11(
|
|
7572
8143
|
"div",
|
|
7573
8144
|
{
|
|
7574
8145
|
"data-ohw-section-insert-line": "",
|
|
7575
8146
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
7576
8147
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
7577
8148
|
children: [
|
|
7578
|
-
/* @__PURE__ */
|
|
7579
|
-
/* @__PURE__ */
|
|
8149
|
+
/* @__PURE__ */ jsx21("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
8150
|
+
/* @__PURE__ */ jsx21(
|
|
7580
8151
|
Badge,
|
|
7581
8152
|
{
|
|
7582
8153
|
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",
|
|
@@ -7589,11 +8160,11 @@ function OhhwellsBridge() {
|
|
|
7589
8160
|
children: "Add Section"
|
|
7590
8161
|
}
|
|
7591
8162
|
),
|
|
7592
|
-
/* @__PURE__ */
|
|
8163
|
+
/* @__PURE__ */ jsx21("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
7593
8164
|
]
|
|
7594
8165
|
}
|
|
7595
8166
|
),
|
|
7596
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */
|
|
8167
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx21(
|
|
7597
8168
|
LinkPopover,
|
|
7598
8169
|
{
|
|
7599
8170
|
panelRef: linkPopoverPanelRef,
|
|
@@ -7608,12 +8179,43 @@ function OhhwellsBridge() {
|
|
|
7608
8179
|
onSubmit: handleLinkPopoverSubmit
|
|
7609
8180
|
},
|
|
7610
8181
|
`${linkPopover.key}-${pathname}`
|
|
7611
|
-
) : null
|
|
8182
|
+
) : null,
|
|
8183
|
+
sectionGap && /* @__PURE__ */ jsxs11(
|
|
8184
|
+
"div",
|
|
8185
|
+
{
|
|
8186
|
+
"data-ohw-section-insert-line": "",
|
|
8187
|
+
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8188
|
+
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8189
|
+
children: [
|
|
8190
|
+
/* @__PURE__ */ jsx21("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
8191
|
+
/* @__PURE__ */ jsx21(
|
|
8192
|
+
Badge,
|
|
8193
|
+
{
|
|
8194
|
+
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",
|
|
8195
|
+
onClick: () => {
|
|
8196
|
+
window.parent.postMessage(
|
|
8197
|
+
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
8198
|
+
"*"
|
|
8199
|
+
);
|
|
8200
|
+
},
|
|
8201
|
+
children: "Add Section"
|
|
8202
|
+
}
|
|
8203
|
+
),
|
|
8204
|
+
/* @__PURE__ */ jsx21("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8205
|
+
]
|
|
8206
|
+
}
|
|
8207
|
+
)
|
|
7612
8208
|
] }),
|
|
7613
8209
|
bridgeRoot
|
|
7614
8210
|
) : null;
|
|
7615
8211
|
}
|
|
7616
8212
|
export {
|
|
8213
|
+
CustomToolbar,
|
|
8214
|
+
CustomToolbarButton,
|
|
8215
|
+
CustomToolbarDivider,
|
|
8216
|
+
DragHandle,
|
|
8217
|
+
ItemActionToolbar,
|
|
8218
|
+
ItemInteractionLayer,
|
|
7617
8219
|
LinkEditorPanel,
|
|
7618
8220
|
LinkPopover,
|
|
7619
8221
|
OhhwellsBridge,
|
|
@@ -7621,9 +8223,14 @@ export {
|
|
|
7621
8223
|
Toggle,
|
|
7622
8224
|
ToggleGroup,
|
|
7623
8225
|
ToggleGroupItem,
|
|
8226
|
+
Tooltip,
|
|
8227
|
+
TooltipContent,
|
|
8228
|
+
TooltipProvider,
|
|
8229
|
+
TooltipTrigger,
|
|
7624
8230
|
buildTarget,
|
|
7625
8231
|
filterAvailablePages,
|
|
7626
8232
|
getEditModeInitialState,
|
|
8233
|
+
isEditSessionActive,
|
|
7627
8234
|
isValidUrl,
|
|
7628
8235
|
parseTarget,
|
|
7629
8236
|
toggleVariants,
|