@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.cjs
CHANGED
|
@@ -31,6 +31,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
// src/index.ts
|
|
32
32
|
var index_exports = {};
|
|
33
33
|
__export(index_exports, {
|
|
34
|
+
CustomToolbar: () => CustomToolbar,
|
|
35
|
+
CustomToolbarButton: () => CustomToolbarButton,
|
|
36
|
+
CustomToolbarDivider: () => CustomToolbarDivider,
|
|
37
|
+
DragHandle: () => DragHandle,
|
|
38
|
+
ItemActionToolbar: () => ItemActionToolbar,
|
|
39
|
+
ItemInteractionLayer: () => ItemInteractionLayer,
|
|
34
40
|
LinkEditorPanel: () => LinkEditorPanel,
|
|
35
41
|
LinkPopover: () => LinkPopover,
|
|
36
42
|
OhhwellsBridge: () => OhhwellsBridge,
|
|
@@ -38,9 +44,14 @@ __export(index_exports, {
|
|
|
38
44
|
Toggle: () => Toggle,
|
|
39
45
|
ToggleGroup: () => ToggleGroup,
|
|
40
46
|
ToggleGroupItem: () => ToggleGroupItem,
|
|
47
|
+
Tooltip: () => Tooltip,
|
|
48
|
+
TooltipContent: () => TooltipContent,
|
|
49
|
+
TooltipProvider: () => TooltipProvider,
|
|
50
|
+
TooltipTrigger: () => TooltipTrigger,
|
|
41
51
|
buildTarget: () => buildTarget,
|
|
42
52
|
filterAvailablePages: () => filterAvailablePages,
|
|
43
53
|
getEditModeInitialState: () => getEditModeInitialState,
|
|
54
|
+
isEditSessionActive: () => isEditSessionActive,
|
|
44
55
|
isValidUrl: () => isValidUrl,
|
|
45
56
|
parseTarget: () => parseTarget,
|
|
46
57
|
toggleVariants: () => toggleVariants,
|
|
@@ -99,6 +110,7 @@ var import_react3 = require("react");
|
|
|
99
110
|
var import_react2 = require("react");
|
|
100
111
|
var import_radix_ui = require("radix-ui");
|
|
101
112
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
113
|
+
var isValidEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
|
|
102
114
|
function Spinner() {
|
|
103
115
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
104
116
|
"svg",
|
|
@@ -132,12 +144,17 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
132
144
|
const [error, setError] = (0, import_react2.useState)(null);
|
|
133
145
|
const isBook = title === "Confirm your spot";
|
|
134
146
|
const handleSubmit = async () => {
|
|
135
|
-
|
|
147
|
+
const trimmed = email.trim();
|
|
148
|
+
if (!trimmed) return;
|
|
149
|
+
if (!isValidEmail(trimmed)) {
|
|
150
|
+
setError("Please enter a valid email address.");
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
136
153
|
setLoading(true);
|
|
137
154
|
setError(null);
|
|
138
155
|
try {
|
|
139
|
-
await onSubmit(
|
|
140
|
-
setSubmittedEmail(
|
|
156
|
+
await onSubmit(trimmed);
|
|
157
|
+
setSubmittedEmail(trimmed);
|
|
141
158
|
setSuccess(true);
|
|
142
159
|
} catch (e) {
|
|
143
160
|
setError(e instanceof Error ? e.message : "Something went wrong. Please try again.");
|
|
@@ -212,7 +229,10 @@ function EmailCaptureModal({ title, subtitle, onSubmit, onClose }) {
|
|
|
212
229
|
{
|
|
213
230
|
type: "email",
|
|
214
231
|
value: email,
|
|
215
|
-
onChange: (e) =>
|
|
232
|
+
onChange: (e) => {
|
|
233
|
+
setEmail(e.target.value);
|
|
234
|
+
if (error) setError(null);
|
|
235
|
+
},
|
|
216
236
|
onKeyDown: handleKeyDown,
|
|
217
237
|
placeholder: "hello@gmail.com",
|
|
218
238
|
autoFocus: true,
|
|
@@ -269,12 +289,20 @@ function formatClassTime(cls) {
|
|
|
269
289
|
const em = endTotal % 60;
|
|
270
290
|
return `${h}:${cls.startTime.minutes}-${eh}:${String(em).padStart(2, "0")}`;
|
|
271
291
|
}
|
|
292
|
+
function formatBookingLabel(cls) {
|
|
293
|
+
const price = cls.price;
|
|
294
|
+
const isFree = price === null || price === void 0 || `${price}` === "" || `${price}` === "0";
|
|
295
|
+
return isFree ? "Book for free" : `Book for ${cls.currency ?? ""} ${price}`.trim();
|
|
296
|
+
}
|
|
272
297
|
function getBookingsOnDate(cls, date) {
|
|
273
298
|
if (!cls.bookings?.length) return 0;
|
|
274
|
-
const
|
|
299
|
+
const target = new Date(date);
|
|
300
|
+
target.setHours(0, 0, 0, 0);
|
|
275
301
|
return cls.bookings.filter((b) => {
|
|
276
302
|
try {
|
|
277
|
-
|
|
303
|
+
const bookingDate = new Date(b.classDate);
|
|
304
|
+
bookingDate.setHours(0, 0, 0, 0);
|
|
305
|
+
return bookingDate.getTime() === target.getTime();
|
|
278
306
|
} catch {
|
|
279
307
|
return false;
|
|
280
308
|
}
|
|
@@ -578,7 +606,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
|
|
|
578
606
|
if (!cls.id) return;
|
|
579
607
|
onOpenModal?.(isFull ? "waitlist" : "book", cls.id, selectedDate);
|
|
580
608
|
},
|
|
581
|
-
children: isFull ? "Join Waitlist" :
|
|
609
|
+
children: isFull ? "Join Waitlist" : formatBookingLabel(cls)
|
|
582
610
|
}
|
|
583
611
|
)
|
|
584
612
|
] })
|
|
@@ -620,6 +648,17 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
620
648
|
const [isHovered, setIsHovered] = (0, import_react3.useState)(false);
|
|
621
649
|
const [modalState, setModalState] = (0, import_react3.useState)(null);
|
|
622
650
|
const switchScheduleIdRef = (0, import_react3.useRef)(null);
|
|
651
|
+
const liveScheduleIdRef = (0, import_react3.useRef)(null);
|
|
652
|
+
const refetchLiveSchedule = (0, import_react3.useCallback)(async () => {
|
|
653
|
+
const id = liveScheduleIdRef.current;
|
|
654
|
+
if (!id) return;
|
|
655
|
+
try {
|
|
656
|
+
const res = await fetch(`${API_URL}/api/schedule/id/${id}`);
|
|
657
|
+
const data = await res.json();
|
|
658
|
+
if (data?.id) setSchedule(data);
|
|
659
|
+
} catch {
|
|
660
|
+
}
|
|
661
|
+
}, []);
|
|
623
662
|
const dates = (0, import_react3.useMemo)(() => {
|
|
624
663
|
const today = /* @__PURE__ */ new Date();
|
|
625
664
|
today.setHours(0, 0, 0, 0);
|
|
@@ -639,6 +678,18 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
639
678
|
}
|
|
640
679
|
}
|
|
641
680
|
}, [schedule, dates]);
|
|
681
|
+
(0, import_react3.useEffect)(() => {
|
|
682
|
+
if (typeof window === "undefined") return;
|
|
683
|
+
const onVisible = () => {
|
|
684
|
+
if (!document.hidden) void refetchLiveSchedule();
|
|
685
|
+
};
|
|
686
|
+
window.addEventListener("focus", refetchLiveSchedule);
|
|
687
|
+
document.addEventListener("visibilitychange", onVisible);
|
|
688
|
+
return () => {
|
|
689
|
+
window.removeEventListener("focus", refetchLiveSchedule);
|
|
690
|
+
document.removeEventListener("visibilitychange", onVisible);
|
|
691
|
+
};
|
|
692
|
+
}, [refetchLiveSchedule]);
|
|
642
693
|
(0, import_react3.useEffect)(() => {
|
|
643
694
|
if (typeof window === "undefined") return;
|
|
644
695
|
const isInEditor = window.self !== window.top;
|
|
@@ -700,7 +751,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
700
751
|
setLoading(false);
|
|
701
752
|
return;
|
|
702
753
|
}
|
|
703
|
-
;
|
|
754
|
+
liveScheduleIdRef.current = effectiveId;
|
|
704
755
|
(async () => {
|
|
705
756
|
try {
|
|
706
757
|
const res = await fetch(`${API_URL}/api/schedule/id/${effectiveId}`);
|
|
@@ -757,18 +808,14 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
757
808
|
const data = await res.json().catch(() => ({}));
|
|
758
809
|
throw new Error(data?.message ?? "Something went wrong. Please try again.");
|
|
759
810
|
}
|
|
811
|
+
await refetchLiveSchedule();
|
|
760
812
|
};
|
|
761
813
|
const handleReplaceSchedule = () => {
|
|
762
814
|
setIsHovered(false);
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
insertAfter
|
|
768
|
-
}, "*");
|
|
769
|
-
} else {
|
|
770
|
-
window.parent.postMessage({ type: "ow:scheduling-not-connected", insertAfter }, "*");
|
|
771
|
-
}
|
|
815
|
+
window.parent.postMessage(
|
|
816
|
+
{ type: "ow:scheduling-not-connected", insertAfter, currentScheduleId: schedule?.id },
|
|
817
|
+
"*"
|
|
818
|
+
);
|
|
772
819
|
};
|
|
773
820
|
if (!inEditor && !loading && !schedule) return null;
|
|
774
821
|
const sectionId = `scheduling-${insertAfter}`;
|
|
@@ -811,7 +858,19 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
811
858
|
),
|
|
812
859
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "max-w-[1280px] mx-auto flex flex-col items-center gap-16", children: [
|
|
813
860
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
|
|
814
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
861
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
862
|
+
"h2",
|
|
863
|
+
{
|
|
864
|
+
className: "font-display text-center m-0 text-(--color-dark,#200C02)",
|
|
865
|
+
style: {
|
|
866
|
+
fontSize: "var(--fs-section-h2, clamp(40px, 4.4vw, 64px))",
|
|
867
|
+
fontWeight: "var(--font-weight-heading, 400)",
|
|
868
|
+
lineHeight: 1.05,
|
|
869
|
+
letterSpacing: "-0.02em"
|
|
870
|
+
},
|
|
871
|
+
children: schedule?.name ?? "Book an appointment"
|
|
872
|
+
}
|
|
873
|
+
),
|
|
815
874
|
schedule?.description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "font-body text-body text-center m-0 text-(--color-accent,#A89B83)", children: schedule.description })
|
|
816
875
|
] }),
|
|
817
876
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "w-full flex flex-col items-end gap-3", children: [
|
|
@@ -4250,6 +4309,336 @@ function ToggleGroupItem({
|
|
|
4250
4309
|
);
|
|
4251
4310
|
}
|
|
4252
4311
|
|
|
4312
|
+
// src/ui/drag-handle.tsx
|
|
4313
|
+
var React3 = __toESM(require("react"), 1);
|
|
4314
|
+
var import_lucide_react = require("lucide-react");
|
|
4315
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
4316
|
+
var DragHandle = React3.forwardRef(
|
|
4317
|
+
({ className, type = "button", ...props }, ref) => {
|
|
4318
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4319
|
+
"button",
|
|
4320
|
+
{
|
|
4321
|
+
ref,
|
|
4322
|
+
type,
|
|
4323
|
+
"data-slot": "drag-handle",
|
|
4324
|
+
className: cn(
|
|
4325
|
+
"inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-[30px]",
|
|
4326
|
+
"bg-white border border-transparent text-stone-500 shadow-md cursor-grab",
|
|
4327
|
+
"enabled:hover:border enabled:hover:border-stone-200 enabled:hover:text-stone-950",
|
|
4328
|
+
"enabled:active:border enabled:active:border-primary enabled:active:bg-primary-50 enabled:active:text-stone-950 enabled:active:shadow enabled:active:cursor-grabbing",
|
|
4329
|
+
"disabled:cursor-not-allowed disabled:opacity-40 disabled:text-stone-950 disabled:pointer-events-none",
|
|
4330
|
+
className
|
|
4331
|
+
),
|
|
4332
|
+
...props,
|
|
4333
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.GripVertical, { className: "size-4 shrink-0", "aria-hidden": "true" })
|
|
4334
|
+
}
|
|
4335
|
+
);
|
|
4336
|
+
}
|
|
4337
|
+
);
|
|
4338
|
+
DragHandle.displayName = "DragHandle";
|
|
4339
|
+
|
|
4340
|
+
// src/ui/custom-toolbar.tsx
|
|
4341
|
+
var React4 = __toESM(require("react"), 1);
|
|
4342
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
4343
|
+
var CustomToolbar = React4.forwardRef(({ className, onMouseDown, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4344
|
+
"div",
|
|
4345
|
+
{
|
|
4346
|
+
ref,
|
|
4347
|
+
"data-ohw-toolbar": "",
|
|
4348
|
+
className: cn(
|
|
4349
|
+
"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)]",
|
|
4350
|
+
className
|
|
4351
|
+
),
|
|
4352
|
+
onMouseDown: (e) => {
|
|
4353
|
+
e.stopPropagation();
|
|
4354
|
+
onMouseDown?.(e);
|
|
4355
|
+
},
|
|
4356
|
+
...props
|
|
4357
|
+
}
|
|
4358
|
+
));
|
|
4359
|
+
CustomToolbar.displayName = "CustomToolbar";
|
|
4360
|
+
function CustomToolbarDivider({ className, ...props }) {
|
|
4361
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4362
|
+
"span",
|
|
4363
|
+
{
|
|
4364
|
+
"aria-hidden": true,
|
|
4365
|
+
className: cn("block h-6 w-px shrink-0 bg-border", className),
|
|
4366
|
+
...props
|
|
4367
|
+
}
|
|
4368
|
+
);
|
|
4369
|
+
}
|
|
4370
|
+
var CustomToolbarButton = React4.forwardRef(
|
|
4371
|
+
({ className, active = false, type = "button", ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4372
|
+
"button",
|
|
4373
|
+
{
|
|
4374
|
+
ref,
|
|
4375
|
+
type,
|
|
4376
|
+
className: cn(
|
|
4377
|
+
"inline-flex shrink-0 items-center justify-center rounded p-1.5 transition-colors",
|
|
4378
|
+
active ? "bg-primary text-primary-foreground" : "bg-transparent text-foreground hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
4379
|
+
className
|
|
4380
|
+
),
|
|
4381
|
+
...props
|
|
4382
|
+
}
|
|
4383
|
+
)
|
|
4384
|
+
);
|
|
4385
|
+
CustomToolbarButton.displayName = "CustomToolbarButton";
|
|
4386
|
+
|
|
4387
|
+
// src/ui/item-action-toolbar.tsx
|
|
4388
|
+
var import_lucide_react2 = require("lucide-react");
|
|
4389
|
+
|
|
4390
|
+
// src/ui/tooltip.tsx
|
|
4391
|
+
var import_radix_ui3 = require("radix-ui");
|
|
4392
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
4393
|
+
function TooltipProvider({
|
|
4394
|
+
delayDuration = 0,
|
|
4395
|
+
...props
|
|
4396
|
+
}) {
|
|
4397
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Tooltip.Provider, { "data-slot": "tooltip-provider", delayDuration, ...props });
|
|
4398
|
+
}
|
|
4399
|
+
function Tooltip({ ...props }) {
|
|
4400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Tooltip.Root, { "data-slot": "tooltip", ...props });
|
|
4401
|
+
}
|
|
4402
|
+
function TooltipTrigger({ ...props }) {
|
|
4403
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Tooltip.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
4404
|
+
}
|
|
4405
|
+
var arrowClassBySide = {
|
|
4406
|
+
top: "before:bottom-0 before:left-1/2 before:-translate-x-1/2 before:translate-y-1/2",
|
|
4407
|
+
bottom: "before:top-0 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2",
|
|
4408
|
+
left: "before:right-0 before:top-1/2 before:-translate-y-1/2 before:translate-x-1/2",
|
|
4409
|
+
right: "before:left-0 before:top-1/2 before:-translate-y-1/2 before:-translate-x-1/2"
|
|
4410
|
+
};
|
|
4411
|
+
function TooltipContent({
|
|
4412
|
+
className,
|
|
4413
|
+
sideOffset = 6,
|
|
4414
|
+
side = "bottom",
|
|
4415
|
+
children,
|
|
4416
|
+
...props
|
|
4417
|
+
}) {
|
|
4418
|
+
const resolvedSide = side ?? "bottom";
|
|
4419
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Tooltip.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4420
|
+
import_radix_ui3.Tooltip.Content,
|
|
4421
|
+
{
|
|
4422
|
+
"data-slot": "tooltip-content",
|
|
4423
|
+
side,
|
|
4424
|
+
sideOffset,
|
|
4425
|
+
className: cn(
|
|
4426
|
+
"relative z-[2147483647] w-fit max-w-xs rounded-md bg-foreground px-3 py-1.5 text-xs text-background shadow-md",
|
|
4427
|
+
'before:pointer-events-none before:absolute before:size-2 before:rotate-45 before:bg-foreground before:content-[""]',
|
|
4428
|
+
arrowClassBySide[resolvedSide],
|
|
4429
|
+
"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",
|
|
4430
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2",
|
|
4431
|
+
"data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2",
|
|
4432
|
+
className
|
|
4433
|
+
),
|
|
4434
|
+
...props,
|
|
4435
|
+
children
|
|
4436
|
+
}
|
|
4437
|
+
) });
|
|
4438
|
+
}
|
|
4439
|
+
|
|
4440
|
+
// src/ui/item-action-toolbar.tsx
|
|
4441
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
4442
|
+
function ToolbarActionTooltip({
|
|
4443
|
+
label,
|
|
4444
|
+
side = "bottom",
|
|
4445
|
+
disabled = false,
|
|
4446
|
+
buttonProps,
|
|
4447
|
+
children
|
|
4448
|
+
}) {
|
|
4449
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, ...buttonProps, children });
|
|
4450
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Tooltip, { children: [
|
|
4451
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "inline-flex", children: button }) : button }),
|
|
4452
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipContent, { side, children: label })
|
|
4453
|
+
] });
|
|
4454
|
+
}
|
|
4455
|
+
function ItemActionToolbar({
|
|
4456
|
+
onEditLink,
|
|
4457
|
+
onAddItem,
|
|
4458
|
+
onMore,
|
|
4459
|
+
addItemDisabled = true,
|
|
4460
|
+
moreDisabled = true,
|
|
4461
|
+
tooltipSide = "bottom"
|
|
4462
|
+
}) {
|
|
4463
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CustomToolbar, { children: [
|
|
4464
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4465
|
+
ToolbarActionTooltip,
|
|
4466
|
+
{
|
|
4467
|
+
label: "Add link",
|
|
4468
|
+
side: tooltipSide,
|
|
4469
|
+
buttonProps: {
|
|
4470
|
+
onMouseDown: (e) => {
|
|
4471
|
+
e.preventDefault();
|
|
4472
|
+
e.stopPropagation();
|
|
4473
|
+
onEditLink?.();
|
|
4474
|
+
},
|
|
4475
|
+
onClick: (e) => {
|
|
4476
|
+
e.preventDefault();
|
|
4477
|
+
e.stopPropagation();
|
|
4478
|
+
}
|
|
4479
|
+
},
|
|
4480
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4481
|
+
}
|
|
4482
|
+
),
|
|
4483
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CustomToolbarDivider, {}),
|
|
4484
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4485
|
+
ToolbarActionTooltip,
|
|
4486
|
+
{
|
|
4487
|
+
label: "Add item",
|
|
4488
|
+
side: tooltipSide,
|
|
4489
|
+
disabled: addItemDisabled,
|
|
4490
|
+
buttonProps: {
|
|
4491
|
+
onMouseDown: (e) => {
|
|
4492
|
+
if (addItemDisabled) return;
|
|
4493
|
+
e.preventDefault();
|
|
4494
|
+
e.stopPropagation();
|
|
4495
|
+
onAddItem?.();
|
|
4496
|
+
}
|
|
4497
|
+
},
|
|
4498
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Plus, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4499
|
+
}
|
|
4500
|
+
),
|
|
4501
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CustomToolbarDivider, {}),
|
|
4502
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
4503
|
+
ToolbarActionTooltip,
|
|
4504
|
+
{
|
|
4505
|
+
label: "More",
|
|
4506
|
+
side: tooltipSide,
|
|
4507
|
+
disabled: moreDisabled,
|
|
4508
|
+
buttonProps: {
|
|
4509
|
+
onMouseDown: (e) => {
|
|
4510
|
+
if (moreDisabled) return;
|
|
4511
|
+
e.preventDefault();
|
|
4512
|
+
e.stopPropagation();
|
|
4513
|
+
onMore?.();
|
|
4514
|
+
}
|
|
4515
|
+
},
|
|
4516
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.MoreHorizontal, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
4517
|
+
}
|
|
4518
|
+
)
|
|
4519
|
+
] }) });
|
|
4520
|
+
}
|
|
4521
|
+
|
|
4522
|
+
// src/ui/item-interaction-layer.tsx
|
|
4523
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
4524
|
+
var PRIMARY = "var(--ohw-primary, #0885FE)";
|
|
4525
|
+
var FOCUS_RING = "0 0 0 4px rgba(8, 133, 254, 0.12)";
|
|
4526
|
+
var DRAG_SHADOW = "0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.1)";
|
|
4527
|
+
function getChromeStyle(state) {
|
|
4528
|
+
switch (state) {
|
|
4529
|
+
case "hover":
|
|
4530
|
+
return {
|
|
4531
|
+
border: `1.5px dashed ${PRIMARY}`,
|
|
4532
|
+
boxShadow: "none"
|
|
4533
|
+
};
|
|
4534
|
+
case "sibling-hint":
|
|
4535
|
+
return {
|
|
4536
|
+
border: `1.5px dashed color-mix(in srgb, ${PRIMARY} 30%, transparent)`,
|
|
4537
|
+
boxShadow: "none"
|
|
4538
|
+
};
|
|
4539
|
+
case "active-top":
|
|
4540
|
+
case "active-bottom":
|
|
4541
|
+
return {
|
|
4542
|
+
border: `2px solid ${PRIMARY}`,
|
|
4543
|
+
boxShadow: FOCUS_RING
|
|
4544
|
+
};
|
|
4545
|
+
case "dragging":
|
|
4546
|
+
return {
|
|
4547
|
+
border: `2px solid ${PRIMARY}`,
|
|
4548
|
+
boxShadow: DRAG_SHADOW
|
|
4549
|
+
};
|
|
4550
|
+
default:
|
|
4551
|
+
return {};
|
|
4552
|
+
}
|
|
4553
|
+
}
|
|
4554
|
+
function ItemInteractionLayer({
|
|
4555
|
+
rect,
|
|
4556
|
+
state,
|
|
4557
|
+
elRef,
|
|
4558
|
+
toolbar,
|
|
4559
|
+
showHandle = false,
|
|
4560
|
+
dragDisabled = false,
|
|
4561
|
+
dragHandleLabel = "Reorder item",
|
|
4562
|
+
onDragHandleDragStart,
|
|
4563
|
+
onDragHandleDragEnd,
|
|
4564
|
+
chromeGap = 6,
|
|
4565
|
+
className
|
|
4566
|
+
}) {
|
|
4567
|
+
if (state === "default") return null;
|
|
4568
|
+
const isActive = state === "active-top" || state === "active-bottom";
|
|
4569
|
+
const isDragging = state === "dragging";
|
|
4570
|
+
const showToolbar = isActive && toolbar;
|
|
4571
|
+
const showDragHandle = isActive && showHandle && !isDragging;
|
|
4572
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4573
|
+
"div",
|
|
4574
|
+
{
|
|
4575
|
+
ref: elRef,
|
|
4576
|
+
"data-ohw-item-interaction": "",
|
|
4577
|
+
"data-ohw-item-interaction-state": state,
|
|
4578
|
+
className: cn("pointer-events-none", className),
|
|
4579
|
+
style: {
|
|
4580
|
+
position: "fixed",
|
|
4581
|
+
top: rect.top - chromeGap,
|
|
4582
|
+
left: rect.left - chromeGap,
|
|
4583
|
+
width: rect.width + chromeGap * 2,
|
|
4584
|
+
height: rect.height + chromeGap * 2,
|
|
4585
|
+
zIndex: 2147483646
|
|
4586
|
+
},
|
|
4587
|
+
children: [
|
|
4588
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4589
|
+
"div",
|
|
4590
|
+
{
|
|
4591
|
+
"aria-hidden": true,
|
|
4592
|
+
className: "absolute inset-0 rounded-lg",
|
|
4593
|
+
style: getChromeStyle(state)
|
|
4594
|
+
}
|
|
4595
|
+
),
|
|
4596
|
+
showDragHandle && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4597
|
+
"div",
|
|
4598
|
+
{
|
|
4599
|
+
"data-ohw-drag-handle-container": "",
|
|
4600
|
+
className: "pointer-events-auto absolute left-0 top-1/2 -translate-x-[calc(100%+7px)] -translate-y-1/2",
|
|
4601
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4602
|
+
DragHandle,
|
|
4603
|
+
{
|
|
4604
|
+
draggable: !dragDisabled,
|
|
4605
|
+
"aria-label": dragHandleLabel,
|
|
4606
|
+
disabled: dragDisabled,
|
|
4607
|
+
onDragStart: (e) => {
|
|
4608
|
+
if (dragDisabled) {
|
|
4609
|
+
e.preventDefault();
|
|
4610
|
+
return;
|
|
4611
|
+
}
|
|
4612
|
+
e.dataTransfer?.setData("text/plain", dragHandleLabel);
|
|
4613
|
+
e.dataTransfer.effectAllowed = "move";
|
|
4614
|
+
onDragHandleDragStart?.(e);
|
|
4615
|
+
},
|
|
4616
|
+
onDragEnd: onDragHandleDragEnd
|
|
4617
|
+
}
|
|
4618
|
+
)
|
|
4619
|
+
}
|
|
4620
|
+
),
|
|
4621
|
+
showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4622
|
+
"div",
|
|
4623
|
+
{
|
|
4624
|
+
className: "pointer-events-auto absolute bottom-full left-1/2 mb-2 -translate-x-1/2",
|
|
4625
|
+
"data-ohw-item-toolbar-anchor": "top",
|
|
4626
|
+
children: toolbar
|
|
4627
|
+
}
|
|
4628
|
+
),
|
|
4629
|
+
showToolbar && state === "active-bottom" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4630
|
+
"div",
|
|
4631
|
+
{
|
|
4632
|
+
className: "pointer-events-auto absolute left-1/2 top-full mt-2 -translate-x-1/2",
|
|
4633
|
+
"data-ohw-item-toolbar-anchor": "bottom",
|
|
4634
|
+
children: toolbar
|
|
4635
|
+
}
|
|
4636
|
+
)
|
|
4637
|
+
]
|
|
4638
|
+
}
|
|
4639
|
+
);
|
|
4640
|
+
}
|
|
4641
|
+
|
|
4253
4642
|
// src/OhhwellsBridge.tsx
|
|
4254
4643
|
var import_react_dom2 = require("react-dom");
|
|
4255
4644
|
var import_navigation = require("next/navigation");
|
|
@@ -4529,61 +4918,61 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
4529
4918
|
}
|
|
4530
4919
|
|
|
4531
4920
|
// src/ui/dialog.tsx
|
|
4532
|
-
var
|
|
4533
|
-
var
|
|
4921
|
+
var React5 = __toESM(require("react"), 1);
|
|
4922
|
+
var import_radix_ui4 = require("radix-ui");
|
|
4534
4923
|
|
|
4535
4924
|
// src/ui/icons.tsx
|
|
4536
|
-
var
|
|
4925
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4537
4926
|
function IconX({ className, ...props }) {
|
|
4538
|
-
return /* @__PURE__ */ (0,
|
|
4539
|
-
/* @__PURE__ */ (0,
|
|
4540
|
-
/* @__PURE__ */ (0,
|
|
4927
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4928
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M18 6 6 18" }),
|
|
4929
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m6 6 12 12" })
|
|
4541
4930
|
] });
|
|
4542
4931
|
}
|
|
4543
4932
|
function IconChevronDown({ className, ...props }) {
|
|
4544
|
-
return /* @__PURE__ */ (0,
|
|
4933
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m6 9 6 6 6-6" }) });
|
|
4545
4934
|
}
|
|
4546
4935
|
function IconFile({ className, ...props }) {
|
|
4547
|
-
return /* @__PURE__ */ (0,
|
|
4548
|
-
/* @__PURE__ */ (0,
|
|
4549
|
-
/* @__PURE__ */ (0,
|
|
4936
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4937
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
4938
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
4550
4939
|
] });
|
|
4551
4940
|
}
|
|
4552
4941
|
function IconInfo({ className, ...props }) {
|
|
4553
|
-
return /* @__PURE__ */ (0,
|
|
4554
|
-
/* @__PURE__ */ (0,
|
|
4555
|
-
/* @__PURE__ */ (0,
|
|
4556
|
-
/* @__PURE__ */ (0,
|
|
4942
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4943
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
4944
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 16v-4" }),
|
|
4945
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 8h.01" })
|
|
4557
4946
|
] });
|
|
4558
4947
|
}
|
|
4559
4948
|
function IconArrowRight({ className, ...props }) {
|
|
4560
|
-
return /* @__PURE__ */ (0,
|
|
4561
|
-
/* @__PURE__ */ (0,
|
|
4562
|
-
/* @__PURE__ */ (0,
|
|
4949
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4950
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M5 12h14" }),
|
|
4951
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m12 5 7 7-7 7" })
|
|
4563
4952
|
] });
|
|
4564
4953
|
}
|
|
4565
4954
|
function IconSection({ className, ...props }) {
|
|
4566
|
-
return /* @__PURE__ */ (0,
|
|
4567
|
-
/* @__PURE__ */ (0,
|
|
4568
|
-
/* @__PURE__ */ (0,
|
|
4569
|
-
/* @__PURE__ */ (0,
|
|
4955
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
4956
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
4957
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
4958
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
4570
4959
|
] });
|
|
4571
4960
|
}
|
|
4572
4961
|
|
|
4573
4962
|
// src/ui/dialog.tsx
|
|
4574
|
-
var
|
|
4963
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4575
4964
|
function Dialog2({ ...props }) {
|
|
4576
|
-
return /* @__PURE__ */ (0,
|
|
4965
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_radix_ui4.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
4577
4966
|
}
|
|
4578
4967
|
function DialogPortal({ ...props }) {
|
|
4579
|
-
return /* @__PURE__ */ (0,
|
|
4968
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_radix_ui4.Dialog.Portal, { ...props });
|
|
4580
4969
|
}
|
|
4581
4970
|
function DialogOverlay({
|
|
4582
4971
|
className,
|
|
4583
4972
|
...props
|
|
4584
4973
|
}) {
|
|
4585
|
-
return /* @__PURE__ */ (0,
|
|
4586
|
-
|
|
4974
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4975
|
+
import_radix_ui4.Dialog.Overlay,
|
|
4587
4976
|
{
|
|
4588
4977
|
"data-slot": "dialog-overlay",
|
|
4589
4978
|
"data-ohw-link-modal-root": "",
|
|
@@ -4592,12 +4981,12 @@ function DialogOverlay({
|
|
|
4592
4981
|
}
|
|
4593
4982
|
);
|
|
4594
4983
|
}
|
|
4595
|
-
var DialogContent =
|
|
4984
|
+
var DialogContent = React5.forwardRef(({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
4596
4985
|
const positionMode = container ? "absolute" : "fixed";
|
|
4597
|
-
return /* @__PURE__ */ (0,
|
|
4598
|
-
/* @__PURE__ */ (0,
|
|
4599
|
-
/* @__PURE__ */ (0,
|
|
4600
|
-
|
|
4986
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
4987
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
4988
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4989
|
+
import_radix_ui4.Dialog.Content,
|
|
4601
4990
|
{
|
|
4602
4991
|
ref,
|
|
4603
4992
|
"data-slot": "dialog-content",
|
|
@@ -4612,13 +5001,13 @@ var DialogContent = React3.forwardRef(({ className, children, showCloseButton =
|
|
|
4612
5001
|
...props,
|
|
4613
5002
|
children: [
|
|
4614
5003
|
children,
|
|
4615
|
-
showCloseButton ? /* @__PURE__ */ (0,
|
|
4616
|
-
|
|
5004
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
5005
|
+
import_radix_ui4.Dialog.Close,
|
|
4617
5006
|
{
|
|
4618
5007
|
type: "button",
|
|
4619
5008
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
4620
5009
|
"aria-label": "Close",
|
|
4621
|
-
children: /* @__PURE__ */ (0,
|
|
5010
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(IconX, { "aria-hidden": true })
|
|
4622
5011
|
}
|
|
4623
5012
|
) : null
|
|
4624
5013
|
]
|
|
@@ -4626,37 +5015,37 @@ var DialogContent = React3.forwardRef(({ className, children, showCloseButton =
|
|
|
4626
5015
|
)
|
|
4627
5016
|
] });
|
|
4628
5017
|
});
|
|
4629
|
-
DialogContent.displayName =
|
|
5018
|
+
DialogContent.displayName = import_radix_ui4.Dialog.Content.displayName;
|
|
4630
5019
|
function DialogHeader({ className, ...props }) {
|
|
4631
|
-
return /* @__PURE__ */ (0,
|
|
5020
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
4632
5021
|
}
|
|
4633
5022
|
function DialogFooter({ className, ...props }) {
|
|
4634
|
-
return /* @__PURE__ */ (0,
|
|
5023
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: cn("flex items-center justify-end gap-2", className), ...props });
|
|
4635
5024
|
}
|
|
4636
|
-
var DialogTitle =
|
|
4637
|
-
|
|
5025
|
+
var DialogTitle = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
5026
|
+
import_radix_ui4.Dialog.Title,
|
|
4638
5027
|
{
|
|
4639
5028
|
ref,
|
|
4640
5029
|
className: cn("text-lg font-semibold leading-none tracking-tight text-card-foreground", className),
|
|
4641
5030
|
...props
|
|
4642
5031
|
}
|
|
4643
5032
|
));
|
|
4644
|
-
DialogTitle.displayName =
|
|
4645
|
-
var DialogDescription =
|
|
4646
|
-
|
|
5033
|
+
DialogTitle.displayName = import_radix_ui4.Dialog.Title.displayName;
|
|
5034
|
+
var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
5035
|
+
import_radix_ui4.Dialog.Description,
|
|
4647
5036
|
{
|
|
4648
5037
|
ref,
|
|
4649
5038
|
className: cn("text-sm text-muted-foreground", className),
|
|
4650
5039
|
...props
|
|
4651
5040
|
}
|
|
4652
5041
|
));
|
|
4653
|
-
DialogDescription.displayName =
|
|
4654
|
-
var DialogClose =
|
|
5042
|
+
DialogDescription.displayName = import_radix_ui4.Dialog.Description.displayName;
|
|
5043
|
+
var DialogClose = import_radix_ui4.Dialog.Close;
|
|
4655
5044
|
|
|
4656
5045
|
// src/ui/button.tsx
|
|
4657
|
-
var
|
|
4658
|
-
var
|
|
4659
|
-
var
|
|
5046
|
+
var React6 = __toESM(require("react"), 1);
|
|
5047
|
+
var import_radix_ui5 = require("radix-ui");
|
|
5048
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4660
5049
|
var buttonVariants = cva(
|
|
4661
5050
|
"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",
|
|
4662
5051
|
{
|
|
@@ -4677,10 +5066,10 @@ var buttonVariants = cva(
|
|
|
4677
5066
|
}
|
|
4678
5067
|
}
|
|
4679
5068
|
);
|
|
4680
|
-
var Button =
|
|
5069
|
+
var Button = React6.forwardRef(
|
|
4681
5070
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
4682
|
-
const Comp = asChild ?
|
|
4683
|
-
return /* @__PURE__ */ (0,
|
|
5071
|
+
const Comp = asChild ? import_radix_ui5.Slot.Root : "button";
|
|
5072
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4684
5073
|
Comp,
|
|
4685
5074
|
{
|
|
4686
5075
|
ref,
|
|
@@ -4694,37 +5083,37 @@ var Button = React4.forwardRef(
|
|
|
4694
5083
|
Button.displayName = "Button";
|
|
4695
5084
|
|
|
4696
5085
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
4697
|
-
var
|
|
5086
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4698
5087
|
function DestinationBreadcrumb({ pageTitle, sectionLabel }) {
|
|
4699
|
-
return /* @__PURE__ */ (0,
|
|
4700
|
-
/* @__PURE__ */ (0,
|
|
4701
|
-
/* @__PURE__ */ (0,
|
|
4702
|
-
/* @__PURE__ */ (0,
|
|
4703
|
-
/* @__PURE__ */ (0,
|
|
4704
|
-
/* @__PURE__ */ (0,
|
|
5088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5089
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
|
|
5090
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
5091
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5092
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconFile, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5093
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-sm font-medium leading-none text-foreground", children: pageTitle })
|
|
4705
5094
|
] }),
|
|
4706
|
-
/* @__PURE__ */ (0,
|
|
4707
|
-
/* @__PURE__ */ (0,
|
|
4708
|
-
/* @__PURE__ */ (0,
|
|
4709
|
-
/* @__PURE__ */ (0,
|
|
5095
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconArrowRight, { className: "shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
5096
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5097
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5098
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
4710
5099
|
] })
|
|
4711
5100
|
] })
|
|
4712
5101
|
] });
|
|
4713
5102
|
}
|
|
4714
5103
|
|
|
4715
5104
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
4716
|
-
var
|
|
5105
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
4717
5106
|
function SectionTreeItem({ section, onSelect, selected }) {
|
|
4718
5107
|
const interactive = Boolean(onSelect);
|
|
4719
|
-
return /* @__PURE__ */ (0,
|
|
4720
|
-
/* @__PURE__ */ (0,
|
|
5108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5109
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
4721
5110
|
"div",
|
|
4722
5111
|
{
|
|
4723
5112
|
className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
4724
5113
|
"aria-hidden": true
|
|
4725
5114
|
}
|
|
4726
5115
|
),
|
|
4727
|
-
/* @__PURE__ */ (0,
|
|
5116
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
4728
5117
|
"div",
|
|
4729
5118
|
{
|
|
4730
5119
|
role: interactive ? "button" : void 0,
|
|
@@ -4742,8 +5131,8 @@ function SectionTreeItem({ section, onSelect, selected }) {
|
|
|
4742
5131
|
interactive && selected && "border-primary"
|
|
4743
5132
|
),
|
|
4744
5133
|
children: [
|
|
4745
|
-
/* @__PURE__ */ (0,
|
|
4746
|
-
/* @__PURE__ */ (0,
|
|
5134
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5135
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
4747
5136
|
]
|
|
4748
5137
|
}
|
|
4749
5138
|
)
|
|
@@ -4751,11 +5140,11 @@ function SectionTreeItem({ section, onSelect, selected }) {
|
|
|
4751
5140
|
}
|
|
4752
5141
|
function SectionPickerList({ sections, onSelect }) {
|
|
4753
5142
|
if (sections.length === 0) {
|
|
4754
|
-
return /* @__PURE__ */ (0,
|
|
5143
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
|
|
4755
5144
|
}
|
|
4756
|
-
return /* @__PURE__ */ (0,
|
|
4757
|
-
/* @__PURE__ */ (0,
|
|
4758
|
-
sections.map((section) => /* @__PURE__ */ (0,
|
|
5145
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
5146
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
|
|
5147
|
+
sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SectionTreeItem, { section, onSelect }, section.id))
|
|
4759
5148
|
] });
|
|
4760
5149
|
}
|
|
4761
5150
|
|
|
@@ -4763,11 +5152,11 @@ function SectionPickerList({ sections, onSelect }) {
|
|
|
4763
5152
|
var import_react4 = require("react");
|
|
4764
5153
|
|
|
4765
5154
|
// src/ui/input.tsx
|
|
4766
|
-
var
|
|
4767
|
-
var
|
|
4768
|
-
var Input =
|
|
5155
|
+
var React7 = __toESM(require("react"), 1);
|
|
5156
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
5157
|
+
var Input = React7.forwardRef(
|
|
4769
5158
|
({ className, type, ...props }, ref) => {
|
|
4770
|
-
return /* @__PURE__ */ (0,
|
|
5159
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
4771
5160
|
"input",
|
|
4772
5161
|
{
|
|
4773
5162
|
type,
|
|
@@ -4785,11 +5174,11 @@ var Input = React5.forwardRef(
|
|
|
4785
5174
|
Input.displayName = "Input";
|
|
4786
5175
|
|
|
4787
5176
|
// src/ui/label.tsx
|
|
4788
|
-
var
|
|
4789
|
-
var
|
|
5177
|
+
var import_radix_ui6 = require("radix-ui");
|
|
5178
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
4790
5179
|
function Label({ className, ...props }) {
|
|
4791
|
-
return /* @__PURE__ */ (0,
|
|
4792
|
-
|
|
5180
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5181
|
+
import_radix_ui6.Label.Root,
|
|
4793
5182
|
{
|
|
4794
5183
|
"data-slot": "label",
|
|
4795
5184
|
className: cn("text-sm font-medium leading-5 text-foreground", className),
|
|
@@ -4799,9 +5188,9 @@ function Label({ className, ...props }) {
|
|
|
4799
5188
|
}
|
|
4800
5189
|
|
|
4801
5190
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
4802
|
-
var
|
|
5191
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
4803
5192
|
function FieldChevron({ onClick }) {
|
|
4804
|
-
return /* @__PURE__ */ (0,
|
|
5193
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4805
5194
|
"button",
|
|
4806
5195
|
{
|
|
4807
5196
|
type: "button",
|
|
@@ -4809,7 +5198,7 @@ function FieldChevron({ onClick }) {
|
|
|
4809
5198
|
onClick,
|
|
4810
5199
|
"aria-label": "Open page list",
|
|
4811
5200
|
tabIndex: -1,
|
|
4812
|
-
children: /* @__PURE__ */ (0,
|
|
5201
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconChevronDown, {})
|
|
4813
5202
|
}
|
|
4814
5203
|
);
|
|
4815
5204
|
}
|
|
@@ -4848,12 +5237,12 @@ function UrlOrPageInput({
|
|
|
4848
5237
|
"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]",
|
|
4849
5238
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
4850
5239
|
);
|
|
4851
|
-
return /* @__PURE__ */ (0,
|
|
4852
|
-
/* @__PURE__ */ (0,
|
|
4853
|
-
/* @__PURE__ */ (0,
|
|
4854
|
-
/* @__PURE__ */ (0,
|
|
4855
|
-
selectedPage ? /* @__PURE__ */ (0,
|
|
4856
|
-
readOnly ? /* @__PURE__ */ (0,
|
|
5240
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5241
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5242
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "relative w-full", children: [
|
|
5243
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5244
|
+
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconFile, { className: "text-foreground", "aria-hidden": true }) }) : null,
|
|
5245
|
+
readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4857
5246
|
Input,
|
|
4858
5247
|
{
|
|
4859
5248
|
ref: inputRef,
|
|
@@ -4872,7 +5261,7 @@ function UrlOrPageInput({
|
|
|
4872
5261
|
)
|
|
4873
5262
|
}
|
|
4874
5263
|
),
|
|
4875
|
-
selectedPage && !readOnly ? /* @__PURE__ */ (0,
|
|
5264
|
+
selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4876
5265
|
"button",
|
|
4877
5266
|
{
|
|
4878
5267
|
type: "button",
|
|
@@ -4880,26 +5269,26 @@ function UrlOrPageInput({
|
|
|
4880
5269
|
onMouseDown: clearSelection,
|
|
4881
5270
|
"aria-label": "Clear selected page",
|
|
4882
5271
|
tabIndex: -1,
|
|
4883
|
-
children: /* @__PURE__ */ (0,
|
|
5272
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconX, { "aria-hidden": true })
|
|
4884
5273
|
}
|
|
4885
5274
|
) : null,
|
|
4886
|
-
!readOnly ? /* @__PURE__ */ (0,
|
|
5275
|
+
!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
|
|
4887
5276
|
] }),
|
|
4888
|
-
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0,
|
|
5277
|
+
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
4889
5278
|
"div",
|
|
4890
5279
|
{
|
|
4891
5280
|
"data-ohw-link-page-dropdown": "",
|
|
4892
5281
|
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",
|
|
4893
5282
|
onMouseDown: (e) => e.preventDefault(),
|
|
4894
|
-
children: filteredPages.map((page) => /* @__PURE__ */ (0,
|
|
5283
|
+
children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
4895
5284
|
"button",
|
|
4896
5285
|
{
|
|
4897
5286
|
type: "button",
|
|
4898
5287
|
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",
|
|
4899
5288
|
onClick: () => onPageSelect(page),
|
|
4900
5289
|
children: [
|
|
4901
|
-
/* @__PURE__ */ (0,
|
|
4902
|
-
/* @__PURE__ */ (0,
|
|
5290
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconFile, { className: "shrink-0", "aria-hidden": true }),
|
|
5291
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "truncate", children: page.title })
|
|
4903
5292
|
]
|
|
4904
5293
|
},
|
|
4905
5294
|
page.path
|
|
@@ -4907,7 +5296,7 @@ function UrlOrPageInput({
|
|
|
4907
5296
|
}
|
|
4908
5297
|
) : null
|
|
4909
5298
|
] }),
|
|
4910
|
-
urlError ? /* @__PURE__ */ (0,
|
|
5299
|
+
urlError ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
|
|
4911
5300
|
] });
|
|
4912
5301
|
}
|
|
4913
5302
|
|
|
@@ -5075,7 +5464,7 @@ function useLinkModalState({
|
|
|
5075
5464
|
}
|
|
5076
5465
|
|
|
5077
5466
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5078
|
-
var
|
|
5467
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5079
5468
|
function LinkEditorPanel({
|
|
5080
5469
|
open = true,
|
|
5081
5470
|
mode = "create",
|
|
@@ -5099,25 +5488,25 @@ function LinkEditorPanel({
|
|
|
5099
5488
|
onSubmit
|
|
5100
5489
|
});
|
|
5101
5490
|
const isCancel = state.secondaryLabel === "Cancel";
|
|
5102
|
-
return /* @__PURE__ */ (0,
|
|
5103
|
-
/* @__PURE__ */ (0,
|
|
5491
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
5492
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5104
5493
|
"button",
|
|
5105
5494
|
{
|
|
5106
5495
|
type: "button",
|
|
5107
5496
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5108
5497
|
"aria-label": "Close",
|
|
5109
|
-
children: /* @__PURE__ */ (0,
|
|
5498
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconX, { "aria-hidden": true })
|
|
5110
5499
|
}
|
|
5111
5500
|
) }),
|
|
5112
|
-
/* @__PURE__ */ (0,
|
|
5113
|
-
/* @__PURE__ */ (0,
|
|
5114
|
-
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0,
|
|
5501
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5502
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5503
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5115
5504
|
DestinationBreadcrumb,
|
|
5116
5505
|
{
|
|
5117
5506
|
pageTitle: state.selectedPage.title,
|
|
5118
5507
|
sectionLabel: state.selectedSection.label
|
|
5119
5508
|
}
|
|
5120
|
-
) : /* @__PURE__ */ (0,
|
|
5509
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5121
5510
|
UrlOrPageInput,
|
|
5122
5511
|
{
|
|
5123
5512
|
value: state.searchValue,
|
|
@@ -5130,18 +5519,18 @@ function LinkEditorPanel({
|
|
|
5130
5519
|
urlError: state.urlError
|
|
5131
5520
|
}
|
|
5132
5521
|
),
|
|
5133
|
-
state.showChooseSection ? /* @__PURE__ */ (0,
|
|
5134
|
-
/* @__PURE__ */ (0,
|
|
5135
|
-
/* @__PURE__ */ (0,
|
|
5136
|
-
/* @__PURE__ */ (0,
|
|
5137
|
-
/* @__PURE__ */ (0,
|
|
5522
|
+
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5523
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
|
|
5524
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5525
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconInfo, { className: "shrink-0", "aria-hidden": true }),
|
|
5526
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
5138
5527
|
] })
|
|
5139
5528
|
] }) : null,
|
|
5140
|
-
state.showSectionPicker ? /* @__PURE__ */ (0,
|
|
5141
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0,
|
|
5529
|
+
state.showSectionPicker ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5530
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5142
5531
|
] }),
|
|
5143
|
-
/* @__PURE__ */ (0,
|
|
5144
|
-
/* @__PURE__ */ (0,
|
|
5532
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5533
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5145
5534
|
Button,
|
|
5146
5535
|
{
|
|
5147
5536
|
type: "button",
|
|
@@ -5156,7 +5545,7 @@ function LinkEditorPanel({
|
|
|
5156
5545
|
children: state.secondaryLabel
|
|
5157
5546
|
}
|
|
5158
5547
|
),
|
|
5159
|
-
/* @__PURE__ */ (0,
|
|
5548
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5160
5549
|
Button,
|
|
5161
5550
|
{
|
|
5162
5551
|
type: "button",
|
|
@@ -5175,7 +5564,7 @@ function LinkEditorPanel({
|
|
|
5175
5564
|
}
|
|
5176
5565
|
|
|
5177
5566
|
// src/ui/link-modal/LinkPopover.tsx
|
|
5178
|
-
var
|
|
5567
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5179
5568
|
function LinkPopover({
|
|
5180
5569
|
open = true,
|
|
5181
5570
|
panelRef,
|
|
@@ -5183,14 +5572,14 @@ function LinkPopover({
|
|
|
5183
5572
|
onClose,
|
|
5184
5573
|
...editorProps
|
|
5185
5574
|
}) {
|
|
5186
|
-
return /* @__PURE__ */ (0,
|
|
5575
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5187
5576
|
Dialog2,
|
|
5188
5577
|
{
|
|
5189
5578
|
open,
|
|
5190
5579
|
onOpenChange: (next) => {
|
|
5191
5580
|
if (!next) onClose?.();
|
|
5192
5581
|
},
|
|
5193
|
-
children: /* @__PURE__ */ (0,
|
|
5582
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5194
5583
|
DialogContent,
|
|
5195
5584
|
{
|
|
5196
5585
|
ref: panelRef,
|
|
@@ -5200,7 +5589,7 @@ function LinkPopover({
|
|
|
5200
5589
|
"data-ohw-bridge": "",
|
|
5201
5590
|
showCloseButton: false,
|
|
5202
5591
|
className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
|
|
5203
|
-
children: /* @__PURE__ */ (0,
|
|
5592
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(LinkEditorPanel, { ...editorProps, open, onClose })
|
|
5204
5593
|
}
|
|
5205
5594
|
)
|
|
5206
5595
|
}
|
|
@@ -5266,7 +5655,7 @@ function shouldUseDevFixtures() {
|
|
|
5266
5655
|
}
|
|
5267
5656
|
|
|
5268
5657
|
// src/ui/badge.tsx
|
|
5269
|
-
var
|
|
5658
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5270
5659
|
var badgeVariants = cva(
|
|
5271
5660
|
"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",
|
|
5272
5661
|
{
|
|
@@ -5284,12 +5673,13 @@ var badgeVariants = cva(
|
|
|
5284
5673
|
}
|
|
5285
5674
|
);
|
|
5286
5675
|
function Badge({ className, variant, ...props }) {
|
|
5287
|
-
return /* @__PURE__ */ (0,
|
|
5676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
5288
5677
|
}
|
|
5289
5678
|
|
|
5290
5679
|
// src/OhhwellsBridge.tsx
|
|
5291
|
-
var
|
|
5292
|
-
var
|
|
5680
|
+
var import_lucide_react3 = require("lucide-react");
|
|
5681
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
5682
|
+
var PRIMARY2 = "#0885FE";
|
|
5293
5683
|
var IMAGE_FADE_MS = 300;
|
|
5294
5684
|
function runOpacityFade(el, onDone) {
|
|
5295
5685
|
const anim = el.animate([{ opacity: 0 }, { opacity: 1 }], {
|
|
@@ -5462,7 +5852,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
5462
5852
|
const root = (0, import_client.createRoot)(container);
|
|
5463
5853
|
(0, import_react_dom.flushSync)(() => {
|
|
5464
5854
|
root.render(
|
|
5465
|
-
/* @__PURE__ */ (0,
|
|
5855
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5466
5856
|
SchedulingWidget,
|
|
5467
5857
|
{
|
|
5468
5858
|
notifyOnConnect,
|
|
@@ -5510,6 +5900,20 @@ function applyLinkHref(el, val) {
|
|
|
5510
5900
|
const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
|
|
5511
5901
|
if (anchor) anchor.setAttribute("href", val);
|
|
5512
5902
|
}
|
|
5903
|
+
function getEditMeasureEl(editable) {
|
|
5904
|
+
return editable.closest("[data-ohw-href-key]") ?? editable;
|
|
5905
|
+
}
|
|
5906
|
+
function isDragHandleDisabled(el) {
|
|
5907
|
+
const carriers = [
|
|
5908
|
+
el.closest("[data-ohw-href-key]"),
|
|
5909
|
+
el.closest("[data-ohw-editable]")
|
|
5910
|
+
];
|
|
5911
|
+
return carriers.some((carrier) => {
|
|
5912
|
+
if (!carrier) return false;
|
|
5913
|
+
const raw = carrier.getAttribute("data-ohw-drag-disabled");
|
|
5914
|
+
return raw === "true" || raw === "";
|
|
5915
|
+
});
|
|
5916
|
+
}
|
|
5513
5917
|
function collectEditableNodes() {
|
|
5514
5918
|
const nodes = Array.from(document.querySelectorAll("[data-ohw-editable]")).map((el) => {
|
|
5515
5919
|
if (el.dataset.ohwEditable === "image") {
|
|
@@ -5563,12 +5967,49 @@ function getHrefKeyFromElement(el) {
|
|
|
5563
5967
|
function isNavbarButton(el) {
|
|
5564
5968
|
return Boolean(el.closest('[data-ohw-role="navbar-button"]'));
|
|
5565
5969
|
}
|
|
5970
|
+
function getNavigationItemAnchor(el) {
|
|
5971
|
+
const anchor = el.matches("[data-ohw-href-key]") ? el : el.closest("[data-ohw-href-key]");
|
|
5972
|
+
if (!anchor) return null;
|
|
5973
|
+
if (!anchor.querySelector('[data-ohw-editable="text"]')) return null;
|
|
5974
|
+
return anchor;
|
|
5975
|
+
}
|
|
5976
|
+
function isNavigationItem(el) {
|
|
5977
|
+
return getNavigationItemAnchor(el) !== null;
|
|
5978
|
+
}
|
|
5979
|
+
function getNavigationItemAddHintTarget(anchor) {
|
|
5980
|
+
const items = listNavigationItems();
|
|
5981
|
+
const idx = items.indexOf(anchor);
|
|
5982
|
+
if (idx >= 0 && idx < items.length - 1) return items[idx + 1];
|
|
5983
|
+
return anchor;
|
|
5984
|
+
}
|
|
5985
|
+
function listNavigationItems() {
|
|
5986
|
+
return Array.from(
|
|
5987
|
+
document.querySelectorAll("nav [data-ohw-href-key], footer [data-ohw-href-key]")
|
|
5988
|
+
).filter((el) => isNavigationItem(el));
|
|
5989
|
+
}
|
|
5990
|
+
function getNavigationItemReorderState(anchor) {
|
|
5991
|
+
if (isNavbarButton(anchor)) return { key: null, disabled: false };
|
|
5992
|
+
return getReorderHandleStateFromAnchor(anchor);
|
|
5993
|
+
}
|
|
5994
|
+
function getReorderHandleState(el) {
|
|
5995
|
+
const linkEl = el.closest("[data-ohw-href-key]");
|
|
5996
|
+
if (!linkEl || getNavigationItemAnchor(linkEl)) return { key: null, disabled: false };
|
|
5997
|
+
return getReorderHandleStateFromAnchor(linkEl);
|
|
5998
|
+
}
|
|
5999
|
+
function getReorderHandleStateFromAnchor(anchor) {
|
|
6000
|
+
const key = anchor.getAttribute("data-ohw-href-key");
|
|
6001
|
+
if (!key) return { key: null, disabled: false };
|
|
6002
|
+
return { key, disabled: isDragHandleDisabled(anchor) };
|
|
6003
|
+
}
|
|
5566
6004
|
function clearHrefKeyHover(anchor) {
|
|
5567
6005
|
anchor.removeAttribute("data-ohw-hovered");
|
|
5568
6006
|
anchor.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
|
|
5569
6007
|
el.removeAttribute("data-ohw-hovered");
|
|
5570
6008
|
});
|
|
5571
6009
|
}
|
|
6010
|
+
function isInsideNavigationItem(el) {
|
|
6011
|
+
return getNavigationItemAnchor(el) !== null;
|
|
6012
|
+
}
|
|
5572
6013
|
function collectSections() {
|
|
5573
6014
|
return collectSectionsFromDom();
|
|
5574
6015
|
}
|
|
@@ -5692,6 +6133,8 @@ var ICONS = {
|
|
|
5692
6133
|
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"/>',
|
|
5693
6134
|
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"/>'
|
|
5694
6135
|
};
|
|
6136
|
+
var TOOLBAR_PILL_PADDING = 2;
|
|
6137
|
+
var TOOLBAR_TOGGLE_GAP = 4;
|
|
5695
6138
|
var TOOLBAR_GROUPS = [
|
|
5696
6139
|
[
|
|
5697
6140
|
{ cmd: "bold", title: "Bold" },
|
|
@@ -5709,24 +6152,64 @@ var TOOLBAR_GROUPS = [
|
|
|
5709
6152
|
{ cmd: "insertOrderedList", title: "Numbered List" }
|
|
5710
6153
|
]
|
|
5711
6154
|
];
|
|
5712
|
-
function
|
|
6155
|
+
function EditGlowChrome({
|
|
6156
|
+
rect,
|
|
6157
|
+
elRef,
|
|
6158
|
+
reorderHrefKey,
|
|
6159
|
+
dragDisabled = false
|
|
6160
|
+
}) {
|
|
5713
6161
|
const GAP = 6;
|
|
5714
|
-
return /* @__PURE__ */ (0,
|
|
6162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
5715
6163
|
"div",
|
|
5716
6164
|
{
|
|
5717
6165
|
ref: elRef,
|
|
6166
|
+
"data-ohw-edit-chrome": "",
|
|
5718
6167
|
style: {
|
|
5719
6168
|
position: "fixed",
|
|
5720
6169
|
top: rect.top - GAP,
|
|
5721
6170
|
left: rect.left - GAP,
|
|
5722
6171
|
width: rect.width + GAP * 2,
|
|
5723
6172
|
height: rect.height + GAP * 2,
|
|
5724
|
-
border: "2px solid #0885FE",
|
|
5725
|
-
borderRadius: 8,
|
|
5726
|
-
boxShadow: "0 0 0 4px rgba(8, 133, 254, 0.12)",
|
|
5727
6173
|
pointerEvents: "none",
|
|
5728
6174
|
zIndex: 2147483646
|
|
5729
|
-
}
|
|
6175
|
+
},
|
|
6176
|
+
children: [
|
|
6177
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6178
|
+
"div",
|
|
6179
|
+
{
|
|
6180
|
+
style: {
|
|
6181
|
+
position: "absolute",
|
|
6182
|
+
inset: 0,
|
|
6183
|
+
border: "2px solid var(--ohw-primary, #0885FE)",
|
|
6184
|
+
borderRadius: 8,
|
|
6185
|
+
boxShadow: "0 0 0 4px rgba(8, 133, 254, 0.12)",
|
|
6186
|
+
pointerEvents: "none"
|
|
6187
|
+
}
|
|
6188
|
+
}
|
|
6189
|
+
),
|
|
6190
|
+
reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6191
|
+
"div",
|
|
6192
|
+
{
|
|
6193
|
+
"data-ohw-drag-handle-container": "",
|
|
6194
|
+
"data-ohw-drag-disabled": dragDisabled ? "" : void 0,
|
|
6195
|
+
style: {
|
|
6196
|
+
position: "absolute",
|
|
6197
|
+
left: 0,
|
|
6198
|
+
top: "50%",
|
|
6199
|
+
transform: "translate(calc(-100% - 7px), -50%)",
|
|
6200
|
+
pointerEvents: dragDisabled ? "none" : "auto"
|
|
6201
|
+
},
|
|
6202
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6203
|
+
DragHandle,
|
|
6204
|
+
{
|
|
6205
|
+
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
6206
|
+
disabled: dragDisabled,
|
|
6207
|
+
"aria-disabled": dragDisabled
|
|
6208
|
+
}
|
|
6209
|
+
)
|
|
6210
|
+
}
|
|
6211
|
+
)
|
|
6212
|
+
]
|
|
5730
6213
|
}
|
|
5731
6214
|
);
|
|
5732
6215
|
}
|
|
@@ -5770,9 +6253,9 @@ function clampToolbarToClip(top, transform, rect, clip, approxH, gap) {
|
|
|
5770
6253
|
const pinnedTop = Math.min(maxBottom - approxH, Math.max(minTop, clip.top + gap));
|
|
5771
6254
|
return { top: pinnedTop + approxH, transform: "translateX(-50%) translateY(-100%)" };
|
|
5772
6255
|
}
|
|
5773
|
-
function calcToolbarPos(rect, parentScroll, approxW =
|
|
6256
|
+
function calcToolbarPos(rect, parentScroll, approxW = 306) {
|
|
5774
6257
|
const GAP = 8;
|
|
5775
|
-
const APPROX_H =
|
|
6258
|
+
const APPROX_H = 32;
|
|
5776
6259
|
const APPROX_W = approxW;
|
|
5777
6260
|
const clip = getIframeVisibleClip(parentScroll);
|
|
5778
6261
|
const clipTop = clip?.top ?? 0;
|
|
@@ -5806,119 +6289,24 @@ function calcToolbarPos(rect, parentScroll, approxW = 330) {
|
|
|
5806
6289
|
const left = Math.max(GAP + APPROX_W / 2, Math.min(rawLeft, window.innerWidth - GAP - APPROX_W / 2));
|
|
5807
6290
|
return { top, left, transform };
|
|
5808
6291
|
}
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
6292
|
+
function resolveItemInteractionState(rect, parentScroll) {
|
|
6293
|
+
const { transform } = calcToolbarPos(rect, parentScroll, 120);
|
|
6294
|
+
return transform.includes("translateY(-100%)") ? "active-top" : "active-bottom";
|
|
6295
|
+
}
|
|
5813
6296
|
function FloatingToolbar({
|
|
5814
6297
|
rect,
|
|
5815
6298
|
parentScroll,
|
|
5816
6299
|
elRef,
|
|
5817
|
-
variant = "rich-text",
|
|
5818
6300
|
onCommand,
|
|
5819
6301
|
activeCommands,
|
|
5820
6302
|
showEditLink,
|
|
5821
6303
|
onEditLink
|
|
5822
6304
|
}) {
|
|
5823
|
-
const
|
|
5824
|
-
|
|
5825
|
-
if (variant === "link-action") {
|
|
5826
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
5827
|
-
"div",
|
|
5828
|
-
{
|
|
5829
|
-
ref: elRef,
|
|
5830
|
-
"data-ohw-toolbar": "",
|
|
5831
|
-
style: {
|
|
5832
|
-
position: "fixed",
|
|
5833
|
-
top,
|
|
5834
|
-
left,
|
|
5835
|
-
transform,
|
|
5836
|
-
zIndex: 2147483647,
|
|
5837
|
-
background: "#fff",
|
|
5838
|
-
border: "1px solid #E7E5E4",
|
|
5839
|
-
borderRadius: 6,
|
|
5840
|
-
boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
|
|
5841
|
-
display: "flex",
|
|
5842
|
-
alignItems: "center",
|
|
5843
|
-
padding: 4,
|
|
5844
|
-
gap: 6,
|
|
5845
|
-
fontFamily: "sans-serif",
|
|
5846
|
-
pointerEvents: "auto",
|
|
5847
|
-
whiteSpace: "nowrap"
|
|
5848
|
-
},
|
|
5849
|
-
onMouseDown: (e) => e.stopPropagation(),
|
|
5850
|
-
children: [
|
|
5851
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5852
|
-
"button",
|
|
5853
|
-
{
|
|
5854
|
-
type: "button",
|
|
5855
|
-
title: "Edit link",
|
|
5856
|
-
onMouseDown: (e) => {
|
|
5857
|
-
e.preventDefault();
|
|
5858
|
-
e.stopPropagation();
|
|
5859
|
-
onEditLink?.();
|
|
5860
|
-
},
|
|
5861
|
-
onClick: (e) => {
|
|
5862
|
-
e.preventDefault();
|
|
5863
|
-
e.stopPropagation();
|
|
5864
|
-
},
|
|
5865
|
-
onMouseEnter: (e) => {
|
|
5866
|
-
e.currentTarget.style.background = "#F5F5F4";
|
|
5867
|
-
},
|
|
5868
|
-
onMouseLeave: (e) => {
|
|
5869
|
-
e.currentTarget.style.background = "transparent";
|
|
5870
|
-
},
|
|
5871
|
-
style: {
|
|
5872
|
-
display: "flex",
|
|
5873
|
-
alignItems: "center",
|
|
5874
|
-
justifyContent: "center",
|
|
5875
|
-
border: "none",
|
|
5876
|
-
background: "transparent",
|
|
5877
|
-
borderRadius: 4,
|
|
5878
|
-
cursor: "pointer",
|
|
5879
|
-
color: "#1C1917",
|
|
5880
|
-
flexShrink: 0,
|
|
5881
|
-
padding: 6
|
|
5882
|
-
},
|
|
5883
|
-
children: EDIT_LINK_ICON
|
|
5884
|
-
}
|
|
5885
|
-
),
|
|
5886
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { display: "block", width: 1, height: 24, background: "#E7E5E4", flexShrink: 0 } }),
|
|
5887
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5888
|
-
"button",
|
|
5889
|
-
{
|
|
5890
|
-
type: "button",
|
|
5891
|
-
title: "Coming soon",
|
|
5892
|
-
disabled: true,
|
|
5893
|
-
style: {
|
|
5894
|
-
display: "flex",
|
|
5895
|
-
alignItems: "center",
|
|
5896
|
-
justifyContent: "center",
|
|
5897
|
-
border: "none",
|
|
5898
|
-
background: "transparent",
|
|
5899
|
-
borderRadius: 4,
|
|
5900
|
-
cursor: "not-allowed",
|
|
5901
|
-
color: "#A8A29E",
|
|
5902
|
-
flexShrink: 0,
|
|
5903
|
-
padding: 6,
|
|
5904
|
-
opacity: 0.6
|
|
5905
|
-
},
|
|
5906
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: [
|
|
5907
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "5", cy: "12", r: "1.5" }),
|
|
5908
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "12", cy: "12", r: "1.5" }),
|
|
5909
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("circle", { cx: "19", cy: "12", r: "1.5" })
|
|
5910
|
-
] })
|
|
5911
|
-
}
|
|
5912
|
-
)
|
|
5913
|
-
]
|
|
5914
|
-
}
|
|
5915
|
-
);
|
|
5916
|
-
}
|
|
5917
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
6305
|
+
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
6306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5918
6307
|
"div",
|
|
5919
6308
|
{
|
|
5920
6309
|
ref: elRef,
|
|
5921
|
-
"data-ohw-toolbar": "",
|
|
5922
6310
|
style: {
|
|
5923
6311
|
position: "fixed",
|
|
5924
6312
|
top,
|
|
@@ -5931,57 +6319,39 @@ function FloatingToolbar({
|
|
|
5931
6319
|
boxShadow: "0px 2px 4px -2px rgba(0,0,0,.1),0px 4px 6px -1px rgba(0,0,0,.1)",
|
|
5932
6320
|
display: "flex",
|
|
5933
6321
|
alignItems: "center",
|
|
5934
|
-
padding:
|
|
5935
|
-
gap:
|
|
6322
|
+
padding: TOOLBAR_PILL_PADDING,
|
|
6323
|
+
gap: TOOLBAR_TOGGLE_GAP,
|
|
5936
6324
|
fontFamily: "sans-serif",
|
|
5937
|
-
pointerEvents: "auto"
|
|
5938
|
-
whiteSpace: "nowrap"
|
|
6325
|
+
pointerEvents: "auto"
|
|
5939
6326
|
},
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { style: { display: "block", width: 1, height: 24, background: "#E7E5E4", flexShrink: 0 } }),
|
|
6327
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(CustomToolbar, { children: [
|
|
6328
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react6.default.Fragment, { children: [
|
|
6329
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CustomToolbarDivider, {}),
|
|
5944
6330
|
btns.map((btn) => {
|
|
5945
6331
|
const isActive = activeCommands.has(btn.cmd);
|
|
5946
|
-
return /* @__PURE__ */ (0,
|
|
5947
|
-
|
|
6332
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6333
|
+
CustomToolbarButton,
|
|
5948
6334
|
{
|
|
5949
6335
|
title: btn.title,
|
|
6336
|
+
active: isActive,
|
|
5950
6337
|
onMouseDown: (e) => {
|
|
5951
6338
|
e.preventDefault();
|
|
5952
6339
|
onCommand(btn.cmd);
|
|
5953
6340
|
},
|
|
5954
|
-
|
|
5955
|
-
if (!isActive) e.currentTarget.style.background = "#F5F5F4";
|
|
5956
|
-
},
|
|
5957
|
-
onMouseLeave: (e) => {
|
|
5958
|
-
if (!isActive) e.currentTarget.style.background = "transparent";
|
|
5959
|
-
},
|
|
5960
|
-
style: {
|
|
5961
|
-
display: "flex",
|
|
5962
|
-
alignItems: "center",
|
|
5963
|
-
justifyContent: "center",
|
|
5964
|
-
border: "none",
|
|
5965
|
-
background: isActive ? PRIMARY : "transparent",
|
|
5966
|
-
borderRadius: 4,
|
|
5967
|
-
cursor: "pointer",
|
|
5968
|
-
color: isActive ? "#FFFFFF" : "#1C1917",
|
|
5969
|
-
flexShrink: 0,
|
|
5970
|
-
padding: 6
|
|
5971
|
-
},
|
|
5972
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6341
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
5973
6342
|
"svg",
|
|
5974
6343
|
{
|
|
5975
6344
|
width: "16",
|
|
5976
6345
|
height: "16",
|
|
5977
6346
|
viewBox: "0 0 24 24",
|
|
5978
6347
|
fill: "none",
|
|
5979
|
-
stroke:
|
|
6348
|
+
stroke: "currentColor",
|
|
5980
6349
|
strokeWidth: "2.5",
|
|
5981
6350
|
strokeLinecap: "round",
|
|
5982
6351
|
strokeLinejoin: "round",
|
|
5983
|
-
style: isActive && gi > 0 ? { filter: "drop-shadow(0 0 0.5px
|
|
5984
|
-
dangerouslySetInnerHTML: { __html: ICONS[btn.cmd] }
|
|
6352
|
+
style: isActive && gi > 0 ? { filter: "drop-shadow(0 0 0.5px currentColor)" } : void 0,
|
|
6353
|
+
dangerouslySetInnerHTML: { __html: ICONS[btn.cmd] },
|
|
6354
|
+
"aria-hidden": true
|
|
5985
6355
|
}
|
|
5986
6356
|
)
|
|
5987
6357
|
},
|
|
@@ -5989,8 +6359,8 @@ function FloatingToolbar({
|
|
|
5989
6359
|
);
|
|
5990
6360
|
})
|
|
5991
6361
|
] }, gi)),
|
|
5992
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
5993
|
-
|
|
6362
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6363
|
+
CustomToolbarButton,
|
|
5994
6364
|
{
|
|
5995
6365
|
type: "button",
|
|
5996
6366
|
title: "Edit link",
|
|
@@ -6003,28 +6373,10 @@ function FloatingToolbar({
|
|
|
6003
6373
|
e.preventDefault();
|
|
6004
6374
|
e.stopPropagation();
|
|
6005
6375
|
},
|
|
6006
|
-
|
|
6007
|
-
e.currentTarget.style.background = "#F5F5F4";
|
|
6008
|
-
},
|
|
6009
|
-
onMouseLeave: (e) => {
|
|
6010
|
-
e.currentTarget.style.background = "transparent";
|
|
6011
|
-
},
|
|
6012
|
-
style: {
|
|
6013
|
-
display: "flex",
|
|
6014
|
-
alignItems: "center",
|
|
6015
|
-
justifyContent: "center",
|
|
6016
|
-
border: "none",
|
|
6017
|
-
background: "transparent",
|
|
6018
|
-
borderRadius: 4,
|
|
6019
|
-
cursor: "pointer",
|
|
6020
|
-
color: "#1C1917",
|
|
6021
|
-
flexShrink: 0,
|
|
6022
|
-
padding: 6
|
|
6023
|
-
},
|
|
6024
|
-
children: EDIT_LINK_ICON
|
|
6376
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react3.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
6025
6377
|
}
|
|
6026
6378
|
) : null
|
|
6027
|
-
]
|
|
6379
|
+
] })
|
|
6028
6380
|
}
|
|
6029
6381
|
);
|
|
6030
6382
|
}
|
|
@@ -6038,7 +6390,7 @@ function StateToggle({
|
|
|
6038
6390
|
states,
|
|
6039
6391
|
onStateChange
|
|
6040
6392
|
}) {
|
|
6041
|
-
return /* @__PURE__ */ (0,
|
|
6393
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
6042
6394
|
ToggleGroup,
|
|
6043
6395
|
{
|
|
6044
6396
|
"data-ohw-state-toggle": "",
|
|
@@ -6052,7 +6404,7 @@ function StateToggle({
|
|
|
6052
6404
|
left: rect.right - 8,
|
|
6053
6405
|
transform: "translateX(-100%)"
|
|
6054
6406
|
},
|
|
6055
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
6407
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
6056
6408
|
}
|
|
6057
6409
|
);
|
|
6058
6410
|
}
|
|
@@ -6140,6 +6492,10 @@ function OhhwellsBridge() {
|
|
|
6140
6492
|
});
|
|
6141
6493
|
const deselectRef = (0, import_react6.useRef)(() => {
|
|
6142
6494
|
});
|
|
6495
|
+
const reselectNavigationItemRef = (0, import_react6.useRef)(() => {
|
|
6496
|
+
});
|
|
6497
|
+
const commitNavigationTextEditRef = (0, import_react6.useRef)(() => {
|
|
6498
|
+
});
|
|
6143
6499
|
const refreshActiveCommandsRef = (0, import_react6.useRef)(() => {
|
|
6144
6500
|
});
|
|
6145
6501
|
const postToParentRef = (0, import_react6.useRef)(postToParent);
|
|
@@ -6150,11 +6506,18 @@ function OhhwellsBridge() {
|
|
|
6150
6506
|
const [toolbarVariant, setToolbarVariant] = (0, import_react6.useState)("none");
|
|
6151
6507
|
const toolbarVariantRef = (0, import_react6.useRef)("none");
|
|
6152
6508
|
toolbarVariantRef.current = toolbarVariant;
|
|
6509
|
+
const [reorderHrefKey, setReorderHrefKey] = (0, import_react6.useState)(null);
|
|
6510
|
+
const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react6.useState)(false);
|
|
6153
6511
|
const [toggleState, setToggleState] = (0, import_react6.useState)(null);
|
|
6154
6512
|
const [maxBadge, setMaxBadge] = (0, import_react6.useState)(null);
|
|
6155
6513
|
const [activeCommands, setActiveCommands] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
|
|
6156
6514
|
const [sectionGap, setSectionGap] = (0, import_react6.useState)(null);
|
|
6157
6515
|
const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react6.useState)(false);
|
|
6516
|
+
const hoveredItemElRef = (0, import_react6.useRef)(null);
|
|
6517
|
+
const [hoveredItemRect, setHoveredItemRect] = (0, import_react6.useState)(null);
|
|
6518
|
+
const siblingHintElRef = (0, import_react6.useRef)(null);
|
|
6519
|
+
const [siblingHintRect, setSiblingHintRect] = (0, import_react6.useState)(null);
|
|
6520
|
+
const [isItemDragging, setIsItemDragging] = (0, import_react6.useState)(false);
|
|
6158
6521
|
const [linkPopover, setLinkPopover] = (0, import_react6.useState)(null);
|
|
6159
6522
|
const [sitePages, setSitePages] = (0, import_react6.useState)([]);
|
|
6160
6523
|
const [sectionsByPath, setSectionsByPath] = (0, import_react6.useState)({});
|
|
@@ -6256,7 +6619,7 @@ function OhhwellsBridge() {
|
|
|
6256
6619
|
(0, import_react6.useEffect)(() => {
|
|
6257
6620
|
const update = () => {
|
|
6258
6621
|
const el = activeElRef.current ?? selectedElRef.current;
|
|
6259
|
-
if (el) setToolbarRect(el.getBoundingClientRect());
|
|
6622
|
+
if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
6260
6623
|
setToggleState((prev) => {
|
|
6261
6624
|
if (!prev || !activeStateElRef.current) return prev;
|
|
6262
6625
|
return { ...prev, rect: activeStateElRef.current.getBoundingClientRect() };
|
|
@@ -6323,6 +6686,8 @@ function OhhwellsBridge() {
|
|
|
6323
6686
|
}
|
|
6324
6687
|
el.removeAttribute("contenteditable");
|
|
6325
6688
|
activeElRef.current = null;
|
|
6689
|
+
setReorderHrefKey(null);
|
|
6690
|
+
setReorderDragDisabled(false);
|
|
6326
6691
|
if (!selectedElRef.current) {
|
|
6327
6692
|
setToolbarRect(null);
|
|
6328
6693
|
setToolbarVariant("none");
|
|
@@ -6334,16 +6699,82 @@ function OhhwellsBridge() {
|
|
|
6334
6699
|
}, [postToParent]);
|
|
6335
6700
|
const deselect = (0, import_react6.useCallback)(() => {
|
|
6336
6701
|
selectedElRef.current = null;
|
|
6702
|
+
setReorderHrefKey(null);
|
|
6703
|
+
setReorderDragDisabled(false);
|
|
6704
|
+
siblingHintElRef.current = null;
|
|
6705
|
+
setSiblingHintRect(null);
|
|
6706
|
+
setIsItemDragging(false);
|
|
6337
6707
|
if (!activeElRef.current) {
|
|
6338
6708
|
setToolbarRect(null);
|
|
6339
6709
|
setToolbarVariant("none");
|
|
6340
6710
|
}
|
|
6341
6711
|
}, []);
|
|
6712
|
+
const reselectNavigationItem = (0, import_react6.useCallback)((navAnchor) => {
|
|
6713
|
+
selectedElRef.current = navAnchor;
|
|
6714
|
+
const { key, disabled } = getNavigationItemReorderState(navAnchor);
|
|
6715
|
+
setReorderHrefKey(key);
|
|
6716
|
+
setReorderDragDisabled(disabled);
|
|
6717
|
+
setToolbarVariant("link-action");
|
|
6718
|
+
setToolbarRect(navAnchor.getBoundingClientRect());
|
|
6719
|
+
setToolbarShowEditLink(false);
|
|
6720
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6721
|
+
}, []);
|
|
6722
|
+
const commitNavigationTextEdit = (0, import_react6.useCallback)((navAnchor) => {
|
|
6723
|
+
const el = activeElRef.current;
|
|
6724
|
+
if (!el) return;
|
|
6725
|
+
const key = el.dataset.ohwKey;
|
|
6726
|
+
if (key) {
|
|
6727
|
+
const timer = autoSaveTimers.current.get(key);
|
|
6728
|
+
if (timer !== void 0) {
|
|
6729
|
+
clearTimeout(timer);
|
|
6730
|
+
autoSaveTimers.current.delete(key);
|
|
6731
|
+
}
|
|
6732
|
+
const html = sanitizeHtml(el.innerHTML);
|
|
6733
|
+
const original = originalContentRef.current ?? "";
|
|
6734
|
+
if (html !== sanitizeHtml(original)) {
|
|
6735
|
+
postToParent({ type: "ow:change", nodes: [{ key, text: html }] });
|
|
6736
|
+
const h = document.documentElement.scrollHeight;
|
|
6737
|
+
if (h > 50) postToParent({ type: "ow:height", height: h });
|
|
6738
|
+
}
|
|
6739
|
+
}
|
|
6740
|
+
el.removeAttribute("contenteditable");
|
|
6741
|
+
activeElRef.current = null;
|
|
6742
|
+
setMaxBadge(null);
|
|
6743
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
6744
|
+
setToolbarShowEditLink(false);
|
|
6745
|
+
postToParent({ type: "ow:exit-edit" });
|
|
6746
|
+
reselectNavigationItem(navAnchor);
|
|
6747
|
+
}, [postToParent, reselectNavigationItem]);
|
|
6748
|
+
const handleAddNavigationItem = (0, import_react6.useCallback)(() => {
|
|
6749
|
+
const selected = selectedElRef.current;
|
|
6750
|
+
if (!selected) return;
|
|
6751
|
+
const target = getNavigationItemAddHintTarget(selected);
|
|
6752
|
+
siblingHintElRef.current = target;
|
|
6753
|
+
setSiblingHintRect(target.getBoundingClientRect());
|
|
6754
|
+
}, []);
|
|
6755
|
+
const handleItemDragStart = (0, import_react6.useCallback)(() => {
|
|
6756
|
+
siblingHintElRef.current = null;
|
|
6757
|
+
setSiblingHintRect(null);
|
|
6758
|
+
setIsItemDragging(true);
|
|
6759
|
+
}, []);
|
|
6760
|
+
const handleItemDragEnd = (0, import_react6.useCallback)(() => {
|
|
6761
|
+
setIsItemDragging(false);
|
|
6762
|
+
}, []);
|
|
6763
|
+
reselectNavigationItemRef.current = reselectNavigationItem;
|
|
6764
|
+
commitNavigationTextEditRef.current = commitNavigationTextEdit;
|
|
6342
6765
|
const select = (0, import_react6.useCallback)((anchor) => {
|
|
6343
|
-
if (!
|
|
6766
|
+
if (!isNavigationItem(anchor)) return;
|
|
6344
6767
|
if (activeElRef.current) deactivate();
|
|
6345
6768
|
selectedElRef.current = anchor;
|
|
6346
6769
|
clearHrefKeyHover(anchor);
|
|
6770
|
+
setHoveredItemRect(null);
|
|
6771
|
+
hoveredItemElRef.current = null;
|
|
6772
|
+
siblingHintElRef.current = null;
|
|
6773
|
+
setSiblingHintRect(null);
|
|
6774
|
+
setIsItemDragging(false);
|
|
6775
|
+
const { key, disabled } = getNavigationItemReorderState(anchor);
|
|
6776
|
+
setReorderHrefKey(key);
|
|
6777
|
+
setReorderDragDisabled(disabled);
|
|
6347
6778
|
setToolbarVariant("link-action");
|
|
6348
6779
|
setToolbarRect(anchor.getBoundingClientRect());
|
|
6349
6780
|
setToolbarShowEditLink(false);
|
|
@@ -6358,13 +6789,26 @@ function OhhwellsBridge() {
|
|
|
6358
6789
|
postToParentRef.current({ type: "ow:image-unhover" });
|
|
6359
6790
|
}
|
|
6360
6791
|
setToolbarVariant("rich-text");
|
|
6792
|
+
siblingHintElRef.current = null;
|
|
6793
|
+
setSiblingHintRect(null);
|
|
6794
|
+
setIsItemDragging(false);
|
|
6361
6795
|
el.setAttribute("contenteditable", "true");
|
|
6362
6796
|
el.removeAttribute("data-ohw-hovered");
|
|
6797
|
+
el.closest("[data-ohw-href-key]")?.removeAttribute("data-ohw-hovered");
|
|
6363
6798
|
activeElRef.current = el;
|
|
6364
6799
|
originalContentRef.current = el.innerHTML;
|
|
6365
6800
|
el.focus();
|
|
6366
|
-
setToolbarRect(el.getBoundingClientRect());
|
|
6367
6801
|
setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
|
|
6802
|
+
const navAnchor = getNavigationItemAnchor(el);
|
|
6803
|
+
if (navAnchor) {
|
|
6804
|
+
setReorderHrefKey(null);
|
|
6805
|
+
setReorderDragDisabled(false);
|
|
6806
|
+
} else {
|
|
6807
|
+
const { key: reorderKey, disabled: reorderDisabled } = getReorderHandleState(el);
|
|
6808
|
+
setReorderHrefKey(reorderKey);
|
|
6809
|
+
setReorderDragDisabled(reorderDisabled);
|
|
6810
|
+
}
|
|
6811
|
+
setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
6368
6812
|
postToParent({ type: "ow:enter-edit", key: el.dataset.ohwKey });
|
|
6369
6813
|
requestAnimationFrame(() => refreshActiveCommandsRef.current());
|
|
6370
6814
|
}, [deactivate, postToParent]);
|
|
@@ -6556,18 +7000,25 @@ function OhhwellsBridge() {
|
|
|
6556
7000
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
6557
7001
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
6558
7002
|
[data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
|
|
6559
|
-
[data-ohw-hovered]:not([contenteditable]) {
|
|
6560
|
-
outline: 2px dashed ${
|
|
7003
|
+
[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
|
|
7004
|
+
outline: 2px dashed ${PRIMARY2} !important;
|
|
6561
7005
|
outline-offset: 4px;
|
|
6562
7006
|
border-radius: 2px;
|
|
6563
7007
|
}
|
|
7008
|
+
[data-ohw-href-key] [data-ohw-hovered],
|
|
7009
|
+
[data-ohw-href-key][data-ohw-hovered],
|
|
7010
|
+
nav [data-ohw-href-key] [data-ohw-hovered],
|
|
7011
|
+
footer [data-ohw-href-key] [data-ohw-hovered] {
|
|
7012
|
+
outline: none !important;
|
|
7013
|
+
outline-offset: 0 !important;
|
|
7014
|
+
}
|
|
6564
7015
|
[data-ohw-editable][contenteditable] {
|
|
6565
7016
|
outline: none !important;
|
|
6566
|
-
caret-color: ${
|
|
7017
|
+
caret-color: ${PRIMARY2};
|
|
6567
7018
|
cursor: text !important;
|
|
6568
7019
|
}
|
|
6569
7020
|
[data-ohw-editable][contenteditable]::selection,
|
|
6570
|
-
[data-ohw-editable][contenteditable] *::selection { background: ${
|
|
7021
|
+
[data-ohw-editable][contenteditable] *::selection { background: ${PRIMARY2}59 !important; }
|
|
6571
7022
|
[data-ohw-editable-state], [data-ohw-editable-state] * { pointer-events: none !important; }
|
|
6572
7023
|
[data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
|
|
6573
7024
|
[data-ohw-editable-state][data-ohw-active-state][data-ohw-editable] { pointer-events: auto !important; }
|
|
@@ -6579,7 +7030,7 @@ function OhhwellsBridge() {
|
|
|
6579
7030
|
stateViews.textContent = `
|
|
6580
7031
|
[data-ohw-state-view]:not([data-ohw-state-view="default"]) { display: none; }
|
|
6581
7032
|
[data-ohw-state-view="default"] [data-ohw-editable] { pointer-events: auto !important; }
|
|
6582
|
-
[data-ohw-state-hovered] { outline: 2px dashed ${
|
|
7033
|
+
[data-ohw-state-hovered] { outline: 2px dashed ${PRIMARY2} !important; outline-offset: 4px; border-radius: 2px; }
|
|
6583
7034
|
[data-ohw-state-hovered]:has([data-ohw-hovered]) { outline: none !important; }
|
|
6584
7035
|
`;
|
|
6585
7036
|
document.head.appendChild(base);
|
|
@@ -6594,6 +7045,11 @@ function OhhwellsBridge() {
|
|
|
6594
7045
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
6595
7046
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
6596
7047
|
if (isInsideLinkEditor(target)) return;
|
|
7048
|
+
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
7049
|
+
e.preventDefault();
|
|
7050
|
+
e.stopPropagation();
|
|
7051
|
+
return;
|
|
7052
|
+
}
|
|
6597
7053
|
const editable = target.closest("[data-ohw-editable]");
|
|
6598
7054
|
if (editable) {
|
|
6599
7055
|
if (editable.dataset.ohwEditable === "link") {
|
|
@@ -6615,15 +7071,15 @@ function OhhwellsBridge() {
|
|
|
6615
7071
|
return;
|
|
6616
7072
|
}
|
|
6617
7073
|
const hrefCtx = getHrefKeyFromElement(editable);
|
|
6618
|
-
|
|
7074
|
+
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
7075
|
+
if (navAnchor) {
|
|
6619
7076
|
e.preventDefault();
|
|
6620
7077
|
e.stopPropagation();
|
|
6621
|
-
|
|
6622
|
-
if (selectedElRef.current === anchor2) {
|
|
7078
|
+
if (selectedElRef.current === navAnchor) {
|
|
6623
7079
|
activateRef.current(editable);
|
|
6624
7080
|
return;
|
|
6625
7081
|
}
|
|
6626
|
-
selectRef.current(
|
|
7082
|
+
selectRef.current(navAnchor);
|
|
6627
7083
|
return;
|
|
6628
7084
|
}
|
|
6629
7085
|
e.preventDefault();
|
|
@@ -6631,8 +7087,8 @@ function OhhwellsBridge() {
|
|
|
6631
7087
|
activateRef.current(editable);
|
|
6632
7088
|
return;
|
|
6633
7089
|
}
|
|
6634
|
-
const hrefAnchor = target
|
|
6635
|
-
if (hrefAnchor
|
|
7090
|
+
const hrefAnchor = getNavigationItemAnchor(target);
|
|
7091
|
+
if (hrefAnchor) {
|
|
6636
7092
|
e.preventDefault();
|
|
6637
7093
|
e.stopPropagation();
|
|
6638
7094
|
if (selectedElRef.current === hrefAnchor) return;
|
|
@@ -6665,19 +7121,58 @@ function OhhwellsBridge() {
|
|
|
6665
7121
|
deactivateRef.current();
|
|
6666
7122
|
};
|
|
6667
7123
|
const handleMouseOver = (e) => {
|
|
6668
|
-
const
|
|
7124
|
+
const target = e.target;
|
|
7125
|
+
const navAnchor = getNavigationItemAnchor(target);
|
|
7126
|
+
if (navAnchor) {
|
|
7127
|
+
const selected2 = selectedElRef.current;
|
|
7128
|
+
if (selected2 === navAnchor || selected2?.contains(navAnchor)) return;
|
|
7129
|
+
clearHrefKeyHover(navAnchor);
|
|
7130
|
+
hoveredItemElRef.current = navAnchor;
|
|
7131
|
+
setHoveredItemRect(navAnchor.getBoundingClientRect());
|
|
7132
|
+
return;
|
|
7133
|
+
}
|
|
7134
|
+
const editable = target.closest("[data-ohw-editable]");
|
|
6669
7135
|
if (!editable) return;
|
|
6670
7136
|
const selected = selectedElRef.current;
|
|
6671
7137
|
if (selected && (selected === editable || selected.contains(editable))) return;
|
|
6672
7138
|
if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image" && !editable.hasAttribute("contenteditable")) {
|
|
6673
|
-
editable.
|
|
7139
|
+
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
7140
|
+
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
7141
|
+
clearHrefKeyHover(hoverTarget);
|
|
7142
|
+
hoveredItemElRef.current = hoverTarget;
|
|
7143
|
+
setHoveredItemRect(hoverTarget.getBoundingClientRect());
|
|
7144
|
+
} else if (!isInsideNavigationItem(editable)) {
|
|
7145
|
+
hoverTarget.setAttribute("data-ohw-hovered", "");
|
|
7146
|
+
}
|
|
6674
7147
|
}
|
|
6675
7148
|
};
|
|
6676
7149
|
const handleMouseOut = (e) => {
|
|
6677
|
-
const
|
|
7150
|
+
const target = e.target;
|
|
7151
|
+
const navAnchor = getNavigationItemAnchor(target);
|
|
7152
|
+
if (navAnchor) {
|
|
7153
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
7154
|
+
if (related2?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
7155
|
+
if (related2 && navAnchor.contains(related2)) return;
|
|
7156
|
+
if (hoveredItemElRef.current === navAnchor) {
|
|
7157
|
+
hoveredItemElRef.current = null;
|
|
7158
|
+
setHoveredItemRect(null);
|
|
7159
|
+
}
|
|
7160
|
+
return;
|
|
7161
|
+
}
|
|
7162
|
+
const editable = target.closest("[data-ohw-editable]");
|
|
6678
7163
|
if (!editable) return;
|
|
7164
|
+
const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
7165
|
+
if (related?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
6679
7166
|
if (editable.dataset.ohwEditable !== "image" && editable.dataset.ohwEditable !== "bg-image") {
|
|
6680
|
-
editable.
|
|
7167
|
+
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
7168
|
+
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
7169
|
+
if (!related?.closest("[data-ohw-href-key]")) {
|
|
7170
|
+
hoveredItemElRef.current = null;
|
|
7171
|
+
setHoveredItemRect(null);
|
|
7172
|
+
}
|
|
7173
|
+
} else {
|
|
7174
|
+
hoverTarget.removeAttribute("data-ohw-hovered");
|
|
7175
|
+
}
|
|
6681
7176
|
}
|
|
6682
7177
|
};
|
|
6683
7178
|
const toProbeCoords = (clientX, clientY, fromParentViewport) => {
|
|
@@ -6792,11 +7287,20 @@ function OhhwellsBridge() {
|
|
|
6792
7287
|
return;
|
|
6793
7288
|
}
|
|
6794
7289
|
}
|
|
7290
|
+
if (activeElRef.current) {
|
|
7291
|
+
if (hoveredImageRef.current) {
|
|
7292
|
+
hoveredImageRef.current = null;
|
|
7293
|
+
hoveredImageHasTextOverlapRef.current = false;
|
|
7294
|
+
resumeAnimTracks();
|
|
7295
|
+
postToParentRef.current({ type: "ow:image-unhover" });
|
|
7296
|
+
}
|
|
7297
|
+
return;
|
|
7298
|
+
}
|
|
6795
7299
|
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
6796
7300
|
if (imgEl) {
|
|
6797
7301
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
6798
7302
|
const topEl = document.elementFromPoint(x, y);
|
|
6799
|
-
if (topEl?.closest(
|
|
7303
|
+
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
6800
7304
|
if (hoveredImageRef.current) {
|
|
6801
7305
|
hoveredImageRef.current = null;
|
|
6802
7306
|
resumeAnimTracks();
|
|
@@ -6844,7 +7348,9 @@ function OhhwellsBridge() {
|
|
|
6844
7348
|
postImageHover(imgEl, isDragOver, true);
|
|
6845
7349
|
}
|
|
6846
7350
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
6847
|
-
textEditable
|
|
7351
|
+
if (textEditable && !isInsideNavigationItem(textEditable)) {
|
|
7352
|
+
textEditable.setAttribute("data-ohw-hovered", "");
|
|
7353
|
+
}
|
|
6848
7354
|
return;
|
|
6849
7355
|
}
|
|
6850
7356
|
if (hoveredImageRef.current) {
|
|
@@ -6854,7 +7360,9 @@ function OhhwellsBridge() {
|
|
|
6854
7360
|
postToParentRef.current({ type: "ow:image-unhover" });
|
|
6855
7361
|
}
|
|
6856
7362
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
6857
|
-
textEditable
|
|
7363
|
+
if (textEditable && !isInsideNavigationItem(textEditable)) {
|
|
7364
|
+
textEditable.setAttribute("data-ohw-hovered", "");
|
|
7365
|
+
}
|
|
6858
7366
|
return;
|
|
6859
7367
|
}
|
|
6860
7368
|
if (hoveredGapRef.current) {
|
|
@@ -6898,7 +7406,24 @@ function OhhwellsBridge() {
|
|
|
6898
7406
|
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
6899
7407
|
});
|
|
6900
7408
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
6901
|
-
if (textEl && !textEl.hasAttribute("contenteditable"))
|
|
7409
|
+
if (textEl && !textEl.hasAttribute("contenteditable")) {
|
|
7410
|
+
const navAnchor = getNavigationItemAnchor(textEl);
|
|
7411
|
+
if (navAnchor) {
|
|
7412
|
+
const selected = selectedElRef.current;
|
|
7413
|
+
if (selected !== navAnchor && !selected?.contains(navAnchor)) {
|
|
7414
|
+
clearHrefKeyHover(navAnchor);
|
|
7415
|
+
hoveredItemElRef.current = navAnchor;
|
|
7416
|
+
setHoveredItemRect(navAnchor.getBoundingClientRect());
|
|
7417
|
+
}
|
|
7418
|
+
} else {
|
|
7419
|
+
hoveredItemElRef.current = null;
|
|
7420
|
+
setHoveredItemRect(null);
|
|
7421
|
+
textEl.setAttribute("data-ohw-hovered", "");
|
|
7422
|
+
}
|
|
7423
|
+
} else {
|
|
7424
|
+
hoveredItemElRef.current = null;
|
|
7425
|
+
setHoveredItemRect(null);
|
|
7426
|
+
}
|
|
6902
7427
|
}
|
|
6903
7428
|
};
|
|
6904
7429
|
const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
|
|
@@ -7089,7 +7614,7 @@ function OhhwellsBridge() {
|
|
|
7089
7614
|
const el = e.target;
|
|
7090
7615
|
const key = el.dataset.ohwKey;
|
|
7091
7616
|
if (!key) return;
|
|
7092
|
-
if (el === activeElRef.current) setToolbarRect(el.getBoundingClientRect());
|
|
7617
|
+
if (el === activeElRef.current) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
|
|
7093
7618
|
const maxLen = el.dataset.ohwMaxLength ? parseInt(el.dataset.ohwMaxLength, 10) : null;
|
|
7094
7619
|
if (maxLen) {
|
|
7095
7620
|
const current = el.innerText.replace(/\n$/, "").length;
|
|
@@ -7176,6 +7701,33 @@ function OhhwellsBridge() {
|
|
|
7176
7701
|
deselectRef.current();
|
|
7177
7702
|
return;
|
|
7178
7703
|
}
|
|
7704
|
+
if (e.key === "Escape" && activeElRef.current) {
|
|
7705
|
+
const hrefCtx = getHrefKeyFromElement(activeElRef.current);
|
|
7706
|
+
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
7707
|
+
if (navAnchor) {
|
|
7708
|
+
e.preventDefault();
|
|
7709
|
+
const el2 = activeElRef.current;
|
|
7710
|
+
if (originalContentRef.current !== null) {
|
|
7711
|
+
el2.innerHTML = originalContentRef.current;
|
|
7712
|
+
}
|
|
7713
|
+
el2.removeAttribute("contenteditable");
|
|
7714
|
+
activeElRef.current = null;
|
|
7715
|
+
setMaxBadge(null);
|
|
7716
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
7717
|
+
setToolbarShowEditLink(false);
|
|
7718
|
+
postToParentRef.current({ type: "ow:exit-edit" });
|
|
7719
|
+
reselectNavigationItemRef.current(navAnchor);
|
|
7720
|
+
return;
|
|
7721
|
+
}
|
|
7722
|
+
}
|
|
7723
|
+
if (e.key === "Enter" && !e.shiftKey && activeElRef.current) {
|
|
7724
|
+
const navAnchor = getNavigationItemAnchor(activeElRef.current);
|
|
7725
|
+
if (navAnchor) {
|
|
7726
|
+
e.preventDefault();
|
|
7727
|
+
commitNavigationTextEditRef.current(navAnchor);
|
|
7728
|
+
return;
|
|
7729
|
+
}
|
|
7730
|
+
}
|
|
7179
7731
|
if (e.key !== "Escape") return;
|
|
7180
7732
|
const el = activeElRef.current;
|
|
7181
7733
|
if (el && originalContentRef.current !== null) {
|
|
@@ -7191,7 +7743,8 @@ function OhhwellsBridge() {
|
|
|
7191
7743
|
const handleScroll = () => {
|
|
7192
7744
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
7193
7745
|
if (focusEl) {
|
|
7194
|
-
const
|
|
7746
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
|
|
7747
|
+
const r2 = measureEl.getBoundingClientRect();
|
|
7195
7748
|
applyToolbarPos(r2);
|
|
7196
7749
|
setToolbarRect(r2);
|
|
7197
7750
|
setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
|
|
@@ -7200,6 +7753,12 @@ function OhhwellsBridge() {
|
|
|
7200
7753
|
const rect = activeStateElRef.current.getBoundingClientRect();
|
|
7201
7754
|
setToggleState((prev) => prev ? { ...prev, rect } : null);
|
|
7202
7755
|
}
|
|
7756
|
+
if (hoveredItemElRef.current) {
|
|
7757
|
+
setHoveredItemRect(hoveredItemElRef.current.getBoundingClientRect());
|
|
7758
|
+
}
|
|
7759
|
+
if (siblingHintElRef.current) {
|
|
7760
|
+
setSiblingHintRect(siblingHintElRef.current.getBoundingClientRect());
|
|
7761
|
+
}
|
|
7203
7762
|
if (hoveredImageRef.current) {
|
|
7204
7763
|
const el = hoveredImageRef.current;
|
|
7205
7764
|
const r2 = el.getBoundingClientRect();
|
|
@@ -7319,7 +7878,7 @@ function OhhwellsBridge() {
|
|
|
7319
7878
|
};
|
|
7320
7879
|
const applyToolbarPos = (rect) => {
|
|
7321
7880
|
const ps = parentScrollRef.current;
|
|
7322
|
-
const approxW =
|
|
7881
|
+
const approxW = 330;
|
|
7323
7882
|
if (toolbarElRef.current) {
|
|
7324
7883
|
const { top, left, transform } = calcToolbarPos(rect, ps, approxW);
|
|
7325
7884
|
toolbarElRef.current.style.top = `${top}px`;
|
|
@@ -7330,6 +7889,8 @@ function OhhwellsBridge() {
|
|
|
7330
7889
|
const GAP = 6;
|
|
7331
7890
|
glowElRef.current.style.top = `${rect.top - GAP}px`;
|
|
7332
7891
|
glowElRef.current.style.left = `${rect.left - GAP}px`;
|
|
7892
|
+
glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
|
|
7893
|
+
glowElRef.current.style.height = `${rect.height + GAP * 2}px`;
|
|
7333
7894
|
}
|
|
7334
7895
|
};
|
|
7335
7896
|
const handleParentScroll = (e) => {
|
|
@@ -7340,7 +7901,10 @@ function OhhwellsBridge() {
|
|
|
7340
7901
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
7341
7902
|
}
|
|
7342
7903
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
7343
|
-
if (focusEl)
|
|
7904
|
+
if (focusEl) {
|
|
7905
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
|
|
7906
|
+
applyToolbarPos(measureEl.getBoundingClientRect());
|
|
7907
|
+
}
|
|
7344
7908
|
};
|
|
7345
7909
|
const handleClickAt = (e) => {
|
|
7346
7910
|
if (e.data?.type !== "ow:click-at") return;
|
|
@@ -7498,7 +8062,7 @@ function OhhwellsBridge() {
|
|
|
7498
8062
|
const handleCommand = (0, import_react6.useCallback)((cmd) => {
|
|
7499
8063
|
document.execCommand(cmd, false);
|
|
7500
8064
|
activeElRef.current?.focus();
|
|
7501
|
-
if (activeElRef.current) setToolbarRect(activeElRef.current.getBoundingClientRect());
|
|
8065
|
+
if (activeElRef.current) setToolbarRect(getEditMeasureEl(activeElRef.current).getBoundingClientRect());
|
|
7502
8066
|
refreshActiveCommandsRef.current();
|
|
7503
8067
|
}, []);
|
|
7504
8068
|
const handleStateChange = (0, import_react6.useCallback)((state) => {
|
|
@@ -7551,37 +8115,55 @@ function OhhwellsBridge() {
|
|
|
7551
8115
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
7552
8116
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
7553
8117
|
return bridgeRoot ? (0, import_react_dom2.createPortal)(
|
|
7554
|
-
/* @__PURE__ */ (0,
|
|
7555
|
-
/* @__PURE__ */ (0,
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
8118
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
8119
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
8120
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
8121
|
+
hoveredItemRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
8122
|
+
toolbarRect && toolbarVariant === "link-action" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
8123
|
+
ItemInteractionLayer,
|
|
8124
|
+
{
|
|
8125
|
+
rect: toolbarRect,
|
|
8126
|
+
elRef: glowElRef,
|
|
8127
|
+
state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
|
|
8128
|
+
showHandle: Boolean(reorderHrefKey),
|
|
8129
|
+
dragDisabled: reorderDragDisabled,
|
|
8130
|
+
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
8131
|
+
onDragHandleDragStart: handleItemDragStart,
|
|
8132
|
+
onDragHandleDragEnd: handleItemDragEnd,
|
|
8133
|
+
toolbar: isItemDragging ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
8134
|
+
ItemActionToolbar,
|
|
8135
|
+
{
|
|
8136
|
+
onEditLink: openLinkPopoverForSelected,
|
|
8137
|
+
onAddItem: handleAddNavigationItem,
|
|
8138
|
+
addItemDisabled: false
|
|
8139
|
+
}
|
|
8140
|
+
)
|
|
8141
|
+
}
|
|
8142
|
+
),
|
|
8143
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
8144
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
8145
|
+
EditGlowChrome,
|
|
7560
8146
|
{
|
|
7561
|
-
variant: "rich-text",
|
|
7562
8147
|
rect: toolbarRect,
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
activeCommands,
|
|
7567
|
-
showEditLink,
|
|
7568
|
-
onEditLink: openLinkPopoverForActive
|
|
8148
|
+
elRef: glowElRef,
|
|
8149
|
+
reorderHrefKey,
|
|
8150
|
+
dragDisabled: reorderDragDisabled
|
|
7569
8151
|
}
|
|
7570
8152
|
),
|
|
7571
|
-
|
|
8153
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7572
8154
|
FloatingToolbar,
|
|
7573
8155
|
{
|
|
7574
|
-
variant: "link-action",
|
|
7575
8156
|
rect: toolbarRect,
|
|
7576
8157
|
parentScroll: parentScrollRef.current,
|
|
7577
8158
|
elRef: toolbarElRef,
|
|
7578
8159
|
onCommand: handleCommand,
|
|
7579
8160
|
activeCommands,
|
|
7580
|
-
|
|
8161
|
+
showEditLink,
|
|
8162
|
+
onEditLink: openLinkPopoverForActive
|
|
7581
8163
|
}
|
|
7582
8164
|
)
|
|
7583
8165
|
] }),
|
|
7584
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
8166
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
7585
8167
|
"div",
|
|
7586
8168
|
{
|
|
7587
8169
|
"data-ohw-max-badge": "",
|
|
@@ -7607,7 +8189,7 @@ function OhhwellsBridge() {
|
|
|
7607
8189
|
]
|
|
7608
8190
|
}
|
|
7609
8191
|
),
|
|
7610
|
-
toggleState && /* @__PURE__ */ (0,
|
|
8192
|
+
toggleState && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7611
8193
|
StateToggle,
|
|
7612
8194
|
{
|
|
7613
8195
|
rect: toggleState.rect,
|
|
@@ -7616,15 +8198,15 @@ function OhhwellsBridge() {
|
|
|
7616
8198
|
onStateChange: handleStateChange
|
|
7617
8199
|
}
|
|
7618
8200
|
),
|
|
7619
|
-
sectionGap && /* @__PURE__ */ (0,
|
|
8201
|
+
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
7620
8202
|
"div",
|
|
7621
8203
|
{
|
|
7622
8204
|
"data-ohw-section-insert-line": "",
|
|
7623
8205
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
7624
8206
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
7625
8207
|
children: [
|
|
7626
|
-
/* @__PURE__ */ (0,
|
|
7627
|
-
/* @__PURE__ */ (0,
|
|
8208
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
8209
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7628
8210
|
Badge,
|
|
7629
8211
|
{
|
|
7630
8212
|
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",
|
|
@@ -7637,11 +8219,11 @@ function OhhwellsBridge() {
|
|
|
7637
8219
|
children: "Add Section"
|
|
7638
8220
|
}
|
|
7639
8221
|
),
|
|
7640
|
-
/* @__PURE__ */ (0,
|
|
8222
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
7641
8223
|
]
|
|
7642
8224
|
}
|
|
7643
8225
|
),
|
|
7644
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0,
|
|
8226
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
7645
8227
|
LinkPopover,
|
|
7646
8228
|
{
|
|
7647
8229
|
panelRef: linkPopoverPanelRef,
|
|
@@ -7656,13 +8238,44 @@ function OhhwellsBridge() {
|
|
|
7656
8238
|
onSubmit: handleLinkPopoverSubmit
|
|
7657
8239
|
},
|
|
7658
8240
|
`${linkPopover.key}-${pathname}`
|
|
7659
|
-
) : null
|
|
8241
|
+
) : null,
|
|
8242
|
+
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
8243
|
+
"div",
|
|
8244
|
+
{
|
|
8245
|
+
"data-ohw-section-insert-line": "",
|
|
8246
|
+
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8247
|
+
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8248
|
+
children: [
|
|
8249
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
8250
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
8251
|
+
Badge,
|
|
8252
|
+
{
|
|
8253
|
+
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",
|
|
8254
|
+
onClick: () => {
|
|
8255
|
+
window.parent.postMessage(
|
|
8256
|
+
{ type: "ow:add-section", insertAfter: sectionGap.insertAfter, insertBefore: sectionGap.insertBefore },
|
|
8257
|
+
"*"
|
|
8258
|
+
);
|
|
8259
|
+
},
|
|
8260
|
+
children: "Add Section"
|
|
8261
|
+
}
|
|
8262
|
+
),
|
|
8263
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8264
|
+
]
|
|
8265
|
+
}
|
|
8266
|
+
)
|
|
7660
8267
|
] }),
|
|
7661
8268
|
bridgeRoot
|
|
7662
8269
|
) : null;
|
|
7663
8270
|
}
|
|
7664
8271
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7665
8272
|
0 && (module.exports = {
|
|
8273
|
+
CustomToolbar,
|
|
8274
|
+
CustomToolbarButton,
|
|
8275
|
+
CustomToolbarDivider,
|
|
8276
|
+
DragHandle,
|
|
8277
|
+
ItemActionToolbar,
|
|
8278
|
+
ItemInteractionLayer,
|
|
7666
8279
|
LinkEditorPanel,
|
|
7667
8280
|
LinkPopover,
|
|
7668
8281
|
OhhwellsBridge,
|
|
@@ -7670,9 +8283,14 @@ function OhhwellsBridge() {
|
|
|
7670
8283
|
Toggle,
|
|
7671
8284
|
ToggleGroup,
|
|
7672
8285
|
ToggleGroupItem,
|
|
8286
|
+
Tooltip,
|
|
8287
|
+
TooltipContent,
|
|
8288
|
+
TooltipProvider,
|
|
8289
|
+
TooltipTrigger,
|
|
7673
8290
|
buildTarget,
|
|
7674
8291
|
filterAvailablePages,
|
|
7675
8292
|
getEditModeInitialState,
|
|
8293
|
+
isEditSessionActive,
|
|
7676
8294
|
isValidUrl,
|
|
7677
8295
|
parseTarget,
|
|
7678
8296
|
toggleVariants,
|