@ohhwells/bridge 0.1.36-next.48 → 0.1.36-next.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +592 -241
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +635 -284
- package/dist/index.js.map +1 -1
- package/dist/styles.css +34 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4639,6 +4639,220 @@ function ItemInteractionLayer({
|
|
|
4639
4639
|
);
|
|
4640
4640
|
}
|
|
4641
4641
|
|
|
4642
|
+
// src/ui/MediaOverlay.tsx
|
|
4643
|
+
var React6 = __toESM(require("react"), 1);
|
|
4644
|
+
var import_lucide_react3 = require("lucide-react");
|
|
4645
|
+
|
|
4646
|
+
// src/ui/button.tsx
|
|
4647
|
+
var React5 = __toESM(require("react"), 1);
|
|
4648
|
+
var import_radix_ui4 = require("radix-ui");
|
|
4649
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
4650
|
+
var buttonVariants = cva(
|
|
4651
|
+
"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",
|
|
4652
|
+
{
|
|
4653
|
+
variants: {
|
|
4654
|
+
variant: {
|
|
4655
|
+
default: "bg-primary text-primary-foreground hover:opacity-90",
|
|
4656
|
+
outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
|
|
4657
|
+
ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
|
|
4658
|
+
},
|
|
4659
|
+
size: {
|
|
4660
|
+
default: "h-9",
|
|
4661
|
+
sm: "h-8 min-w-[64px] px-2 py-1.5 text-sm"
|
|
4662
|
+
}
|
|
4663
|
+
},
|
|
4664
|
+
defaultVariants: {
|
|
4665
|
+
variant: "default",
|
|
4666
|
+
size: "default"
|
|
4667
|
+
}
|
|
4668
|
+
}
|
|
4669
|
+
);
|
|
4670
|
+
var Button = React5.forwardRef(
|
|
4671
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
4672
|
+
const Comp = asChild ? import_radix_ui4.Slot.Root : "button";
|
|
4673
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
4674
|
+
Comp,
|
|
4675
|
+
{
|
|
4676
|
+
ref,
|
|
4677
|
+
"data-slot": "button",
|
|
4678
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
4679
|
+
...props
|
|
4680
|
+
}
|
|
4681
|
+
);
|
|
4682
|
+
}
|
|
4683
|
+
);
|
|
4684
|
+
Button.displayName = "Button";
|
|
4685
|
+
|
|
4686
|
+
// src/ui/MediaOverlay.tsx
|
|
4687
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
4688
|
+
var MEDIA_UPLOAD_FADE_MS = 300;
|
|
4689
|
+
var VIDEO_SETTINGS_BAR_INSET = 8;
|
|
4690
|
+
var OVERLAY_BUTTON_STYLE = {
|
|
4691
|
+
pointerEvents: "auto",
|
|
4692
|
+
fontFamily: "Inter, sans-serif",
|
|
4693
|
+
fontSize: 12,
|
|
4694
|
+
color: "#000"
|
|
4695
|
+
};
|
|
4696
|
+
var SKELETON_CSS = `
|
|
4697
|
+
@keyframes ohw-media-shimmer {
|
|
4698
|
+
0% { transform: translateX(-100%); }
|
|
4699
|
+
100% { transform: translateX(100%); }
|
|
4700
|
+
}
|
|
4701
|
+
[data-ohw-media-skeleton] {
|
|
4702
|
+
overflow: hidden;
|
|
4703
|
+
background-color: #d1d5db; /* tailwind gray-300 */
|
|
4704
|
+
}
|
|
4705
|
+
[data-ohw-media-skeleton]::after {
|
|
4706
|
+
content: "";
|
|
4707
|
+
position: absolute;
|
|
4708
|
+
inset: 0;
|
|
4709
|
+
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.6), transparent);
|
|
4710
|
+
animation: ohw-media-shimmer 1.4s infinite;
|
|
4711
|
+
}
|
|
4712
|
+
`;
|
|
4713
|
+
function MediaOverlay({
|
|
4714
|
+
hover,
|
|
4715
|
+
isUploading,
|
|
4716
|
+
fadingOut = false,
|
|
4717
|
+
onFadeOutComplete,
|
|
4718
|
+
onReplace,
|
|
4719
|
+
onVideoSettingsChange
|
|
4720
|
+
}) {
|
|
4721
|
+
const { rect } = hover;
|
|
4722
|
+
const skeletonRef = React6.useRef(null);
|
|
4723
|
+
const isVideo = hover.elementType === "video";
|
|
4724
|
+
const autoplay = hover.videoAutoplay ?? true;
|
|
4725
|
+
const muted = hover.videoMuted ?? true;
|
|
4726
|
+
const box = {
|
|
4727
|
+
position: "fixed",
|
|
4728
|
+
top: rect.top,
|
|
4729
|
+
left: rect.left,
|
|
4730
|
+
width: rect.width,
|
|
4731
|
+
height: rect.height,
|
|
4732
|
+
zIndex: 2147483646
|
|
4733
|
+
};
|
|
4734
|
+
React6.useEffect(() => {
|
|
4735
|
+
if (!isUploading || !fadingOut || !skeletonRef.current) return;
|
|
4736
|
+
const anim = skeletonRef.current.animate([{ opacity: 1 }, { opacity: 0 }], {
|
|
4737
|
+
duration: MEDIA_UPLOAD_FADE_MS,
|
|
4738
|
+
easing: "ease-out",
|
|
4739
|
+
fill: "forwards"
|
|
4740
|
+
});
|
|
4741
|
+
anim.finished.then(() => onFadeOutComplete?.(hover.key)).catch(() => onFadeOutComplete?.(hover.key));
|
|
4742
|
+
return () => anim.cancel();
|
|
4743
|
+
}, [isUploading, fadingOut, onFadeOutComplete, hover.key]);
|
|
4744
|
+
if (isUploading) {
|
|
4745
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4746
|
+
"div",
|
|
4747
|
+
{
|
|
4748
|
+
ref: skeletonRef,
|
|
4749
|
+
"data-ohw-bridge": "",
|
|
4750
|
+
"data-ohw-media-overlay": "",
|
|
4751
|
+
"data-ohw-media-skeleton": "",
|
|
4752
|
+
"aria-hidden": true,
|
|
4753
|
+
style: { ...box, pointerEvents: "none" },
|
|
4754
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("style", { children: SKELETON_CSS })
|
|
4755
|
+
}
|
|
4756
|
+
);
|
|
4757
|
+
}
|
|
4758
|
+
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4759
|
+
"div",
|
|
4760
|
+
{
|
|
4761
|
+
"data-ohw-bridge": "",
|
|
4762
|
+
"data-ohw-media-overlay": "",
|
|
4763
|
+
className: "flex items-center justify-center gap-1.5",
|
|
4764
|
+
style: {
|
|
4765
|
+
position: "fixed",
|
|
4766
|
+
top: rect.top + VIDEO_SETTINGS_BAR_INSET,
|
|
4767
|
+
left: rect.left,
|
|
4768
|
+
width: rect.width,
|
|
4769
|
+
zIndex: 2147483647,
|
|
4770
|
+
pointerEvents: "auto"
|
|
4771
|
+
},
|
|
4772
|
+
onClick: (e) => e.stopPropagation(),
|
|
4773
|
+
children: [
|
|
4774
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4775
|
+
Button,
|
|
4776
|
+
{
|
|
4777
|
+
"data-ohw-media-overlay": "",
|
|
4778
|
+
variant: "outline",
|
|
4779
|
+
size: "sm",
|
|
4780
|
+
className: "cursor-pointer hover:bg-background",
|
|
4781
|
+
style: { ...OVERLAY_BUTTON_STYLE, minWidth: 0, padding: "0 8px" },
|
|
4782
|
+
"aria-label": autoplay ? "Disable autoplay" : "Enable autoplay",
|
|
4783
|
+
title: autoplay ? "Autoplay on \u2014 click to disable" : "Autoplay off \u2014 click to enable",
|
|
4784
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4785
|
+
onClick: (e) => {
|
|
4786
|
+
e.stopPropagation();
|
|
4787
|
+
onVideoSettingsChange?.(hover.key, { autoplay: !autoplay });
|
|
4788
|
+
},
|
|
4789
|
+
children: autoplay ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Pause, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Play, { size: 14 })
|
|
4790
|
+
}
|
|
4791
|
+
),
|
|
4792
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4793
|
+
Button,
|
|
4794
|
+
{
|
|
4795
|
+
"data-ohw-media-overlay": "",
|
|
4796
|
+
variant: "outline",
|
|
4797
|
+
size: "sm",
|
|
4798
|
+
className: "cursor-pointer hover:bg-background",
|
|
4799
|
+
style: { ...OVERLAY_BUTTON_STYLE, minWidth: 0, padding: "0 8px" },
|
|
4800
|
+
"aria-label": muted ? "Unmute video" : "Mute video",
|
|
4801
|
+
title: muted ? "Muted \u2014 click to unmute" : "Sound on \u2014 click to mute",
|
|
4802
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4803
|
+
onClick: (e) => {
|
|
4804
|
+
e.stopPropagation();
|
|
4805
|
+
onVideoSettingsChange?.(hover.key, { muted: !muted });
|
|
4806
|
+
},
|
|
4807
|
+
children: muted ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.VolumeX, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Volume2, { size: 14 })
|
|
4808
|
+
}
|
|
4809
|
+
)
|
|
4810
|
+
]
|
|
4811
|
+
}
|
|
4812
|
+
) : null;
|
|
4813
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
4814
|
+
settingsBar,
|
|
4815
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
4816
|
+
"div",
|
|
4817
|
+
{
|
|
4818
|
+
"data-ohw-bridge": "",
|
|
4819
|
+
"data-ohw-media-overlay": "",
|
|
4820
|
+
className: "flex items-center justify-center cursor-pointer",
|
|
4821
|
+
style: {
|
|
4822
|
+
...box,
|
|
4823
|
+
// When text overlays this media, let clicks fall THROUGH to the text underneath. In the
|
|
4824
|
+
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
4825
|
+
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
4826
|
+
// Replace still works.
|
|
4827
|
+
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
4828
|
+
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
4829
|
+
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
4830
|
+
},
|
|
4831
|
+
onClick: () => onReplace(hover.key),
|
|
4832
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
4833
|
+
Button,
|
|
4834
|
+
{
|
|
4835
|
+
"data-ohw-media-overlay": "",
|
|
4836
|
+
variant: "outline",
|
|
4837
|
+
size: "sm",
|
|
4838
|
+
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
4839
|
+
style: OVERLAY_BUTTON_STYLE,
|
|
4840
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
4841
|
+
onClick: (e) => {
|
|
4842
|
+
e.stopPropagation();
|
|
4843
|
+
onReplace(hover.key);
|
|
4844
|
+
},
|
|
4845
|
+
children: [
|
|
4846
|
+
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.ImageIcon, { size: 14 }),
|
|
4847
|
+
isVideo ? "Replace video" : "Replace image"
|
|
4848
|
+
]
|
|
4849
|
+
}
|
|
4850
|
+
)
|
|
4851
|
+
}
|
|
4852
|
+
)
|
|
4853
|
+
] });
|
|
4854
|
+
}
|
|
4855
|
+
|
|
4642
4856
|
// src/OhhwellsBridge.tsx
|
|
4643
4857
|
var import_react_dom2 = require("react-dom");
|
|
4644
4858
|
var import_navigation = require("next/navigation");
|
|
@@ -4918,61 +5132,61 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
|
|
|
4918
5132
|
}
|
|
4919
5133
|
|
|
4920
5134
|
// src/ui/dialog.tsx
|
|
4921
|
-
var
|
|
4922
|
-
var
|
|
5135
|
+
var React7 = __toESM(require("react"), 1);
|
|
5136
|
+
var import_radix_ui5 = require("radix-ui");
|
|
4923
5137
|
|
|
4924
5138
|
// src/ui/icons.tsx
|
|
4925
|
-
var
|
|
5139
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
4926
5140
|
function IconX({ className, ...props }) {
|
|
4927
|
-
return /* @__PURE__ */ (0,
|
|
4928
|
-
/* @__PURE__ */ (0,
|
|
4929
|
-
/* @__PURE__ */ (0,
|
|
5141
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5142
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M18 6 6 18" }),
|
|
5143
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m6 6 12 12" })
|
|
4930
5144
|
] });
|
|
4931
5145
|
}
|
|
4932
5146
|
function IconChevronDown({ className, ...props }) {
|
|
4933
|
-
return /* @__PURE__ */ (0,
|
|
5147
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m6 9 6 6 6-6" }) });
|
|
4934
5148
|
}
|
|
4935
5149
|
function IconFile({ className, ...props }) {
|
|
4936
|
-
return /* @__PURE__ */ (0,
|
|
4937
|
-
/* @__PURE__ */ (0,
|
|
4938
|
-
/* @__PURE__ */ (0,
|
|
5150
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5151
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
|
|
5152
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
|
|
4939
5153
|
] });
|
|
4940
5154
|
}
|
|
4941
5155
|
function IconInfo({ className, ...props }) {
|
|
4942
|
-
return /* @__PURE__ */ (0,
|
|
4943
|
-
/* @__PURE__ */ (0,
|
|
4944
|
-
/* @__PURE__ */ (0,
|
|
4945
|
-
/* @__PURE__ */ (0,
|
|
5156
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5157
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
5158
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M12 16v-4" }),
|
|
5159
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M12 8h.01" })
|
|
4946
5160
|
] });
|
|
4947
5161
|
}
|
|
4948
5162
|
function IconArrowRight({ className, ...props }) {
|
|
4949
|
-
return /* @__PURE__ */ (0,
|
|
4950
|
-
/* @__PURE__ */ (0,
|
|
4951
|
-
/* @__PURE__ */ (0,
|
|
5163
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5164
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "M5 12h14" }),
|
|
5165
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { d: "m12 5 7 7-7 7" })
|
|
4952
5166
|
] });
|
|
4953
5167
|
}
|
|
4954
5168
|
function IconSection({ className, ...props }) {
|
|
4955
|
-
return /* @__PURE__ */ (0,
|
|
4956
|
-
/* @__PURE__ */ (0,
|
|
4957
|
-
/* @__PURE__ */ (0,
|
|
4958
|
-
/* @__PURE__ */ (0,
|
|
5169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, ...props, children: [
|
|
5170
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { width: "18", height: "7", x: "3", y: "3", rx: "1" }),
|
|
5171
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { width: "9", height: "7", x: "3", y: "14", rx: "1" }),
|
|
5172
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("rect", { width: "5", height: "7", x: "16", y: "14", rx: "1" })
|
|
4959
5173
|
] });
|
|
4960
5174
|
}
|
|
4961
5175
|
|
|
4962
5176
|
// src/ui/dialog.tsx
|
|
4963
|
-
var
|
|
5177
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
4964
5178
|
function Dialog2({ ...props }) {
|
|
4965
|
-
return /* @__PURE__ */ (0,
|
|
5179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui5.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
4966
5180
|
}
|
|
4967
5181
|
function DialogPortal({ ...props }) {
|
|
4968
|
-
return /* @__PURE__ */ (0,
|
|
5182
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui5.Dialog.Portal, { ...props });
|
|
4969
5183
|
}
|
|
4970
5184
|
function DialogOverlay({
|
|
4971
5185
|
className,
|
|
4972
5186
|
...props
|
|
4973
5187
|
}) {
|
|
4974
|
-
return /* @__PURE__ */ (0,
|
|
4975
|
-
|
|
5188
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5189
|
+
import_radix_ui5.Dialog.Overlay,
|
|
4976
5190
|
{
|
|
4977
5191
|
"data-slot": "dialog-overlay",
|
|
4978
5192
|
"data-ohw-link-modal-root": "",
|
|
@@ -4981,12 +5195,12 @@ function DialogOverlay({
|
|
|
4981
5195
|
}
|
|
4982
5196
|
);
|
|
4983
5197
|
}
|
|
4984
|
-
var DialogContent =
|
|
5198
|
+
var DialogContent = React7.forwardRef(({ className, children, showCloseButton = true, container, ...props }, ref) => {
|
|
4985
5199
|
const positionMode = container ? "absolute" : "fixed";
|
|
4986
|
-
return /* @__PURE__ */ (0,
|
|
4987
|
-
/* @__PURE__ */ (0,
|
|
4988
|
-
/* @__PURE__ */ (0,
|
|
4989
|
-
|
|
5200
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogPortal, { container: container ?? void 0, children: [
|
|
5201
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
|
|
5202
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
5203
|
+
import_radix_ui5.Dialog.Content,
|
|
4990
5204
|
{
|
|
4991
5205
|
ref,
|
|
4992
5206
|
"data-slot": "dialog-content",
|
|
@@ -5001,13 +5215,13 @@ var DialogContent = React5.forwardRef(({ className, children, showCloseButton =
|
|
|
5001
5215
|
...props,
|
|
5002
5216
|
children: [
|
|
5003
5217
|
children,
|
|
5004
|
-
showCloseButton ? /* @__PURE__ */ (0,
|
|
5005
|
-
|
|
5218
|
+
showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5219
|
+
import_radix_ui5.Dialog.Close,
|
|
5006
5220
|
{
|
|
5007
5221
|
type: "button",
|
|
5008
5222
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5009
5223
|
"aria-label": "Close",
|
|
5010
|
-
children: /* @__PURE__ */ (0,
|
|
5224
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IconX, { "aria-hidden": true })
|
|
5011
5225
|
}
|
|
5012
5226
|
) : null
|
|
5013
5227
|
]
|
|
@@ -5015,105 +5229,65 @@ var DialogContent = React5.forwardRef(({ className, children, showCloseButton =
|
|
|
5015
5229
|
)
|
|
5016
5230
|
] });
|
|
5017
5231
|
});
|
|
5018
|
-
DialogContent.displayName =
|
|
5232
|
+
DialogContent.displayName = import_radix_ui5.Dialog.Content.displayName;
|
|
5019
5233
|
function DialogHeader({ className, ...props }) {
|
|
5020
|
-
return /* @__PURE__ */ (0,
|
|
5234
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
5021
5235
|
}
|
|
5022
5236
|
function DialogFooter({ className, ...props }) {
|
|
5023
|
-
return /* @__PURE__ */ (0,
|
|
5237
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("flex items-center justify-end gap-2", className), ...props });
|
|
5024
5238
|
}
|
|
5025
|
-
var DialogTitle =
|
|
5026
|
-
|
|
5239
|
+
var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5240
|
+
import_radix_ui5.Dialog.Title,
|
|
5027
5241
|
{
|
|
5028
5242
|
ref,
|
|
5029
5243
|
className: cn("text-lg font-semibold leading-none tracking-tight text-card-foreground", className),
|
|
5030
5244
|
...props
|
|
5031
5245
|
}
|
|
5032
5246
|
));
|
|
5033
|
-
DialogTitle.displayName =
|
|
5034
|
-
var DialogDescription =
|
|
5035
|
-
|
|
5247
|
+
DialogTitle.displayName = import_radix_ui5.Dialog.Title.displayName;
|
|
5248
|
+
var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5249
|
+
import_radix_ui5.Dialog.Description,
|
|
5036
5250
|
{
|
|
5037
5251
|
ref,
|
|
5038
5252
|
className: cn("text-sm text-muted-foreground", className),
|
|
5039
5253
|
...props
|
|
5040
5254
|
}
|
|
5041
5255
|
));
|
|
5042
|
-
DialogDescription.displayName =
|
|
5043
|
-
var DialogClose =
|
|
5044
|
-
|
|
5045
|
-
// src/ui/button.tsx
|
|
5046
|
-
var React6 = __toESM(require("react"), 1);
|
|
5047
|
-
var import_radix_ui5 = require("radix-ui");
|
|
5048
|
-
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
5049
|
-
var buttonVariants = cva(
|
|
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",
|
|
5051
|
-
{
|
|
5052
|
-
variants: {
|
|
5053
|
-
variant: {
|
|
5054
|
-
default: "bg-primary text-primary-foreground hover:opacity-90",
|
|
5055
|
-
outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
|
|
5056
|
-
ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
|
|
5057
|
-
},
|
|
5058
|
-
size: {
|
|
5059
|
-
default: "h-9",
|
|
5060
|
-
sm: "h-8 min-w-[64px] px-2 py-1.5 text-sm"
|
|
5061
|
-
}
|
|
5062
|
-
},
|
|
5063
|
-
defaultVariants: {
|
|
5064
|
-
variant: "default",
|
|
5065
|
-
size: "default"
|
|
5066
|
-
}
|
|
5067
|
-
}
|
|
5068
|
-
);
|
|
5069
|
-
var Button = React6.forwardRef(
|
|
5070
|
-
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
5071
|
-
const Comp = asChild ? import_radix_ui5.Slot.Root : "button";
|
|
5072
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5073
|
-
Comp,
|
|
5074
|
-
{
|
|
5075
|
-
ref,
|
|
5076
|
-
"data-slot": "button",
|
|
5077
|
-
className: cn(buttonVariants({ variant, size, className })),
|
|
5078
|
-
...props
|
|
5079
|
-
}
|
|
5080
|
-
);
|
|
5081
|
-
}
|
|
5082
|
-
);
|
|
5083
|
-
Button.displayName = "Button";
|
|
5256
|
+
DialogDescription.displayName = import_radix_ui5.Dialog.Description.displayName;
|
|
5257
|
+
var DialogClose = import_radix_ui5.Dialog.Close;
|
|
5084
5258
|
|
|
5085
5259
|
// src/ui/link-modal/DestinationBreadcrumb.tsx
|
|
5086
|
-
var
|
|
5260
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
5087
5261
|
function DestinationBreadcrumb({ pageTitle, sectionLabel }) {
|
|
5088
|
-
return /* @__PURE__ */ (0,
|
|
5089
|
-
/* @__PURE__ */ (0,
|
|
5090
|
-
/* @__PURE__ */ (0,
|
|
5091
|
-
/* @__PURE__ */ (0,
|
|
5092
|
-
/* @__PURE__ */ (0,
|
|
5093
|
-
/* @__PURE__ */ (0,
|
|
5262
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
|
|
5263
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Destination" }),
|
|
5264
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
5265
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5266
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconFile, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5267
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-sm font-medium leading-none text-foreground", children: pageTitle })
|
|
5094
5268
|
] }),
|
|
5095
|
-
/* @__PURE__ */ (0,
|
|
5096
|
-
/* @__PURE__ */ (0,
|
|
5097
|
-
/* @__PURE__ */ (0,
|
|
5098
|
-
/* @__PURE__ */ (0,
|
|
5269
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconArrowRight, { className: "shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
5270
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
|
|
5271
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5272
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
|
|
5099
5273
|
] })
|
|
5100
5274
|
] })
|
|
5101
5275
|
] });
|
|
5102
5276
|
}
|
|
5103
5277
|
|
|
5104
5278
|
// src/ui/link-modal/SectionTreeItem.tsx
|
|
5105
|
-
var
|
|
5279
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
5106
5280
|
function SectionTreeItem({ section, onSelect, selected }) {
|
|
5107
5281
|
const interactive = Boolean(onSelect);
|
|
5108
|
-
return /* @__PURE__ */ (0,
|
|
5109
|
-
/* @__PURE__ */ (0,
|
|
5282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
|
|
5283
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
5110
5284
|
"div",
|
|
5111
5285
|
{
|
|
5112
5286
|
className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
5113
5287
|
"aria-hidden": true
|
|
5114
5288
|
}
|
|
5115
5289
|
),
|
|
5116
|
-
/* @__PURE__ */ (0,
|
|
5290
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
5117
5291
|
"div",
|
|
5118
5292
|
{
|
|
5119
5293
|
role: interactive ? "button" : void 0,
|
|
@@ -5131,8 +5305,8 @@ function SectionTreeItem({ section, onSelect, selected }) {
|
|
|
5131
5305
|
interactive && selected && "border-primary"
|
|
5132
5306
|
),
|
|
5133
5307
|
children: [
|
|
5134
|
-
/* @__PURE__ */ (0,
|
|
5135
|
-
/* @__PURE__ */ (0,
|
|
5308
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSection, { className: "shrink-0 text-foreground", "aria-hidden": true }),
|
|
5309
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
|
|
5136
5310
|
]
|
|
5137
5311
|
}
|
|
5138
5312
|
)
|
|
@@ -5140,11 +5314,11 @@ function SectionTreeItem({ section, onSelect, selected }) {
|
|
|
5140
5314
|
}
|
|
5141
5315
|
function SectionPickerList({ sections, onSelect }) {
|
|
5142
5316
|
if (sections.length === 0) {
|
|
5143
|
-
return /* @__PURE__ */ (0,
|
|
5317
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." });
|
|
5144
5318
|
}
|
|
5145
|
-
return /* @__PURE__ */ (0,
|
|
5146
|
-
/* @__PURE__ */ (0,
|
|
5147
|
-
sections.map((section) => /* @__PURE__ */ (0,
|
|
5319
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
5320
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm text-muted-foreground", children: "Pick a section this link should scroll to." }),
|
|
5321
|
+
sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(SectionTreeItem, { section, onSelect }, section.id))
|
|
5148
5322
|
] });
|
|
5149
5323
|
}
|
|
5150
5324
|
|
|
@@ -5152,11 +5326,11 @@ function SectionPickerList({ sections, onSelect }) {
|
|
|
5152
5326
|
var import_react4 = require("react");
|
|
5153
5327
|
|
|
5154
5328
|
// src/ui/input.tsx
|
|
5155
|
-
var
|
|
5156
|
-
var
|
|
5157
|
-
var Input =
|
|
5329
|
+
var React8 = __toESM(require("react"), 1);
|
|
5330
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
5331
|
+
var Input = React8.forwardRef(
|
|
5158
5332
|
({ className, type, ...props }, ref) => {
|
|
5159
|
-
return /* @__PURE__ */ (0,
|
|
5333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5160
5334
|
"input",
|
|
5161
5335
|
{
|
|
5162
5336
|
type,
|
|
@@ -5175,9 +5349,9 @@ Input.displayName = "Input";
|
|
|
5175
5349
|
|
|
5176
5350
|
// src/ui/label.tsx
|
|
5177
5351
|
var import_radix_ui6 = require("radix-ui");
|
|
5178
|
-
var
|
|
5352
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
5179
5353
|
function Label({ className, ...props }) {
|
|
5180
|
-
return /* @__PURE__ */ (0,
|
|
5354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
5181
5355
|
import_radix_ui6.Label.Root,
|
|
5182
5356
|
{
|
|
5183
5357
|
"data-slot": "label",
|
|
@@ -5188,9 +5362,9 @@ function Label({ className, ...props }) {
|
|
|
5188
5362
|
}
|
|
5189
5363
|
|
|
5190
5364
|
// src/ui/link-modal/UrlOrPageInput.tsx
|
|
5191
|
-
var
|
|
5365
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
5192
5366
|
function FieldChevron({ onClick }) {
|
|
5193
|
-
return /* @__PURE__ */ (0,
|
|
5367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5194
5368
|
"button",
|
|
5195
5369
|
{
|
|
5196
5370
|
type: "button",
|
|
@@ -5198,7 +5372,7 @@ function FieldChevron({ onClick }) {
|
|
|
5198
5372
|
onClick,
|
|
5199
5373
|
"aria-label": "Open page list",
|
|
5200
5374
|
tabIndex: -1,
|
|
5201
|
-
children: /* @__PURE__ */ (0,
|
|
5375
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconChevronDown, {})
|
|
5202
5376
|
}
|
|
5203
5377
|
);
|
|
5204
5378
|
}
|
|
@@ -5237,12 +5411,12 @@ function UrlOrPageInput({
|
|
|
5237
5411
|
"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]",
|
|
5238
5412
|
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
5239
5413
|
);
|
|
5240
|
-
return /* @__PURE__ */ (0,
|
|
5241
|
-
/* @__PURE__ */ (0,
|
|
5242
|
-
/* @__PURE__ */ (0,
|
|
5243
|
-
/* @__PURE__ */ (0,
|
|
5244
|
-
selectedPage ? /* @__PURE__ */ (0,
|
|
5245
|
-
readOnly ? /* @__PURE__ */ (0,
|
|
5414
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
5415
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
5416
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "relative w-full", children: [
|
|
5417
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
|
|
5418
|
+
selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconFile, { className: "text-foreground", "aria-hidden": true }) }) : null,
|
|
5419
|
+
readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5246
5420
|
Input,
|
|
5247
5421
|
{
|
|
5248
5422
|
ref: inputRef,
|
|
@@ -5261,7 +5435,7 @@ function UrlOrPageInput({
|
|
|
5261
5435
|
)
|
|
5262
5436
|
}
|
|
5263
5437
|
),
|
|
5264
|
-
selectedPage && !readOnly ? /* @__PURE__ */ (0,
|
|
5438
|
+
selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5265
5439
|
"button",
|
|
5266
5440
|
{
|
|
5267
5441
|
type: "button",
|
|
@@ -5269,26 +5443,26 @@ function UrlOrPageInput({
|
|
|
5269
5443
|
onMouseDown: clearSelection,
|
|
5270
5444
|
"aria-label": "Clear selected page",
|
|
5271
5445
|
tabIndex: -1,
|
|
5272
|
-
children: /* @__PURE__ */ (0,
|
|
5446
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconX, { "aria-hidden": true })
|
|
5273
5447
|
}
|
|
5274
5448
|
) : null,
|
|
5275
|
-
!readOnly ? /* @__PURE__ */ (0,
|
|
5449
|
+
!readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
|
|
5276
5450
|
] }),
|
|
5277
|
-
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0,
|
|
5451
|
+
dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5278
5452
|
"div",
|
|
5279
5453
|
{
|
|
5280
5454
|
"data-ohw-link-page-dropdown": "",
|
|
5281
5455
|
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",
|
|
5282
5456
|
onMouseDown: (e) => e.preventDefault(),
|
|
5283
|
-
children: filteredPages.map((page) => /* @__PURE__ */ (0,
|
|
5457
|
+
children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
5284
5458
|
"button",
|
|
5285
5459
|
{
|
|
5286
5460
|
type: "button",
|
|
5287
5461
|
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",
|
|
5288
5462
|
onClick: () => onPageSelect(page),
|
|
5289
5463
|
children: [
|
|
5290
|
-
/* @__PURE__ */ (0,
|
|
5291
|
-
/* @__PURE__ */ (0,
|
|
5464
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconFile, { className: "shrink-0", "aria-hidden": true }),
|
|
5465
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "truncate", children: page.title })
|
|
5292
5466
|
]
|
|
5293
5467
|
},
|
|
5294
5468
|
page.path
|
|
@@ -5296,7 +5470,7 @@ function UrlOrPageInput({
|
|
|
5296
5470
|
}
|
|
5297
5471
|
) : null
|
|
5298
5472
|
] }),
|
|
5299
|
-
urlError ? /* @__PURE__ */ (0,
|
|
5473
|
+
urlError ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
|
|
5300
5474
|
] });
|
|
5301
5475
|
}
|
|
5302
5476
|
|
|
@@ -5464,7 +5638,7 @@ function useLinkModalState({
|
|
|
5464
5638
|
}
|
|
5465
5639
|
|
|
5466
5640
|
// src/ui/link-modal/LinkEditorPanel.tsx
|
|
5467
|
-
var
|
|
5641
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5468
5642
|
function LinkEditorPanel({
|
|
5469
5643
|
open = true,
|
|
5470
5644
|
mode = "create",
|
|
@@ -5488,25 +5662,25 @@ function LinkEditorPanel({
|
|
|
5488
5662
|
onSubmit
|
|
5489
5663
|
});
|
|
5490
5664
|
const isCancel = state.secondaryLabel === "Cancel";
|
|
5491
|
-
return /* @__PURE__ */ (0,
|
|
5492
|
-
/* @__PURE__ */ (0,
|
|
5665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
|
|
5666
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5493
5667
|
"button",
|
|
5494
5668
|
{
|
|
5495
5669
|
type: "button",
|
|
5496
5670
|
className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
|
|
5497
5671
|
"aria-label": "Close",
|
|
5498
|
-
children: /* @__PURE__ */ (0,
|
|
5672
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconX, { "aria-hidden": true })
|
|
5499
5673
|
}
|
|
5500
5674
|
) }),
|
|
5501
|
-
/* @__PURE__ */ (0,
|
|
5502
|
-
/* @__PURE__ */ (0,
|
|
5503
|
-
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0,
|
|
5675
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
|
|
5676
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
|
|
5677
|
+
state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5504
5678
|
DestinationBreadcrumb,
|
|
5505
5679
|
{
|
|
5506
5680
|
pageTitle: state.selectedPage.title,
|
|
5507
5681
|
sectionLabel: state.selectedSection.label
|
|
5508
5682
|
}
|
|
5509
|
-
) : /* @__PURE__ */ (0,
|
|
5683
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5510
5684
|
UrlOrPageInput,
|
|
5511
5685
|
{
|
|
5512
5686
|
value: state.searchValue,
|
|
@@ -5519,18 +5693,18 @@ function LinkEditorPanel({
|
|
|
5519
5693
|
urlError: state.urlError
|
|
5520
5694
|
}
|
|
5521
5695
|
),
|
|
5522
|
-
state.showChooseSection ? /* @__PURE__ */ (0,
|
|
5523
|
-
/* @__PURE__ */ (0,
|
|
5524
|
-
/* @__PURE__ */ (0,
|
|
5525
|
-
/* @__PURE__ */ (0,
|
|
5526
|
-
/* @__PURE__ */ (0,
|
|
5696
|
+
state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
|
|
5697
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Button, { type: "button", variant: "outline", className: "w-fit cursor-pointer", size: "sm", onClick: state.handleChooseSection, children: "Choose a section" }),
|
|
5698
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
|
|
5699
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(IconInfo, { className: "shrink-0", "aria-hidden": true }),
|
|
5700
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: "Pick a section this link should scroll to." })
|
|
5527
5701
|
] })
|
|
5528
5702
|
] }) : null,
|
|
5529
|
-
state.showSectionPicker ? /* @__PURE__ */ (0,
|
|
5530
|
-
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0,
|
|
5703
|
+
state.showSectionPicker ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SectionPickerList, { sections: state.activeSections, onSelect: state.handleSectionSelect }) : null,
|
|
5704
|
+
state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
|
|
5531
5705
|
] }),
|
|
5532
|
-
/* @__PURE__ */ (0,
|
|
5533
|
-
/* @__PURE__ */ (0,
|
|
5706
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
|
|
5707
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5534
5708
|
Button,
|
|
5535
5709
|
{
|
|
5536
5710
|
type: "button",
|
|
@@ -5545,7 +5719,7 @@ function LinkEditorPanel({
|
|
|
5545
5719
|
children: state.secondaryLabel
|
|
5546
5720
|
}
|
|
5547
5721
|
),
|
|
5548
|
-
/* @__PURE__ */ (0,
|
|
5722
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
5549
5723
|
Button,
|
|
5550
5724
|
{
|
|
5551
5725
|
type: "button",
|
|
@@ -5564,7 +5738,7 @@ function LinkEditorPanel({
|
|
|
5564
5738
|
}
|
|
5565
5739
|
|
|
5566
5740
|
// src/ui/link-modal/LinkPopover.tsx
|
|
5567
|
-
var
|
|
5741
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
5568
5742
|
function LinkPopover({
|
|
5569
5743
|
open = true,
|
|
5570
5744
|
panelRef,
|
|
@@ -5572,14 +5746,14 @@ function LinkPopover({
|
|
|
5572
5746
|
onClose,
|
|
5573
5747
|
...editorProps
|
|
5574
5748
|
}) {
|
|
5575
|
-
return /* @__PURE__ */ (0,
|
|
5749
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5576
5750
|
Dialog2,
|
|
5577
5751
|
{
|
|
5578
5752
|
open,
|
|
5579
5753
|
onOpenChange: (next) => {
|
|
5580
5754
|
if (!next) onClose?.();
|
|
5581
5755
|
},
|
|
5582
|
-
children: /* @__PURE__ */ (0,
|
|
5756
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
5583
5757
|
DialogContent,
|
|
5584
5758
|
{
|
|
5585
5759
|
ref: panelRef,
|
|
@@ -5589,7 +5763,7 @@ function LinkPopover({
|
|
|
5589
5763
|
"data-ohw-bridge": "",
|
|
5590
5764
|
showCloseButton: false,
|
|
5591
5765
|
className: "gap-0 p-0 w-full md:w-md pointer-events-auto",
|
|
5592
|
-
children: /* @__PURE__ */ (0,
|
|
5766
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LinkEditorPanel, { ...editorProps, open, onClose })
|
|
5593
5767
|
}
|
|
5594
5768
|
)
|
|
5595
5769
|
}
|
|
@@ -5655,7 +5829,7 @@ function shouldUseDevFixtures() {
|
|
|
5655
5829
|
}
|
|
5656
5830
|
|
|
5657
5831
|
// src/ui/badge.tsx
|
|
5658
|
-
var
|
|
5832
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
5659
5833
|
var badgeVariants = cva(
|
|
5660
5834
|
"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",
|
|
5661
5835
|
{
|
|
@@ -5673,12 +5847,12 @@ var badgeVariants = cva(
|
|
|
5673
5847
|
}
|
|
5674
5848
|
);
|
|
5675
5849
|
function Badge({ className, variant, ...props }) {
|
|
5676
|
-
return /* @__PURE__ */ (0,
|
|
5850
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
5677
5851
|
}
|
|
5678
5852
|
|
|
5679
5853
|
// src/OhhwellsBridge.tsx
|
|
5680
|
-
var
|
|
5681
|
-
var
|
|
5854
|
+
var import_lucide_react4 = require("lucide-react");
|
|
5855
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
5682
5856
|
var PRIMARY2 = "#0885FE";
|
|
5683
5857
|
var IMAGE_FADE_MS = 300;
|
|
5684
5858
|
function runOpacityFade(el, onDone) {
|
|
@@ -5852,7 +6026,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
5852
6026
|
const root = (0, import_client.createRoot)(container);
|
|
5853
6027
|
(0, import_react_dom.flushSync)(() => {
|
|
5854
6028
|
root.render(
|
|
5855
|
-
/* @__PURE__ */ (0,
|
|
6029
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
5856
6030
|
SchedulingWidget,
|
|
5857
6031
|
{
|
|
5858
6032
|
notifyOnConnect,
|
|
@@ -5925,6 +6099,9 @@ function collectEditableNodes() {
|
|
|
5925
6099
|
const url = raw.replace(/^url\(['"]?/, "").replace(/['"]?\)$/, "");
|
|
5926
6100
|
return { key: el.dataset.ohwKey ?? "", type: "bg-image", text: url };
|
|
5927
6101
|
}
|
|
6102
|
+
if (el.dataset.ohwEditable === "video") {
|
|
6103
|
+
return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
|
|
6104
|
+
}
|
|
5928
6105
|
if (el.dataset.ohwEditable === "link") {
|
|
5929
6106
|
return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref(el) };
|
|
5930
6107
|
}
|
|
@@ -5939,8 +6116,62 @@ function collectEditableNodes() {
|
|
|
5939
6116
|
if (!key) return;
|
|
5940
6117
|
nodes.push({ key, type: "link", text: getLinkHref(el) });
|
|
5941
6118
|
});
|
|
6119
|
+
document.querySelectorAll('[data-ohw-editable="video"]').forEach((el) => {
|
|
6120
|
+
const key = el.dataset.ohwKey ?? "";
|
|
6121
|
+
const video = getVideoEl(el);
|
|
6122
|
+
if (!key || !video) return;
|
|
6123
|
+
nodes.push({ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, type: "video-setting", text: String(video.autoplay) });
|
|
6124
|
+
nodes.push({ key: `${key}${VIDEO_MUTED_SUFFIX}`, type: "video-setting", text: String(video.muted) });
|
|
6125
|
+
});
|
|
5942
6126
|
return nodes;
|
|
5943
6127
|
}
|
|
6128
|
+
function isMediaEditable(el) {
|
|
6129
|
+
const t = el.dataset.ohwEditable;
|
|
6130
|
+
return t === "image" || t === "bg-image" || t === "video";
|
|
6131
|
+
}
|
|
6132
|
+
var MEDIA_SELECTOR = '[data-ohw-editable="image"], [data-ohw-editable="bg-image"], [data-ohw-editable="video"]';
|
|
6133
|
+
var NON_MEDIA_SELECTOR = '[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"])';
|
|
6134
|
+
function getVideoEl(el) {
|
|
6135
|
+
return el instanceof HTMLVideoElement ? el : el.querySelector("video");
|
|
6136
|
+
}
|
|
6137
|
+
var VIDEO_AUTOPLAY_SUFFIX = "__ohw_autoplay";
|
|
6138
|
+
var VIDEO_MUTED_SUFFIX = "__ohw_muted";
|
|
6139
|
+
function isBackgroundVideo(video) {
|
|
6140
|
+
return video.autoplay && video.muted;
|
|
6141
|
+
}
|
|
6142
|
+
function syncVideoPlayback(video) {
|
|
6143
|
+
const background = isBackgroundVideo(video);
|
|
6144
|
+
video.controls = !background;
|
|
6145
|
+
if (video.autoplay) void video.play().catch(() => {
|
|
6146
|
+
});
|
|
6147
|
+
else video.pause();
|
|
6148
|
+
}
|
|
6149
|
+
function applyVideoSrc(video, url) {
|
|
6150
|
+
const { autoplay, muted } = video;
|
|
6151
|
+
video.src = url;
|
|
6152
|
+
video.loop = true;
|
|
6153
|
+
video.playsInline = true;
|
|
6154
|
+
video.autoplay = autoplay;
|
|
6155
|
+
video.muted = muted;
|
|
6156
|
+
video.load();
|
|
6157
|
+
syncVideoPlayback(video);
|
|
6158
|
+
}
|
|
6159
|
+
function applyVideoSettingNode(key, val) {
|
|
6160
|
+
const isAutoplay = key.endsWith(VIDEO_AUTOPLAY_SUFFIX);
|
|
6161
|
+
const isMuted = key.endsWith(VIDEO_MUTED_SUFFIX);
|
|
6162
|
+
if (!isAutoplay && !isMuted) return false;
|
|
6163
|
+
const suffixLen = (isAutoplay ? VIDEO_AUTOPLAY_SUFFIX : VIDEO_MUTED_SUFFIX).length;
|
|
6164
|
+
const baseKey = key.slice(0, key.length - suffixLen);
|
|
6165
|
+
const on = val === "true";
|
|
6166
|
+
document.querySelectorAll(`[data-ohw-key="${baseKey}"]`).forEach((el) => {
|
|
6167
|
+
const video = getVideoEl(el);
|
|
6168
|
+
if (!video) return;
|
|
6169
|
+
if (isAutoplay) video.autoplay = on;
|
|
6170
|
+
else video.muted = on;
|
|
6171
|
+
syncVideoPlayback(video);
|
|
6172
|
+
});
|
|
6173
|
+
return true;
|
|
6174
|
+
}
|
|
5944
6175
|
function applyLinkByKey(key, val) {
|
|
5945
6176
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
5946
6177
|
if (el.dataset.ohwEditable === "link") applyLinkHref(el, val);
|
|
@@ -6240,7 +6471,7 @@ function EditGlowChrome({
|
|
|
6240
6471
|
dragDisabled = false
|
|
6241
6472
|
}) {
|
|
6242
6473
|
const GAP = 6;
|
|
6243
|
-
return /* @__PURE__ */ (0,
|
|
6474
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
6244
6475
|
"div",
|
|
6245
6476
|
{
|
|
6246
6477
|
ref: elRef,
|
|
@@ -6255,7 +6486,7 @@ function EditGlowChrome({
|
|
|
6255
6486
|
zIndex: 2147483646
|
|
6256
6487
|
},
|
|
6257
6488
|
children: [
|
|
6258
|
-
/* @__PURE__ */ (0,
|
|
6489
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6259
6490
|
"div",
|
|
6260
6491
|
{
|
|
6261
6492
|
style: {
|
|
@@ -6268,7 +6499,7 @@ function EditGlowChrome({
|
|
|
6268
6499
|
}
|
|
6269
6500
|
}
|
|
6270
6501
|
),
|
|
6271
|
-
reorderHrefKey && /* @__PURE__ */ (0,
|
|
6502
|
+
reorderHrefKey && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6272
6503
|
"div",
|
|
6273
6504
|
{
|
|
6274
6505
|
"data-ohw-drag-handle-container": "",
|
|
@@ -6280,7 +6511,7 @@ function EditGlowChrome({
|
|
|
6280
6511
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
6281
6512
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
6282
6513
|
},
|
|
6283
|
-
children: /* @__PURE__ */ (0,
|
|
6514
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6284
6515
|
DragHandle,
|
|
6285
6516
|
{
|
|
6286
6517
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -6384,7 +6615,7 @@ function FloatingToolbar({
|
|
|
6384
6615
|
onEditLink
|
|
6385
6616
|
}) {
|
|
6386
6617
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, 330);
|
|
6387
|
-
return /* @__PURE__ */ (0,
|
|
6618
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6388
6619
|
"div",
|
|
6389
6620
|
{
|
|
6390
6621
|
ref: elRef,
|
|
@@ -6405,12 +6636,12 @@ function FloatingToolbar({
|
|
|
6405
6636
|
fontFamily: "sans-serif",
|
|
6406
6637
|
pointerEvents: "auto"
|
|
6407
6638
|
},
|
|
6408
|
-
children: /* @__PURE__ */ (0,
|
|
6409
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
6410
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
6639
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(CustomToolbar, { children: [
|
|
6640
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react6.default.Fragment, { children: [
|
|
6641
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CustomToolbarDivider, {}),
|
|
6411
6642
|
btns.map((btn) => {
|
|
6412
6643
|
const isActive = activeCommands.has(btn.cmd);
|
|
6413
|
-
return /* @__PURE__ */ (0,
|
|
6644
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6414
6645
|
CustomToolbarButton,
|
|
6415
6646
|
{
|
|
6416
6647
|
title: btn.title,
|
|
@@ -6419,7 +6650,7 @@ function FloatingToolbar({
|
|
|
6419
6650
|
e.preventDefault();
|
|
6420
6651
|
onCommand(btn.cmd);
|
|
6421
6652
|
},
|
|
6422
|
-
children: /* @__PURE__ */ (0,
|
|
6653
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6423
6654
|
"svg",
|
|
6424
6655
|
{
|
|
6425
6656
|
width: "16",
|
|
@@ -6440,7 +6671,7 @@ function FloatingToolbar({
|
|
|
6440
6671
|
);
|
|
6441
6672
|
})
|
|
6442
6673
|
] }, gi)),
|
|
6443
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
6674
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6444
6675
|
CustomToolbarButton,
|
|
6445
6676
|
{
|
|
6446
6677
|
type: "button",
|
|
@@ -6454,7 +6685,7 @@ function FloatingToolbar({
|
|
|
6454
6685
|
e.preventDefault();
|
|
6455
6686
|
e.stopPropagation();
|
|
6456
6687
|
},
|
|
6457
|
-
children: /* @__PURE__ */ (0,
|
|
6688
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react4.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
6458
6689
|
}
|
|
6459
6690
|
) : null
|
|
6460
6691
|
] })
|
|
@@ -6471,7 +6702,7 @@ function StateToggle({
|
|
|
6471
6702
|
states,
|
|
6472
6703
|
onStateChange
|
|
6473
6704
|
}) {
|
|
6474
|
-
return /* @__PURE__ */ (0,
|
|
6705
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
6475
6706
|
ToggleGroup,
|
|
6476
6707
|
{
|
|
6477
6708
|
"data-ohw-state-toggle": "",
|
|
@@ -6485,7 +6716,7 @@ function StateToggle({
|
|
|
6485
6716
|
left: rect.right - 8,
|
|
6486
6717
|
transform: "translateX(-100%)"
|
|
6487
6718
|
},
|
|
6488
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
6719
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
6489
6720
|
}
|
|
6490
6721
|
);
|
|
6491
6722
|
}
|
|
@@ -6521,7 +6752,10 @@ function OhhwellsBridge() {
|
|
|
6521
6752
|
const stylesheet = Object.assign(document.createElement("link"), {
|
|
6522
6753
|
id: figtreeFontId,
|
|
6523
6754
|
rel: "stylesheet",
|
|
6524
|
-
|
|
6755
|
+
// Inter is loaded alongside Figtree for the media overlay's Replace button. The bridge
|
|
6756
|
+
// renders inside the customer's document, so it cannot assume any font is present — an
|
|
6757
|
+
// unloaded family would silently fall back to whatever the template happens to use.
|
|
6758
|
+
href: "https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&family=Inter:wght@400;500;600&display=swap"
|
|
6525
6759
|
});
|
|
6526
6760
|
document.head.append(preconnect1, preconnect2, stylesheet);
|
|
6527
6761
|
}
|
|
@@ -6561,6 +6795,8 @@ function OhhwellsBridge() {
|
|
|
6561
6795
|
const glowElRef = (0, import_react6.useRef)(null);
|
|
6562
6796
|
const hoveredImageRef = (0, import_react6.useRef)(null);
|
|
6563
6797
|
const hoveredImageHasTextOverlapRef = (0, import_react6.useRef)(false);
|
|
6798
|
+
const [mediaHover, setMediaHover] = (0, import_react6.useState)(null);
|
|
6799
|
+
const [uploadingRects, setUploadingRects] = (0, import_react6.useState)({});
|
|
6564
6800
|
const hoveredGapRef = (0, import_react6.useRef)(null);
|
|
6565
6801
|
const imageUnhoverTimerRef = (0, import_react6.useRef)(null);
|
|
6566
6802
|
const imageShowTimerRef = (0, import_react6.useRef)(null);
|
|
@@ -6642,7 +6878,7 @@ function OhhwellsBridge() {
|
|
|
6642
6878
|
}
|
|
6643
6879
|
hoveredGapRef.current = null;
|
|
6644
6880
|
setSectionGap(null);
|
|
6645
|
-
|
|
6881
|
+
setMediaHover(null);
|
|
6646
6882
|
postToParent({ type: "ow:link-modal-lock", locked: true });
|
|
6647
6883
|
const html = document.documentElement;
|
|
6648
6884
|
const body = document.body;
|
|
@@ -6886,7 +7122,7 @@ function OhhwellsBridge() {
|
|
|
6886
7122
|
deactivate();
|
|
6887
7123
|
if (hoveredImageRef.current) {
|
|
6888
7124
|
hoveredImageRef.current = null;
|
|
6889
|
-
|
|
7125
|
+
setMediaHover(null);
|
|
6890
7126
|
}
|
|
6891
7127
|
setToolbarVariant("rich-text");
|
|
6892
7128
|
siblingHintElRef.current = null;
|
|
@@ -6929,6 +7165,7 @@ function OhhwellsBridge() {
|
|
|
6929
7165
|
const imageLoads = [];
|
|
6930
7166
|
for (const [key, val] of Object.entries(content)) {
|
|
6931
7167
|
if (key === "__ohw_sections") continue;
|
|
7168
|
+
if (applyVideoSettingNode(key, val)) continue;
|
|
6932
7169
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
6933
7170
|
if (el.dataset.ohwEditable === "image") {
|
|
6934
7171
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -6942,6 +7179,15 @@ function OhhwellsBridge() {
|
|
|
6942
7179
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
6943
7180
|
const next = `url('${val}')`;
|
|
6944
7181
|
if (el.style.backgroundImage !== next) el.style.backgroundImage = next;
|
|
7182
|
+
} else if (el.dataset.ohwEditable === "video") {
|
|
7183
|
+
const video = getVideoEl(el);
|
|
7184
|
+
if (video && video.src !== val) {
|
|
7185
|
+
applyVideoSrc(video, val);
|
|
7186
|
+
imageLoads.push(new Promise((resolve) => {
|
|
7187
|
+
video.onloadeddata = () => resolve();
|
|
7188
|
+
video.onerror = () => resolve();
|
|
7189
|
+
}));
|
|
7190
|
+
}
|
|
6945
7191
|
} else if (el.dataset.ohwEditable === "link") {
|
|
6946
7192
|
applyLinkHref(el, val);
|
|
6947
7193
|
} else if (el.innerHTML !== val) {
|
|
@@ -6990,6 +7236,7 @@ function OhhwellsBridge() {
|
|
|
6990
7236
|
try {
|
|
6991
7237
|
for (const [key, val] of Object.entries(content)) {
|
|
6992
7238
|
if (key === "__ohw_sections") continue;
|
|
7239
|
+
if (applyVideoSettingNode(key, val)) continue;
|
|
6993
7240
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
6994
7241
|
if (el.dataset.ohwEditable === "image") {
|
|
6995
7242
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
@@ -6997,6 +7244,9 @@ function OhhwellsBridge() {
|
|
|
6997
7244
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
6998
7245
|
const next = `url('${val}')`;
|
|
6999
7246
|
if (el.style.backgroundImage !== next) el.style.backgroundImage = next;
|
|
7247
|
+
} else if (el.dataset.ohwEditable === "video") {
|
|
7248
|
+
const video = getVideoEl(el);
|
|
7249
|
+
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
7000
7250
|
} else if (el.dataset.ohwEditable === "link") {
|
|
7001
7251
|
applyLinkHref(el, val);
|
|
7002
7252
|
} else if (el.innerHTML !== val) {
|
|
@@ -7100,8 +7350,9 @@ function OhhwellsBridge() {
|
|
|
7100
7350
|
[data-ohw-editable] {
|
|
7101
7351
|
display: block;
|
|
7102
7352
|
}
|
|
7103
|
-
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]) { cursor: text !important; }
|
|
7353
|
+
[data-ohw-editable]:not([contenteditable]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]) { cursor: text !important; }
|
|
7104
7354
|
[data-ohw-editable="image"], [data-ohw-editable="image"] *,
|
|
7355
|
+
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
7105
7356
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
7106
7357
|
[data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
|
|
7107
7358
|
[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
|
|
@@ -7168,10 +7419,10 @@ function OhhwellsBridge() {
|
|
|
7168
7419
|
});
|
|
7169
7420
|
return;
|
|
7170
7421
|
}
|
|
7171
|
-
if (editable
|
|
7422
|
+
if (isMediaEditable(editable)) {
|
|
7172
7423
|
e.preventDefault();
|
|
7173
7424
|
e.stopPropagation();
|
|
7174
|
-
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "" });
|
|
7425
|
+
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "", elementType: editable.dataset.ohwEditable ?? "image" });
|
|
7175
7426
|
return;
|
|
7176
7427
|
}
|
|
7177
7428
|
const hrefCtx = getHrefKeyFromElement(editable);
|
|
@@ -7271,7 +7522,7 @@ function OhhwellsBridge() {
|
|
|
7271
7522
|
if (!editable) return;
|
|
7272
7523
|
const selected = selectedElRef.current;
|
|
7273
7524
|
if (selected && (selected === editable || selected.contains(editable))) return;
|
|
7274
|
-
if (editable
|
|
7525
|
+
if (!isMediaEditable(editable) && !editable.hasAttribute("contenteditable")) {
|
|
7275
7526
|
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
7276
7527
|
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
7277
7528
|
clearHrefKeyHover(hoverTarget);
|
|
@@ -7299,7 +7550,7 @@ function OhhwellsBridge() {
|
|
|
7299
7550
|
if (!editable) return;
|
|
7300
7551
|
const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
7301
7552
|
if (related?.closest("[data-ohw-drag-handle-container], [data-ohw-item-interaction]")) return;
|
|
7302
|
-
if (editable
|
|
7553
|
+
if (!isMediaEditable(editable)) {
|
|
7303
7554
|
const hoverTarget = editable.closest("[data-ohw-href-key]") ?? editable;
|
|
7304
7555
|
if (hoverTarget.hasAttribute("data-ohw-href-key")) {
|
|
7305
7556
|
if (!related?.closest("[data-ohw-href-key]")) {
|
|
@@ -7345,23 +7596,26 @@ function OhhwellsBridge() {
|
|
|
7345
7596
|
}
|
|
7346
7597
|
return { top, left, width: Math.max(0, right - left), height: Math.max(0, bottom - top) };
|
|
7347
7598
|
};
|
|
7348
|
-
const
|
|
7599
|
+
const showImageHover = (imgEl, isDragOver = false, forceTextOverlap) => {
|
|
7349
7600
|
const r2 = getVisibleRect(imgEl);
|
|
7350
7601
|
const hasTextOverlap = forceTextOverlap ?? false;
|
|
7351
7602
|
hoveredImageHasTextOverlapRef.current = hasTextOverlap;
|
|
7352
|
-
|
|
7353
|
-
|
|
7603
|
+
const video = imgEl.dataset.ohwEditable === "video" ? getVideoEl(imgEl) : null;
|
|
7604
|
+
setMediaHover({
|
|
7354
7605
|
key: imgEl.dataset.ohwKey ?? "",
|
|
7355
7606
|
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
7607
|
+
elementType: imgEl.dataset.ohwEditable ?? "image",
|
|
7356
7608
|
hasTextOverlap,
|
|
7357
|
-
|
|
7609
|
+
isDragOver,
|
|
7610
|
+
...video ? { videoAutoplay: video.autoplay, videoMuted: video.muted } : {}
|
|
7358
7611
|
});
|
|
7359
7612
|
const track = imgEl.closest("[data-ohw-hover-pause]");
|
|
7360
7613
|
if (track) track.setAttribute("data-ohw-hover-paused", "");
|
|
7361
7614
|
};
|
|
7615
|
+
const clearImageHover = () => setMediaHover(null);
|
|
7362
7616
|
const findImageAtPoint = (clientX, clientY, fromParentViewport) => {
|
|
7363
7617
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7364
|
-
const images = Array.from(document.querySelectorAll(
|
|
7618
|
+
const images = Array.from(document.querySelectorAll(MEDIA_SELECTOR));
|
|
7365
7619
|
const matches = [];
|
|
7366
7620
|
for (let i = images.length - 1; i >= 0; i--) {
|
|
7367
7621
|
const el = images[i];
|
|
@@ -7377,7 +7631,9 @@ function OhhwellsBridge() {
|
|
|
7377
7631
|
if (x >= r2.left && x <= r2.left + r2.width && y >= r2.top && y <= r2.top + r2.height) matches.push(el);
|
|
7378
7632
|
}
|
|
7379
7633
|
if (matches.length === 0) return null;
|
|
7380
|
-
const imageTypeMatches = matches.filter(
|
|
7634
|
+
const imageTypeMatches = matches.filter(
|
|
7635
|
+
(el) => el.dataset.ohwEditable === "image" || el.dataset.ohwEditable === "video"
|
|
7636
|
+
);
|
|
7381
7637
|
const candidatePool = imageTypeMatches.length > 0 ? imageTypeMatches : matches;
|
|
7382
7638
|
const smallest = candidatePool.reduce((best, el) => {
|
|
7383
7639
|
const br = getVisibleRect(best);
|
|
@@ -7406,7 +7662,7 @@ function OhhwellsBridge() {
|
|
|
7406
7662
|
hoveredImageRef.current = null;
|
|
7407
7663
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7408
7664
|
resumeAnimTracks();
|
|
7409
|
-
|
|
7665
|
+
clearImageHover();
|
|
7410
7666
|
}
|
|
7411
7667
|
return;
|
|
7412
7668
|
}
|
|
@@ -7418,21 +7674,22 @@ function OhhwellsBridge() {
|
|
|
7418
7674
|
if (hoveredImageRef.current) {
|
|
7419
7675
|
hoveredImageRef.current = null;
|
|
7420
7676
|
resumeAnimTracks();
|
|
7421
|
-
|
|
7677
|
+
clearImageHover();
|
|
7422
7678
|
}
|
|
7423
7679
|
return;
|
|
7424
7680
|
}
|
|
7425
7681
|
}
|
|
7426
|
-
|
|
7682
|
+
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
7683
|
+
const activeEl = activeElRef.current;
|
|
7684
|
+
if (activeEl && (!imgEl || imgEl.contains(activeEl))) {
|
|
7427
7685
|
if (hoveredImageRef.current) {
|
|
7428
7686
|
hoveredImageRef.current = null;
|
|
7429
7687
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7430
7688
|
resumeAnimTracks();
|
|
7431
|
-
|
|
7689
|
+
clearImageHover();
|
|
7432
7690
|
}
|
|
7433
7691
|
return;
|
|
7434
7692
|
}
|
|
7435
|
-
const imgEl = findImageAtPoint(clientX, clientY, fromParentViewport);
|
|
7436
7693
|
if (imgEl) {
|
|
7437
7694
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7438
7695
|
const topEl = document.elementFromPoint(x, y);
|
|
@@ -7440,7 +7697,7 @@ function OhhwellsBridge() {
|
|
|
7440
7697
|
if (hoveredImageRef.current) {
|
|
7441
7698
|
hoveredImageRef.current = null;
|
|
7442
7699
|
resumeAnimTracks();
|
|
7443
|
-
|
|
7700
|
+
clearImageHover();
|
|
7444
7701
|
}
|
|
7445
7702
|
return;
|
|
7446
7703
|
}
|
|
@@ -7449,13 +7706,13 @@ function OhhwellsBridge() {
|
|
|
7449
7706
|
hoveredImageRef.current = null;
|
|
7450
7707
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7451
7708
|
resumeAnimTracks();
|
|
7452
|
-
|
|
7709
|
+
clearImageHover();
|
|
7453
7710
|
}
|
|
7454
7711
|
return;
|
|
7455
7712
|
}
|
|
7456
7713
|
const isStateCardImage = !!imgEl.closest("[data-ohw-editable-state]");
|
|
7457
7714
|
const textEditable = Array.from(
|
|
7458
|
-
document.querySelectorAll(
|
|
7715
|
+
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7459
7716
|
).find((el) => {
|
|
7460
7717
|
const er = el.getBoundingClientRect();
|
|
7461
7718
|
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
@@ -7474,14 +7731,14 @@ function OhhwellsBridge() {
|
|
|
7474
7731
|
hoveredImageRef.current = null;
|
|
7475
7732
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7476
7733
|
resumeAnimTracks();
|
|
7477
|
-
|
|
7734
|
+
clearImageHover();
|
|
7478
7735
|
}
|
|
7479
7736
|
return;
|
|
7480
7737
|
}
|
|
7481
7738
|
if (isStateCardImage) {
|
|
7482
7739
|
if (imgEl !== hoveredImageRef.current || !hoveredImageHasTextOverlapRef.current) {
|
|
7483
7740
|
hoveredImageRef.current = imgEl;
|
|
7484
|
-
|
|
7741
|
+
showImageHover(imgEl, isDragOver, true);
|
|
7485
7742
|
}
|
|
7486
7743
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7487
7744
|
if (textEditable && !isInsideNavigationItem(textEditable)) {
|
|
@@ -7493,7 +7750,7 @@ function OhhwellsBridge() {
|
|
|
7493
7750
|
hoveredImageRef.current = null;
|
|
7494
7751
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7495
7752
|
resumeAnimTracks();
|
|
7496
|
-
|
|
7753
|
+
clearImageHover();
|
|
7497
7754
|
}
|
|
7498
7755
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7499
7756
|
if (textEditable && !isInsideNavigationItem(textEditable)) {
|
|
@@ -7505,7 +7762,7 @@ function OhhwellsBridge() {
|
|
|
7505
7762
|
if (hoveredImageRef.current) {
|
|
7506
7763
|
hoveredImageRef.current = null;
|
|
7507
7764
|
resumeAnimTracks();
|
|
7508
|
-
|
|
7765
|
+
clearImageHover();
|
|
7509
7766
|
}
|
|
7510
7767
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7511
7768
|
return;
|
|
@@ -7513,9 +7770,9 @@ function OhhwellsBridge() {
|
|
|
7513
7770
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
7514
7771
|
if (imgEl !== hoveredImageRef.current || hoveredImageHasTextOverlapRef.current) {
|
|
7515
7772
|
hoveredImageRef.current = imgEl;
|
|
7516
|
-
|
|
7773
|
+
showImageHover(imgEl, isDragOver);
|
|
7517
7774
|
} else if (isDragOver) {
|
|
7518
|
-
|
|
7775
|
+
showImageHover(imgEl, true);
|
|
7519
7776
|
}
|
|
7520
7777
|
} else {
|
|
7521
7778
|
const inIframeView = clientX >= 0 && clientY >= 0 && clientX <= window.innerWidth && clientY <= window.innerHeight;
|
|
@@ -7532,11 +7789,11 @@ function OhhwellsBridge() {
|
|
|
7532
7789
|
hoveredImageRef.current = null;
|
|
7533
7790
|
hoveredImageHasTextOverlapRef.current = false;
|
|
7534
7791
|
resumeAnimTracks();
|
|
7535
|
-
|
|
7792
|
+
clearImageHover();
|
|
7536
7793
|
}
|
|
7537
7794
|
const { x, y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
7538
7795
|
const textEl = Array.from(
|
|
7539
|
-
document.querySelectorAll(
|
|
7796
|
+
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
7540
7797
|
).find((el) => {
|
|
7541
7798
|
const er = el.getBoundingClientRect();
|
|
7542
7799
|
return x >= er.left && x <= er.right && y >= er.top && y <= er.bottom;
|
|
@@ -7645,7 +7902,7 @@ function OhhwellsBridge() {
|
|
|
7645
7902
|
if (hoveredImageRef.current !== el) {
|
|
7646
7903
|
hoveredImageRef.current = el;
|
|
7647
7904
|
const isStateCard = !!el.closest("[data-ohw-editable-state]");
|
|
7648
|
-
|
|
7905
|
+
showImageHover(el, true, isStateCard ? true : void 0);
|
|
7649
7906
|
}
|
|
7650
7907
|
};
|
|
7651
7908
|
const handleDragLeave = (e) => {
|
|
@@ -7653,7 +7910,7 @@ function OhhwellsBridge() {
|
|
|
7653
7910
|
if (imgEl) return;
|
|
7654
7911
|
hoveredImageRef.current = null;
|
|
7655
7912
|
resumeAnimTracks();
|
|
7656
|
-
|
|
7913
|
+
clearImageHover();
|
|
7657
7914
|
};
|
|
7658
7915
|
const handleDrop = (e) => {
|
|
7659
7916
|
e.preventDefault();
|
|
@@ -7661,7 +7918,9 @@ function OhhwellsBridge() {
|
|
|
7661
7918
|
if (!el) return;
|
|
7662
7919
|
const file = e.dataTransfer?.files?.[0];
|
|
7663
7920
|
if (file) {
|
|
7664
|
-
|
|
7921
|
+
const wantsVideo = el.dataset.ohwEditable === "video";
|
|
7922
|
+
const accepted = wantsVideo ? file.type.startsWith("video/") : file.type.startsWith("image/");
|
|
7923
|
+
if (accepted) {
|
|
7665
7924
|
const key = el.dataset.ohwKey ?? "";
|
|
7666
7925
|
const { name, type: mimeType } = file;
|
|
7667
7926
|
const r2 = el.getBoundingClientRect();
|
|
@@ -7675,7 +7934,7 @@ function OhhwellsBridge() {
|
|
|
7675
7934
|
}
|
|
7676
7935
|
hoveredImageRef.current = null;
|
|
7677
7936
|
resumeAnimTracks();
|
|
7678
|
-
|
|
7937
|
+
clearImageHover();
|
|
7679
7938
|
};
|
|
7680
7939
|
const handleImageUrl = (e) => {
|
|
7681
7940
|
if (e.data?.type !== "ow:image-url") return;
|
|
@@ -7693,7 +7952,11 @@ function OhhwellsBridge() {
|
|
|
7693
7952
|
}
|
|
7694
7953
|
});
|
|
7695
7954
|
hoveredImageRef.current = null;
|
|
7696
|
-
|
|
7955
|
+
setUploadingRects((prev) => {
|
|
7956
|
+
const entry = prev[key];
|
|
7957
|
+
if (!entry || entry.fadingOut) return prev;
|
|
7958
|
+
return { ...prev, [key]: { ...entry, fadingOut: true } };
|
|
7959
|
+
});
|
|
7697
7960
|
};
|
|
7698
7961
|
let found = false;
|
|
7699
7962
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -7728,6 +7991,19 @@ function OhhwellsBridge() {
|
|
|
7728
7991
|
requestAnimationFrame(() => onReady());
|
|
7729
7992
|
}
|
|
7730
7993
|
}
|
|
7994
|
+
} else if (el.dataset.ohwEditable === "video") {
|
|
7995
|
+
const video = getVideoEl(el);
|
|
7996
|
+
if (video) {
|
|
7997
|
+
found = true;
|
|
7998
|
+
const onReady = () => {
|
|
7999
|
+
video.onloadeddata = null;
|
|
8000
|
+
video.onerror = null;
|
|
8001
|
+
notify();
|
|
8002
|
+
};
|
|
8003
|
+
video.onloadeddata = onReady;
|
|
8004
|
+
video.onerror = onReady;
|
|
8005
|
+
applyVideoSrc(video, url);
|
|
8006
|
+
}
|
|
7731
8007
|
}
|
|
7732
8008
|
});
|
|
7733
8009
|
if (!found) notify();
|
|
@@ -7794,12 +8070,16 @@ function OhhwellsBridge() {
|
|
|
7794
8070
|
sectionsJson = val;
|
|
7795
8071
|
continue;
|
|
7796
8072
|
}
|
|
8073
|
+
if (applyVideoSettingNode(key, val)) continue;
|
|
7797
8074
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
7798
8075
|
if (el.dataset.ohwEditable === "image") {
|
|
7799
8076
|
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
7800
8077
|
if (img) img.src = val;
|
|
7801
8078
|
} else if (el.dataset.ohwEditable === "bg-image") {
|
|
7802
8079
|
el.style.backgroundImage = `url('${val}')`;
|
|
8080
|
+
} else if (el.dataset.ohwEditable === "video") {
|
|
8081
|
+
const video = getVideoEl(el);
|
|
8082
|
+
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
7803
8083
|
} else if (el.dataset.ohwEditable === "link") {
|
|
7804
8084
|
applyLinkHref(el, val);
|
|
7805
8085
|
} else {
|
|
@@ -7912,12 +8192,9 @@ function OhhwellsBridge() {
|
|
|
7912
8192
|
if (hoveredImageRef.current) {
|
|
7913
8193
|
const el = hoveredImageRef.current;
|
|
7914
8194
|
const r2 = el.getBoundingClientRect();
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
7919
|
-
hasTextOverlap: hoveredImageHasTextOverlapRef.current
|
|
7920
|
-
});
|
|
8195
|
+
setMediaHover(
|
|
8196
|
+
(prev) => prev ? { ...prev, rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } } : prev
|
|
8197
|
+
);
|
|
7921
8198
|
}
|
|
7922
8199
|
};
|
|
7923
8200
|
const handleSave = (e) => {
|
|
@@ -8006,19 +8283,39 @@ function OhhwellsBridge() {
|
|
|
8006
8283
|
refreshActiveCommandsRef.current = handleSelectionChange;
|
|
8007
8284
|
const handleDocMouseLeave = () => {
|
|
8008
8285
|
hoveredImageRef.current = null;
|
|
8286
|
+
setMediaHover(null);
|
|
8009
8287
|
document.querySelectorAll("[data-ohw-state-hovered]").forEach((el) => el.removeAttribute("data-ohw-state-hovered"));
|
|
8010
8288
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
8011
8289
|
activeStateElRef.current = null;
|
|
8012
8290
|
setToggleState(null);
|
|
8013
8291
|
};
|
|
8014
|
-
const
|
|
8015
|
-
if (e.data?.type !== "ow:
|
|
8016
|
-
const { key } = e.data;
|
|
8292
|
+
const handleImageUploading = (e) => {
|
|
8293
|
+
if (e.data?.type !== "ow:image-uploading") return;
|
|
8294
|
+
const { key, uploading } = e.data;
|
|
8295
|
+
setUploadingRects((prev) => {
|
|
8296
|
+
if (!uploading) {
|
|
8297
|
+
if (!(key in prev)) return prev;
|
|
8298
|
+
const next = { ...prev };
|
|
8299
|
+
delete next[key];
|
|
8300
|
+
return next;
|
|
8301
|
+
}
|
|
8302
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
8303
|
+
if (!el) return prev;
|
|
8304
|
+
const r2 = getVisibleRect(el);
|
|
8305
|
+
return {
|
|
8306
|
+
...prev,
|
|
8307
|
+
[key]: { rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } }
|
|
8308
|
+
};
|
|
8309
|
+
});
|
|
8017
8310
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8018
8311
|
const track = el.closest("[data-ohw-hover-pause]");
|
|
8019
|
-
if (track)
|
|
8312
|
+
if (!track) return;
|
|
8313
|
+
if (uploading) {
|
|
8020
8314
|
uploadLockedTracks.add(track);
|
|
8021
8315
|
track.setAttribute("data-ohw-hover-paused", "");
|
|
8316
|
+
} else {
|
|
8317
|
+
uploadLockedTracks.delete(track);
|
|
8318
|
+
track.removeAttribute("data-ohw-hover-paused");
|
|
8022
8319
|
}
|
|
8023
8320
|
});
|
|
8024
8321
|
};
|
|
@@ -8060,7 +8357,7 @@ function OhhwellsBridge() {
|
|
|
8060
8357
|
if (e.data?.type !== "ow:click-at") return;
|
|
8061
8358
|
const { clientX, clientY } = e.data;
|
|
8062
8359
|
const allImages = Array.from(
|
|
8063
|
-
document.querySelectorAll(
|
|
8360
|
+
document.querySelectorAll(MEDIA_SELECTOR)
|
|
8064
8361
|
).filter((el) => !!el.closest("[data-ohw-editable-state]"));
|
|
8065
8362
|
const stateCardImage = allImages.find((el) => {
|
|
8066
8363
|
const ownerCard = el.closest("[data-ohw-editable-state]");
|
|
@@ -8075,13 +8372,11 @@ function OhhwellsBridge() {
|
|
|
8075
8372
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
8076
8373
|
});
|
|
8077
8374
|
if (stateCardImage) {
|
|
8078
|
-
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "" });
|
|
8375
|
+
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "", elementType: stateCardImage.dataset.ohwEditable ?? "image" });
|
|
8079
8376
|
return;
|
|
8080
8377
|
}
|
|
8081
8378
|
const textEditable = Array.from(
|
|
8082
|
-
document.querySelectorAll(
|
|
8083
|
-
'[data-ohw-editable]:not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"])'
|
|
8084
|
-
)
|
|
8379
|
+
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
8085
8380
|
).find((el) => {
|
|
8086
8381
|
const r2 = el.getBoundingClientRect();
|
|
8087
8382
|
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
@@ -8109,7 +8404,7 @@ function OhhwellsBridge() {
|
|
|
8109
8404
|
window.addEventListener("message", handleClearSchedulingWidget);
|
|
8110
8405
|
window.addEventListener("message", handleRemoveSchedulingSection);
|
|
8111
8406
|
window.addEventListener("message", handleImageUrl);
|
|
8112
|
-
window.addEventListener("message",
|
|
8407
|
+
window.addEventListener("message", handleImageUploading);
|
|
8113
8408
|
window.addEventListener("message", handleCanvasHeight);
|
|
8114
8409
|
window.addEventListener("message", handleParentScroll);
|
|
8115
8410
|
window.addEventListener("message", handlePointerSync);
|
|
@@ -8156,7 +8451,7 @@ function OhhwellsBridge() {
|
|
|
8156
8451
|
window.removeEventListener("message", handleClearSchedulingWidget);
|
|
8157
8452
|
window.removeEventListener("message", handleRemoveSchedulingSection);
|
|
8158
8453
|
window.removeEventListener("message", handleImageUrl);
|
|
8159
|
-
window.removeEventListener("message",
|
|
8454
|
+
window.removeEventListener("message", handleImageUploading);
|
|
8160
8455
|
window.removeEventListener("message", handleCanvasHeight);
|
|
8161
8456
|
window.removeEventListener("message", handleParentScroll);
|
|
8162
8457
|
window.removeEventListener("resize", handleViewportResize);
|
|
@@ -8276,12 +8571,68 @@ function OhhwellsBridge() {
|
|
|
8276
8571
|
const showEditLink = toolbarShowEditLink;
|
|
8277
8572
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
8278
8573
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
8574
|
+
const handleMediaReplace = (0, import_react6.useCallback)(
|
|
8575
|
+
(key) => {
|
|
8576
|
+
postToParent({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
8577
|
+
},
|
|
8578
|
+
[postToParent, mediaHover?.elementType]
|
|
8579
|
+
);
|
|
8580
|
+
const handleVideoSettingsChange = (0, import_react6.useCallback)(
|
|
8581
|
+
(key, settings) => {
|
|
8582
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
8583
|
+
const video = getVideoEl(el);
|
|
8584
|
+
if (!video) return;
|
|
8585
|
+
if (typeof settings.autoplay === "boolean") video.autoplay = settings.autoplay;
|
|
8586
|
+
if (typeof settings.muted === "boolean") video.muted = settings.muted;
|
|
8587
|
+
syncVideoPlayback(video);
|
|
8588
|
+
postToParent({
|
|
8589
|
+
type: "ow:change",
|
|
8590
|
+
nodes: [
|
|
8591
|
+
{ key: `${key}${VIDEO_AUTOPLAY_SUFFIX}`, text: String(video.autoplay) },
|
|
8592
|
+
{ key: `${key}${VIDEO_MUTED_SUFFIX}`, text: String(video.muted) }
|
|
8593
|
+
]
|
|
8594
|
+
});
|
|
8595
|
+
setMediaHover(
|
|
8596
|
+
(prev) => prev && prev.key === key ? { ...prev, videoAutoplay: video.autoplay, videoMuted: video.muted } : prev
|
|
8597
|
+
);
|
|
8598
|
+
});
|
|
8599
|
+
},
|
|
8600
|
+
[postToParent]
|
|
8601
|
+
);
|
|
8602
|
+
const handleMediaFadeOutComplete = (0, import_react6.useCallback)((key) => {
|
|
8603
|
+
setUploadingRects((prev) => {
|
|
8604
|
+
if (!(key in prev)) return prev;
|
|
8605
|
+
const next = { ...prev };
|
|
8606
|
+
delete next[key];
|
|
8607
|
+
return next;
|
|
8608
|
+
});
|
|
8609
|
+
}, []);
|
|
8279
8610
|
return bridgeRoot ? (0, import_react_dom2.createPortal)(
|
|
8280
|
-
/* @__PURE__ */ (0,
|
|
8281
|
-
/* @__PURE__ */ (0,
|
|
8282
|
-
|
|
8283
|
-
|
|
8284
|
-
|
|
8611
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
8612
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
8613
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8614
|
+
MediaOverlay,
|
|
8615
|
+
{
|
|
8616
|
+
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
8617
|
+
isUploading: true,
|
|
8618
|
+
fadingOut,
|
|
8619
|
+
onFadeOutComplete: handleMediaFadeOutComplete,
|
|
8620
|
+
onReplace: handleMediaReplace
|
|
8621
|
+
},
|
|
8622
|
+
`uploading-${key}`
|
|
8623
|
+
)),
|
|
8624
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8625
|
+
MediaOverlay,
|
|
8626
|
+
{
|
|
8627
|
+
hover: mediaHover,
|
|
8628
|
+
isUploading: false,
|
|
8629
|
+
onReplace: handleMediaReplace,
|
|
8630
|
+
onVideoSettingsChange: handleVideoSettingsChange
|
|
8631
|
+
}
|
|
8632
|
+
),
|
|
8633
|
+
siblingHintRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
8634
|
+
hoveredItemRect && !siblingHintRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
8635
|
+
toolbarRect && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8285
8636
|
ItemInteractionLayer,
|
|
8286
8637
|
{
|
|
8287
8638
|
rect: toolbarRect,
|
|
@@ -8292,7 +8643,7 @@ function OhhwellsBridge() {
|
|
|
8292
8643
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
8293
8644
|
onDragHandleDragStart: handleItemDragStart,
|
|
8294
8645
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
8295
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0,
|
|
8646
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8296
8647
|
ItemActionToolbar,
|
|
8297
8648
|
{
|
|
8298
8649
|
onEditLink: openLinkPopoverForSelected,
|
|
@@ -8302,8 +8653,8 @@ function OhhwellsBridge() {
|
|
|
8302
8653
|
) : void 0
|
|
8303
8654
|
}
|
|
8304
8655
|
),
|
|
8305
|
-
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0,
|
|
8306
|
-
/* @__PURE__ */ (0,
|
|
8656
|
+
toolbarRect && toolbarVariant === "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
8657
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8307
8658
|
EditGlowChrome,
|
|
8308
8659
|
{
|
|
8309
8660
|
rect: toolbarRect,
|
|
@@ -8312,7 +8663,7 @@ function OhhwellsBridge() {
|
|
|
8312
8663
|
dragDisabled: reorderDragDisabled
|
|
8313
8664
|
}
|
|
8314
8665
|
),
|
|
8315
|
-
/* @__PURE__ */ (0,
|
|
8666
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8316
8667
|
FloatingToolbar,
|
|
8317
8668
|
{
|
|
8318
8669
|
rect: toolbarRect,
|
|
@@ -8325,7 +8676,7 @@ function OhhwellsBridge() {
|
|
|
8325
8676
|
}
|
|
8326
8677
|
)
|
|
8327
8678
|
] }),
|
|
8328
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
8679
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
8329
8680
|
"div",
|
|
8330
8681
|
{
|
|
8331
8682
|
"data-ohw-max-badge": "",
|
|
@@ -8351,7 +8702,7 @@ function OhhwellsBridge() {
|
|
|
8351
8702
|
]
|
|
8352
8703
|
}
|
|
8353
8704
|
),
|
|
8354
|
-
toggleState && /* @__PURE__ */ (0,
|
|
8705
|
+
toggleState && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8355
8706
|
StateToggle,
|
|
8356
8707
|
{
|
|
8357
8708
|
rect: toggleState.rect,
|
|
@@ -8360,15 +8711,15 @@ function OhhwellsBridge() {
|
|
|
8360
8711
|
onStateChange: handleStateChange
|
|
8361
8712
|
}
|
|
8362
8713
|
),
|
|
8363
|
-
sectionGap && /* @__PURE__ */ (0,
|
|
8714
|
+
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
8364
8715
|
"div",
|
|
8365
8716
|
{
|
|
8366
8717
|
"data-ohw-section-insert-line": "",
|
|
8367
8718
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8368
8719
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8369
8720
|
children: [
|
|
8370
|
-
/* @__PURE__ */ (0,
|
|
8371
|
-
/* @__PURE__ */ (0,
|
|
8721
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
8722
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8372
8723
|
Badge,
|
|
8373
8724
|
{
|
|
8374
8725
|
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",
|
|
@@ -8381,11 +8732,11 @@ function OhhwellsBridge() {
|
|
|
8381
8732
|
children: "Add Section"
|
|
8382
8733
|
}
|
|
8383
8734
|
),
|
|
8384
|
-
/* @__PURE__ */ (0,
|
|
8735
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8385
8736
|
]
|
|
8386
8737
|
}
|
|
8387
8738
|
),
|
|
8388
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0,
|
|
8739
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8389
8740
|
LinkPopover,
|
|
8390
8741
|
{
|
|
8391
8742
|
panelRef: linkPopoverPanelRef,
|
|
@@ -8401,15 +8752,15 @@ function OhhwellsBridge() {
|
|
|
8401
8752
|
},
|
|
8402
8753
|
`${linkPopover.key}-${pathname}`
|
|
8403
8754
|
) : null,
|
|
8404
|
-
sectionGap && /* @__PURE__ */ (0,
|
|
8755
|
+
sectionGap && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
8405
8756
|
"div",
|
|
8406
8757
|
{
|
|
8407
8758
|
"data-ohw-section-insert-line": "",
|
|
8408
8759
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
8409
8760
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
8410
8761
|
children: [
|
|
8411
|
-
/* @__PURE__ */ (0,
|
|
8412
|
-
/* @__PURE__ */ (0,
|
|
8762
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
8763
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
8413
8764
|
Badge,
|
|
8414
8765
|
{
|
|
8415
8766
|
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",
|
|
@@ -8422,7 +8773,7 @@ function OhhwellsBridge() {
|
|
|
8422
8773
|
children: "Add Section"
|
|
8423
8774
|
}
|
|
8424
8775
|
),
|
|
8425
|
-
/* @__PURE__ */ (0,
|
|
8776
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
8426
8777
|
]
|
|
8427
8778
|
}
|
|
8428
8779
|
)
|