@yoamigo.com/core 0.1.15 → 0.2.2
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/{MarkdownText-BUTYfqXS.d.ts → MarkdownText-kV5IiAma.d.ts} +3 -3
- package/dist/index.d.ts +183 -6
- package/dist/index.js +1203 -138
- package/dist/plugin.js +31 -0
- package/dist/prod.d.ts +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1219,7 +1219,7 @@ function AIEditProvider({ children, staggerDelay = 100 }) {
|
|
|
1219
1219
|
processingRef.current = true;
|
|
1220
1220
|
const fieldId = queueRef.current.shift();
|
|
1221
1221
|
const state = animationsRef.current.get(fieldId);
|
|
1222
|
-
if (state
|
|
1222
|
+
if (state?.status === "pending") {
|
|
1223
1223
|
state.status = "animating";
|
|
1224
1224
|
state.startTime = performance.now();
|
|
1225
1225
|
notifyListeners(fieldId);
|
|
@@ -1232,7 +1232,7 @@ function AIEditProvider({ children, staggerDelay = 100 }) {
|
|
|
1232
1232
|
const queueAnimation = useCallback3(
|
|
1233
1233
|
(fieldId, config) => {
|
|
1234
1234
|
const existing = animationsRef.current.get(fieldId);
|
|
1235
|
-
if (existing
|
|
1235
|
+
if (existing?.status === "animating") {
|
|
1236
1236
|
animationsRef.current.delete(fieldId);
|
|
1237
1237
|
}
|
|
1238
1238
|
const state = {
|
|
@@ -2508,7 +2508,7 @@ function YaTooltip({
|
|
|
2508
2508
|
}
|
|
2509
2509
|
|
|
2510
2510
|
// src/components/ya-image.css
|
|
2511
|
-
styleInject('.ya-image-container {\n position: relative;\n display: inline-block;\n min-width: 45px;\n min-height: 45px;\n cursor: pointer;\n transition: outline 0.15s ease;\n}\n.ya-image-container img {\n display: block;\n}\n.ya-image-editable {\n cursor: pointer;\n}\n.ya-image-editable:hover {\n outline: 2px dashed var(--color-primary, #D4A574);\n outline-offset: 4px;\n}\n.ya-image-selected {\n outline: 3px solid var(--color-primary, #D4A574);\n outline-offset: 4px;\n}\n.ya-image-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n background: rgba(0, 0, 0, 0.5);\n opacity: 0;\n transition: opacity 0.2s ease;\n pointer-events: none;\n border-radius: inherit;\n}\n.ya-image-editable:hover .ya-image-overlay {\n opacity: 1;\n}\n.ya-image-selected .ya-image-overlay {\n opacity: 0;\n}\n.ya-image-edit-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n background: white;\n border-radius: 50%;\n color: #1a1a1a;\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2);\n}\n.ya-image-edit-icon svg {\n width: 24px;\n height: 24px;\n}\n.ya-image-edit-label {\n color: white;\n font-size: 14px;\n font-weight: 500;\n text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);\n}\n@keyframes ya-image-success {\n 0% {\n outline-color: var(--color-primary, #D4A574);\n }\n 50% {\n outline-color: #22c55e;\n outline-width: 4px;\n }\n 100% {\n outline-color: var(--color-primary, #D4A574);\n outline-width: 2px;\n }\n}\n.ya-image-success {\n animation: ya-image-success 0.4s ease;\n}\n.ya-image-loading::after {\n content: "";\n position: absolute;\n inset: 0;\n background:\n linear-gradient(\n 90deg,\n rgba(255, 255, 255, 0) 0%,\n rgba(255, 255, 255, 0.3) 50%,\n rgba(255, 255, 255, 0) 100%);\n background-size: 200% 100%;\n animation: ya-image-shimmer 1.5s infinite;\n}\n@keyframes ya-image-shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.ya-image-container:focus {\n outline: 3px solid var(--color-primary, #D4A574);\n outline-offset: 4px;\n}\n.ya-image-container:focus:not(:focus-visible) {\n outline: none;\n}\n.ya-image-container:focus-visible {\n outline: 3px solid var(--color-primary, #D4A574);\n outline-offset: 4px;\n}\n.ya-image-small .ya-image-overlay {\n display: none;\n}\n');
|
|
2511
|
+
styleInject('.ya-image-container {\n position: relative;\n display: inline-block;\n min-width: 45px;\n min-height: 45px;\n cursor: pointer;\n transition: outline 0.15s ease;\n}\n.ya-image-container img {\n display: block;\n}\n.ya-image-editable {\n cursor: pointer;\n}\n.ya-image-editable:hover {\n outline: 2px dashed var(--color-primary, #D4A574);\n outline-offset: 4px;\n}\n.ya-image-selected {\n outline: 3px solid var(--color-primary, #D4A574);\n outline-offset: 4px;\n}\n.ya-image-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n background: rgba(0, 0, 0, 0.5);\n opacity: 0;\n transition: opacity 0.2s ease;\n pointer-events: none;\n border-radius: inherit;\n}\n.ya-image-editable:hover .ya-image-overlay {\n opacity: 1;\n}\n.ya-image-selected .ya-image-overlay {\n opacity: 0;\n}\n.ya-image-edit-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n background: white;\n border-radius: 50%;\n color: #1a1a1a;\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2);\n}\n.ya-image-edit-icon svg {\n width: 24px;\n height: 24px;\n}\n.ya-image-edit-label {\n color: white;\n font-size: 14px;\n font-weight: 500;\n text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);\n}\n@keyframes ya-image-success {\n 0% {\n outline-color: var(--color-primary, #D4A574);\n }\n 50% {\n outline-color: #22c55e;\n outline-width: 4px;\n }\n 100% {\n outline-color: var(--color-primary, #D4A574);\n outline-width: 2px;\n }\n}\n.ya-image-success {\n animation: ya-image-success 0.4s ease;\n}\n.ya-image-loading::after {\n content: "";\n position: absolute;\n inset: 0;\n background:\n linear-gradient(\n 90deg,\n rgba(255, 255, 255, 0) 0%,\n rgba(255, 255, 255, 0.3) 50%,\n rgba(255, 255, 255, 0) 100%);\n background-size: 200% 100%;\n animation: ya-image-shimmer 1.5s infinite;\n}\n@keyframes ya-image-shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.ya-image-container:focus {\n outline: 3px solid var(--color-primary, #D4A574);\n outline-offset: 4px;\n}\n.ya-image-container:focus:not(:focus-visible) {\n outline: none;\n}\n.ya-image-container:focus-visible {\n outline: 3px solid var(--color-primary, #D4A574);\n outline-offset: 4px;\n}\n.ya-image-small .ya-image-overlay {\n display: none;\n}\n.ya-image-drop-target {\n outline: 2px dashed var(--ya-drop-color, #3b82f6) !important;\n outline-offset: 4px;\n}\n.ya-image-drop-target .ya-image-overlay {\n display: none !important;\n}\n.ya-image-drop-hover {\n outline: 3px solid var(--ya-drop-color, #3b82f6) !important;\n outline-offset: 4px;\n background-color: rgba(59, 130, 246, 0.1);\n}\n.ya-image-drop-hover::before {\n content: "";\n position: absolute;\n inset: -4px;\n border: 2px solid var(--ya-drop-color, #3b82f6);\n border-radius: inherit;\n animation: ya-drop-pulse 1s ease-in-out infinite;\n pointer-events: none;\n}\n@keyframes ya-drop-pulse {\n 0%, 100% {\n opacity: 0.4;\n transform: scale(1);\n }\n 50% {\n opacity: 0.8;\n transform: scale(1.02);\n }\n}\n');
|
|
2512
2512
|
|
|
2513
2513
|
// src/components/YaImage.tsx
|
|
2514
2514
|
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
@@ -2561,6 +2561,8 @@ function YaImage({
|
|
|
2561
2561
|
const [isSelected, setIsSelected] = useState6(false);
|
|
2562
2562
|
const [isHovered, setIsHovered] = useState6(false);
|
|
2563
2563
|
const [isSmallImage, setIsSmallImage] = useState6(false);
|
|
2564
|
+
const [isDropMode, setIsDropMode] = useState6(false);
|
|
2565
|
+
const [isDropHover, setIsDropHover] = useState6(false);
|
|
2564
2566
|
const rawValue = getValue(fieldId);
|
|
2565
2567
|
const imageData = parseImageValue(rawValue);
|
|
2566
2568
|
const src = imageData.src || fallbackSrc || PLACEHOLDER_SVG;
|
|
@@ -2610,6 +2612,84 @@ function YaImage({
|
|
|
2610
2612
|
window.addEventListener("message", handleMessage2);
|
|
2611
2613
|
return () => window.removeEventListener("message", handleMessage2);
|
|
2612
2614
|
}, [mode, fieldId]);
|
|
2615
|
+
useEffect6(() => {
|
|
2616
|
+
if (mode !== "inline-edit") return;
|
|
2617
|
+
const handleDropModeMessage = (event) => {
|
|
2618
|
+
if (event.data?.type === "DROP_MODE_START") {
|
|
2619
|
+
setIsDropMode(true);
|
|
2620
|
+
}
|
|
2621
|
+
if (event.data?.type === "DROP_MODE_END") {
|
|
2622
|
+
setIsDropMode(false);
|
|
2623
|
+
setIsDropHover(false);
|
|
2624
|
+
}
|
|
2625
|
+
};
|
|
2626
|
+
window.addEventListener("message", handleDropModeMessage);
|
|
2627
|
+
return () => window.removeEventListener("message", handleDropModeMessage);
|
|
2628
|
+
}, [mode]);
|
|
2629
|
+
const handleDragEnter = useCallback7(
|
|
2630
|
+
(e) => {
|
|
2631
|
+
if (!isDropMode) return;
|
|
2632
|
+
e.preventDefault();
|
|
2633
|
+
e.stopPropagation();
|
|
2634
|
+
setIsDropHover(true);
|
|
2635
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
2636
|
+
window.parent.postMessage(
|
|
2637
|
+
{
|
|
2638
|
+
type: "DROP_ZONE_ENTER",
|
|
2639
|
+
fieldId,
|
|
2640
|
+
zoneType: "image",
|
|
2641
|
+
rect: rect ? {
|
|
2642
|
+
top: rect.top,
|
|
2643
|
+
left: rect.left,
|
|
2644
|
+
width: rect.width,
|
|
2645
|
+
height: rect.height
|
|
2646
|
+
} : { top: 0, left: 0, width: 0, height: 0 }
|
|
2647
|
+
},
|
|
2648
|
+
"*"
|
|
2649
|
+
);
|
|
2650
|
+
},
|
|
2651
|
+
[isDropMode, fieldId]
|
|
2652
|
+
);
|
|
2653
|
+
const handleDragOver = useCallback7(
|
|
2654
|
+
(e) => {
|
|
2655
|
+
if (!isDropMode) return;
|
|
2656
|
+
e.preventDefault();
|
|
2657
|
+
e.stopPropagation();
|
|
2658
|
+
},
|
|
2659
|
+
[isDropMode]
|
|
2660
|
+
);
|
|
2661
|
+
const handleDragLeave = useCallback7(
|
|
2662
|
+
(e) => {
|
|
2663
|
+
if (!isDropMode) return;
|
|
2664
|
+
e.preventDefault();
|
|
2665
|
+
e.stopPropagation();
|
|
2666
|
+
const target = e.currentTarget;
|
|
2667
|
+
const relatedTarget = e.relatedTarget;
|
|
2668
|
+
if (!relatedTarget || !target.contains(relatedTarget)) {
|
|
2669
|
+
setIsDropHover(false);
|
|
2670
|
+
window.parent.postMessage({ type: "DROP_ZONE_LEAVE" }, "*");
|
|
2671
|
+
}
|
|
2672
|
+
},
|
|
2673
|
+
[isDropMode]
|
|
2674
|
+
);
|
|
2675
|
+
const handleDrop = useCallback7(
|
|
2676
|
+
(e) => {
|
|
2677
|
+
if (!isDropMode) return;
|
|
2678
|
+
e.preventDefault();
|
|
2679
|
+
e.stopPropagation();
|
|
2680
|
+
setIsDropHover(false);
|
|
2681
|
+
setIsDropMode(false);
|
|
2682
|
+
window.parent.postMessage(
|
|
2683
|
+
{
|
|
2684
|
+
type: "DROP_ZONE_DROP",
|
|
2685
|
+
fieldId,
|
|
2686
|
+
zoneType: "image"
|
|
2687
|
+
},
|
|
2688
|
+
"*"
|
|
2689
|
+
);
|
|
2690
|
+
},
|
|
2691
|
+
[isDropMode, fieldId]
|
|
2692
|
+
);
|
|
2613
2693
|
useEffect6(() => {
|
|
2614
2694
|
if (mode !== "inline-edit") return;
|
|
2615
2695
|
const checkSize = () => {
|
|
@@ -2701,14 +2781,25 @@ function YaImage({
|
|
|
2701
2781
|
]
|
|
2702
2782
|
}
|
|
2703
2783
|
);
|
|
2784
|
+
const containerClasses = [
|
|
2785
|
+
"ya-image-container",
|
|
2786
|
+
isSelected ? "ya-image-selected" : "ya-image-editable",
|
|
2787
|
+
isSmallImage ? "ya-image-small" : "",
|
|
2788
|
+
isDropMode ? "ya-image-drop-target" : "",
|
|
2789
|
+
isDropHover ? "ya-image-drop-hover" : ""
|
|
2790
|
+
].filter(Boolean).join(" ");
|
|
2704
2791
|
return /* @__PURE__ */ jsxs3(
|
|
2705
2792
|
"div",
|
|
2706
2793
|
{
|
|
2707
2794
|
ref: containerRef,
|
|
2708
|
-
className:
|
|
2795
|
+
className: containerClasses,
|
|
2709
2796
|
onClick: handleClick,
|
|
2710
2797
|
onMouseEnter: () => setIsHovered(true),
|
|
2711
2798
|
onMouseLeave: () => setIsHovered(false),
|
|
2799
|
+
onDragEnter: handleDragEnter,
|
|
2800
|
+
onDragOver: handleDragOver,
|
|
2801
|
+
onDragLeave: handleDragLeave,
|
|
2802
|
+
onDrop: handleDrop,
|
|
2712
2803
|
"data-ya-restricted": "true",
|
|
2713
2804
|
"data-field-id": fieldId,
|
|
2714
2805
|
"data-ya-image": "true",
|
|
@@ -2751,9 +2842,396 @@ function YaImage({
|
|
|
2751
2842
|
);
|
|
2752
2843
|
}
|
|
2753
2844
|
|
|
2845
|
+
// src/components/YaVideo.tsx
|
|
2846
|
+
import { useCallback as useCallback8, useEffect as useEffect7, useRef as useRef8, useState as useState7 } from "react";
|
|
2847
|
+
|
|
2848
|
+
// src/components/ya-video.css
|
|
2849
|
+
styleInject('.ya-video-wrapper {\n position: relative;\n display: block;\n width: 100%;\n}\n.ya-video-wrapper video,\n.ya-video-wrapper iframe {\n display: block;\n width: 100%;\n height: 100%;\n}\n.ya-video-container {\n position: relative;\n display: block;\n width: 100%;\n min-width: 80px;\n min-height: 45px;\n cursor: pointer;\n transition: outline 0.15s ease;\n}\n.ya-video-container video,\n.ya-video-container iframe {\n display: block;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.ya-video-editable {\n cursor: pointer;\n}\n.ya-video-editable:hover {\n outline: 2px dashed var(--color-primary, #D4A574);\n outline-offset: 4px;\n}\n.ya-video-selected {\n outline: 3px solid var(--color-primary, #D4A574);\n outline-offset: 4px;\n}\n.ya-video-overlay {\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n background: rgba(0, 0, 0, 0.5);\n opacity: 0;\n transition: opacity 0.2s ease;\n pointer-events: none;\n border-radius: inherit;\n}\n.ya-video-editable:hover .ya-video-overlay {\n opacity: 1;\n}\n.ya-video-selected .ya-video-overlay {\n opacity: 0;\n}\n.ya-video-edit-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 48px;\n height: 48px;\n background: white;\n border-radius: 50%;\n color: #1a1a1a;\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2);\n}\n.ya-video-edit-icon svg {\n width: 24px;\n height: 24px;\n}\n.ya-video-edit-label {\n color: white;\n font-size: 14px;\n font-weight: 500;\n text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);\n}\n.ya-video-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 100%;\n height: 100%;\n min-height: 120px;\n background: #f3f4f6;\n border: 2px dashed #d1d5db;\n border-radius: 8px;\n color: #6b7280;\n font-size: 14px;\n}\n.ya-video-placeholder img {\n width: 64px;\n height: auto;\n opacity: 0.5;\n}\n@keyframes ya-video-success {\n 0% {\n outline-color: var(--color-primary, #D4A574);\n }\n 50% {\n outline-color: #22c55e;\n outline-width: 4px;\n }\n 100% {\n outline-color: var(--color-primary, #D4A574);\n outline-width: 2px;\n }\n}\n.ya-video-success {\n animation: ya-video-success 0.4s ease;\n}\n.ya-video-loading::after {\n content: "";\n position: absolute;\n inset: 0;\n background:\n linear-gradient(\n 90deg,\n rgba(255, 255, 255, 0) 0%,\n rgba(255, 255, 255, 0.3) 50%,\n rgba(255, 255, 255, 0) 100%);\n background-size: 200% 100%;\n animation: ya-video-shimmer 1.5s infinite;\n}\n@keyframes ya-video-shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.ya-video-container:focus {\n outline: 3px solid var(--color-primary, #D4A574);\n outline-offset: 4px;\n}\n.ya-video-container:focus:not(:focus-visible) {\n outline: none;\n}\n.ya-video-container:focus-visible {\n outline: 3px solid var(--color-primary, #D4A574);\n outline-offset: 4px;\n}\n.ya-video-small .ya-video-overlay {\n display: none;\n}\n.ya-video-background {\n position: absolute;\n inset: 0;\n z-index: -1;\n}\n.ya-video-background video {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n');
|
|
2850
|
+
|
|
2851
|
+
// src/components/YaVideo.tsx
|
|
2852
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2853
|
+
function parseVideoValue(value) {
|
|
2854
|
+
if (!value) {
|
|
2855
|
+
return { type: "upload", src: "" };
|
|
2856
|
+
}
|
|
2857
|
+
try {
|
|
2858
|
+
const parsed = JSON.parse(value);
|
|
2859
|
+
if (typeof parsed === "object" && parsed.src) {
|
|
2860
|
+
return {
|
|
2861
|
+
type: parsed.type || "upload",
|
|
2862
|
+
...parsed
|
|
2863
|
+
};
|
|
2864
|
+
}
|
|
2865
|
+
} catch {
|
|
2866
|
+
}
|
|
2867
|
+
return { type: "upload", src: value };
|
|
2868
|
+
}
|
|
2869
|
+
function serializeVideoValue(value) {
|
|
2870
|
+
return JSON.stringify(value);
|
|
2871
|
+
}
|
|
2872
|
+
function buildYouTubeEmbedUrl(videoId, value) {
|
|
2873
|
+
const params = new URLSearchParams({
|
|
2874
|
+
rel: "0",
|
|
2875
|
+
modestbranding: "1"
|
|
2876
|
+
});
|
|
2877
|
+
if (value.autoplay) params.set("autoplay", "1");
|
|
2878
|
+
if (value.muted) params.set("mute", "1");
|
|
2879
|
+
if (value.loop) {
|
|
2880
|
+
params.set("loop", "1");
|
|
2881
|
+
params.set("playlist", videoId);
|
|
2882
|
+
}
|
|
2883
|
+
if (value.controls === false) params.set("controls", "0");
|
|
2884
|
+
if (value.startTime) params.set("start", String(Math.floor(value.startTime)));
|
|
2885
|
+
if (value.endTime) params.set("end", String(Math.floor(value.endTime)));
|
|
2886
|
+
return `https://www.youtube.com/embed/${videoId}?${params.toString()}`;
|
|
2887
|
+
}
|
|
2888
|
+
function buildVimeoEmbedUrl(videoId, value) {
|
|
2889
|
+
const params = new URLSearchParams({
|
|
2890
|
+
title: "0",
|
|
2891
|
+
byline: "0",
|
|
2892
|
+
portrait: "0"
|
|
2893
|
+
});
|
|
2894
|
+
if (value.autoplay) params.set("autoplay", "1");
|
|
2895
|
+
if (value.muted) params.set("muted", "1");
|
|
2896
|
+
if (value.loop) params.set("loop", "1");
|
|
2897
|
+
if (value.controls === false) params.set("controls", "0");
|
|
2898
|
+
let url = `https://player.vimeo.com/video/${videoId}?${params.toString()}`;
|
|
2899
|
+
if (value.startTime) {
|
|
2900
|
+
url += `#t=${Math.floor(value.startTime)}s`;
|
|
2901
|
+
}
|
|
2902
|
+
return url;
|
|
2903
|
+
}
|
|
2904
|
+
var SMALL_VIDEO_THRESHOLD = 100;
|
|
2905
|
+
var PLACEHOLDER_SVG2 = `data:image/svg+xml,${encodeURIComponent(`
|
|
2906
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="225" viewBox="0 0 400 225">
|
|
2907
|
+
<rect fill="#e5e7eb" width="400" height="225"/>
|
|
2908
|
+
<g fill="#9ca3af" transform="translate(175, 87)">
|
|
2909
|
+
<rect x="0" y="5" width="35" height="25" rx="3" stroke="currentColor" stroke-width="2" fill="none"/>
|
|
2910
|
+
<polygon points="40,17.5 50,10 50,25" fill="currentColor"/>
|
|
2911
|
+
</g>
|
|
2912
|
+
</svg>
|
|
2913
|
+
`)}`;
|
|
2914
|
+
function YaVideo({
|
|
2915
|
+
fieldId,
|
|
2916
|
+
className,
|
|
2917
|
+
aspectRatio: propAspectRatio,
|
|
2918
|
+
objectFit: propObjectFit,
|
|
2919
|
+
loading = "lazy",
|
|
2920
|
+
defaultValue,
|
|
2921
|
+
fallbackSrc,
|
|
2922
|
+
fallbackPoster
|
|
2923
|
+
}) {
|
|
2924
|
+
const { getValue, mode } = useContentStore();
|
|
2925
|
+
const containerRef = useRef8(null);
|
|
2926
|
+
const videoRef = useRef8(null);
|
|
2927
|
+
const [isSelected, setIsSelected] = useState7(false);
|
|
2928
|
+
const [isHovered, setIsHovered] = useState7(false);
|
|
2929
|
+
const [isSmallVideo, setIsSmallVideo] = useState7(false);
|
|
2930
|
+
const [isInView, setIsInView] = useState7(loading === "eager");
|
|
2931
|
+
const rawValue = getValue(fieldId);
|
|
2932
|
+
const parsedValue = parseVideoValue(rawValue);
|
|
2933
|
+
const videoData = parsedValue.src ? parsedValue : defaultValue || parsedValue;
|
|
2934
|
+
const src = videoData.src || fallbackSrc || "";
|
|
2935
|
+
const poster = videoData.poster || fallbackPoster || "";
|
|
2936
|
+
const objectFit = videoData.objectFit || propObjectFit || "cover";
|
|
2937
|
+
const aspectRatio = videoData.aspectRatio || propAspectRatio || "16/9";
|
|
2938
|
+
const autoplay = videoData.autoplay ?? false;
|
|
2939
|
+
const muted = videoData.muted ?? false;
|
|
2940
|
+
const loop = videoData.loop ?? false;
|
|
2941
|
+
const controls = videoData.controls ?? true;
|
|
2942
|
+
const playsinline = videoData.playsinline ?? true;
|
|
2943
|
+
const preload = videoData.preload ?? "metadata";
|
|
2944
|
+
const [prefersReducedMotion, setPrefersReducedMotion] = useState7(false);
|
|
2945
|
+
useEffect7(() => {
|
|
2946
|
+
const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
2947
|
+
setPrefersReducedMotion(mediaQuery.matches);
|
|
2948
|
+
const handleChange = (e) => {
|
|
2949
|
+
setPrefersReducedMotion(e.matches);
|
|
2950
|
+
};
|
|
2951
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
2952
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
2953
|
+
}, []);
|
|
2954
|
+
const effectiveAutoplay = autoplay && !prefersReducedMotion;
|
|
2955
|
+
useEffect7(() => {
|
|
2956
|
+
if (loading === "eager" || isInView) return;
|
|
2957
|
+
const observer = new IntersectionObserver(
|
|
2958
|
+
(entries) => {
|
|
2959
|
+
if (entries[0]?.isIntersecting) {
|
|
2960
|
+
setIsInView(true);
|
|
2961
|
+
observer.disconnect();
|
|
2962
|
+
}
|
|
2963
|
+
},
|
|
2964
|
+
{ rootMargin: "200px" }
|
|
2965
|
+
// Start loading 200px before visible
|
|
2966
|
+
);
|
|
2967
|
+
if (containerRef.current) {
|
|
2968
|
+
observer.observe(containerRef.current);
|
|
2969
|
+
}
|
|
2970
|
+
return () => observer.disconnect();
|
|
2971
|
+
}, [loading, isInView]);
|
|
2972
|
+
const handleKeyDown = useCallback8(
|
|
2973
|
+
(e) => {
|
|
2974
|
+
if ((e.key === " " || e.key === "Enter") && videoData.type === "upload" && controls) {
|
|
2975
|
+
e.preventDefault();
|
|
2976
|
+
const video = videoRef.current;
|
|
2977
|
+
if (video) {
|
|
2978
|
+
if (video.paused) {
|
|
2979
|
+
video.play();
|
|
2980
|
+
} else {
|
|
2981
|
+
video.pause();
|
|
2982
|
+
}
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2985
|
+
},
|
|
2986
|
+
[videoData.type, controls]
|
|
2987
|
+
);
|
|
2988
|
+
const handleClick = useCallback8(() => {
|
|
2989
|
+
if (mode !== "inline-edit") return;
|
|
2990
|
+
if (document.body.classList.contains("builder-selector-active")) return;
|
|
2991
|
+
setIsSelected(true);
|
|
2992
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
2993
|
+
window.parent.postMessage(
|
|
2994
|
+
{
|
|
2995
|
+
type: "YA_VIDEO_EDIT_REQUEST",
|
|
2996
|
+
fieldId,
|
|
2997
|
+
currentValue: videoData,
|
|
2998
|
+
elementRect: rect ? {
|
|
2999
|
+
top: rect.top,
|
|
3000
|
+
left: rect.left,
|
|
3001
|
+
width: rect.width,
|
|
3002
|
+
height: rect.height
|
|
3003
|
+
} : void 0
|
|
3004
|
+
},
|
|
3005
|
+
"*"
|
|
3006
|
+
);
|
|
3007
|
+
}, [mode, fieldId, videoData]);
|
|
3008
|
+
useEffect7(() => {
|
|
3009
|
+
if (mode !== "inline-edit") return;
|
|
3010
|
+
const handleMessage2 = (event) => {
|
|
3011
|
+
if (event.data?.type === "YA_VIDEO_EDIT_COMPLETE" && event.data.fieldId === fieldId) {
|
|
3012
|
+
setIsSelected(false);
|
|
3013
|
+
}
|
|
3014
|
+
if (event.data?.type === "YA_VIDEO_EDIT_CANCEL" && event.data.fieldId === fieldId) {
|
|
3015
|
+
setIsSelected(false);
|
|
3016
|
+
}
|
|
3017
|
+
};
|
|
3018
|
+
window.addEventListener("message", handleMessage2);
|
|
3019
|
+
return () => window.removeEventListener("message", handleMessage2);
|
|
3020
|
+
}, [mode, fieldId]);
|
|
3021
|
+
useEffect7(() => {
|
|
3022
|
+
if (mode !== "inline-edit") return;
|
|
3023
|
+
const checkSize = () => {
|
|
3024
|
+
if (containerRef.current) {
|
|
3025
|
+
const { width, height } = containerRef.current.getBoundingClientRect();
|
|
3026
|
+
setIsSmallVideo(width < SMALL_VIDEO_THRESHOLD || height < SMALL_VIDEO_THRESHOLD);
|
|
3027
|
+
}
|
|
3028
|
+
};
|
|
3029
|
+
checkSize();
|
|
3030
|
+
window.addEventListener("resize", checkSize);
|
|
3031
|
+
return () => window.removeEventListener("resize", checkSize);
|
|
3032
|
+
}, [mode]);
|
|
3033
|
+
useEffect7(() => {
|
|
3034
|
+
if (!isSelected || mode !== "inline-edit") return;
|
|
3035
|
+
let lastRectKey = "";
|
|
3036
|
+
let lastTime = 0;
|
|
3037
|
+
let rafId;
|
|
3038
|
+
const loop2 = (time) => {
|
|
3039
|
+
if (time - lastTime >= 50) {
|
|
3040
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
3041
|
+
if (rect) {
|
|
3042
|
+
const rectKey = `${Math.round(rect.top)},${Math.round(rect.left)},${Math.round(rect.width)},${Math.round(rect.height)}`;
|
|
3043
|
+
if (rectKey !== lastRectKey) {
|
|
3044
|
+
lastRectKey = rectKey;
|
|
3045
|
+
window.parent.postMessage(
|
|
3046
|
+
{
|
|
3047
|
+
type: "YA_VIDEO_POSITION_UPDATE",
|
|
3048
|
+
fieldId,
|
|
3049
|
+
elementRect: {
|
|
3050
|
+
top: rect.top,
|
|
3051
|
+
left: rect.left,
|
|
3052
|
+
width: rect.width,
|
|
3053
|
+
height: rect.height
|
|
3054
|
+
}
|
|
3055
|
+
},
|
|
3056
|
+
"*"
|
|
3057
|
+
);
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
lastTime = time;
|
|
3061
|
+
}
|
|
3062
|
+
rafId = requestAnimationFrame(loop2);
|
|
3063
|
+
};
|
|
3064
|
+
rafId = requestAnimationFrame(loop2);
|
|
3065
|
+
return () => cancelAnimationFrame(rafId);
|
|
3066
|
+
}, [isSelected, fieldId, mode]);
|
|
3067
|
+
const renderVideo = (isReadOnly) => {
|
|
3068
|
+
if (!src && !isReadOnly) {
|
|
3069
|
+
return /* @__PURE__ */ jsxs4("div", { className: "ya-video-placeholder", children: [
|
|
3070
|
+
/* @__PURE__ */ jsx8("img", { src: PLACEHOLDER_SVG2, alt: "" }),
|
|
3071
|
+
/* @__PURE__ */ jsx8("span", { children: "No video selected" })
|
|
3072
|
+
] });
|
|
3073
|
+
}
|
|
3074
|
+
if (!isInView && loading === "lazy" && !isReadOnly) {
|
|
3075
|
+
return /* @__PURE__ */ jsx8(
|
|
3076
|
+
"div",
|
|
3077
|
+
{
|
|
3078
|
+
className: "ya-video-placeholder",
|
|
3079
|
+
style: { aspectRatio },
|
|
3080
|
+
children: /* @__PURE__ */ jsx8("img", { src: PLACEHOLDER_SVG2, alt: "" })
|
|
3081
|
+
}
|
|
3082
|
+
);
|
|
3083
|
+
}
|
|
3084
|
+
if (videoData.type === "youtube" && src) {
|
|
3085
|
+
const embedUrl = buildYouTubeEmbedUrl(src, videoData);
|
|
3086
|
+
return /* @__PURE__ */ jsx8(
|
|
3087
|
+
"iframe",
|
|
3088
|
+
{
|
|
3089
|
+
src: embedUrl,
|
|
3090
|
+
className,
|
|
3091
|
+
style: {
|
|
3092
|
+
width: "100%",
|
|
3093
|
+
height: "100%",
|
|
3094
|
+
border: "none",
|
|
3095
|
+
aspectRatio,
|
|
3096
|
+
objectFit
|
|
3097
|
+
},
|
|
3098
|
+
allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
|
|
3099
|
+
allowFullScreen: true,
|
|
3100
|
+
loading
|
|
3101
|
+
}
|
|
3102
|
+
);
|
|
3103
|
+
}
|
|
3104
|
+
if (videoData.type === "vimeo" && src) {
|
|
3105
|
+
const embedUrl = buildVimeoEmbedUrl(src, videoData);
|
|
3106
|
+
return /* @__PURE__ */ jsx8(
|
|
3107
|
+
"iframe",
|
|
3108
|
+
{
|
|
3109
|
+
src: embedUrl,
|
|
3110
|
+
className,
|
|
3111
|
+
style: {
|
|
3112
|
+
width: "100%",
|
|
3113
|
+
height: "100%",
|
|
3114
|
+
border: "none",
|
|
3115
|
+
aspectRatio,
|
|
3116
|
+
objectFit
|
|
3117
|
+
},
|
|
3118
|
+
allow: "autoplay; fullscreen; picture-in-picture",
|
|
3119
|
+
allowFullScreen: true,
|
|
3120
|
+
loading
|
|
3121
|
+
}
|
|
3122
|
+
);
|
|
3123
|
+
}
|
|
3124
|
+
const resolvedSrc = resolveAssetUrl(src);
|
|
3125
|
+
const resolvedPoster = poster ? resolveAssetUrl(poster) : void 0;
|
|
3126
|
+
return /* @__PURE__ */ jsx8(
|
|
3127
|
+
"video",
|
|
3128
|
+
{
|
|
3129
|
+
ref: videoRef,
|
|
3130
|
+
src: resolvedSrc,
|
|
3131
|
+
poster: resolvedPoster,
|
|
3132
|
+
className,
|
|
3133
|
+
style: {
|
|
3134
|
+
objectFit,
|
|
3135
|
+
aspectRatio
|
|
3136
|
+
},
|
|
3137
|
+
autoPlay: effectiveAutoplay,
|
|
3138
|
+
muted,
|
|
3139
|
+
loop,
|
|
3140
|
+
controls: controls && isReadOnly,
|
|
3141
|
+
playsInline: playsinline,
|
|
3142
|
+
preload,
|
|
3143
|
+
onLoadedMetadata: (e) => {
|
|
3144
|
+
if (videoData.startTime) {
|
|
3145
|
+
e.currentTarget.currentTime = videoData.startTime;
|
|
3146
|
+
}
|
|
3147
|
+
},
|
|
3148
|
+
onTimeUpdate: (e) => {
|
|
3149
|
+
if (videoData.endTime && e.currentTarget.currentTime >= videoData.endTime) {
|
|
3150
|
+
if (loop) {
|
|
3151
|
+
e.currentTarget.currentTime = videoData.startTime || 0;
|
|
3152
|
+
} else {
|
|
3153
|
+
e.currentTarget.pause();
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
}
|
|
3157
|
+
}
|
|
3158
|
+
);
|
|
3159
|
+
};
|
|
3160
|
+
if (mode === "read-only") {
|
|
3161
|
+
return /* @__PURE__ */ jsx8(
|
|
3162
|
+
"div",
|
|
3163
|
+
{
|
|
3164
|
+
ref: containerRef,
|
|
3165
|
+
className: `ya-video-wrapper ${className || ""}`,
|
|
3166
|
+
style: { aspectRatio },
|
|
3167
|
+
"data-ya-restricted": "true",
|
|
3168
|
+
"data-field-id": fieldId,
|
|
3169
|
+
tabIndex: videoData.type === "upload" && controls ? 0 : void 0,
|
|
3170
|
+
role: videoData.type === "upload" && controls ? "application" : void 0,
|
|
3171
|
+
"aria-label": videoData.type === "upload" && controls ? "Video player. Press Space or Enter to play/pause." : void 0,
|
|
3172
|
+
onKeyDown: handleKeyDown,
|
|
3173
|
+
children: renderVideo(true)
|
|
3174
|
+
}
|
|
3175
|
+
);
|
|
3176
|
+
}
|
|
3177
|
+
const videoIcon = /* @__PURE__ */ jsxs4(
|
|
3178
|
+
"svg",
|
|
3179
|
+
{
|
|
3180
|
+
width: "24",
|
|
3181
|
+
height: "24",
|
|
3182
|
+
viewBox: "0 0 24 24",
|
|
3183
|
+
fill: "none",
|
|
3184
|
+
stroke: "currentColor",
|
|
3185
|
+
strokeWidth: "2",
|
|
3186
|
+
strokeLinecap: "round",
|
|
3187
|
+
strokeLinejoin: "round",
|
|
3188
|
+
children: [
|
|
3189
|
+
/* @__PURE__ */ jsx8("rect", { x: "2", y: "4", width: "15", height: "13", rx: "2", ry: "2" }),
|
|
3190
|
+
/* @__PURE__ */ jsx8("polygon", { points: "22 7 15 12 22 17 22 7", fill: "currentColor" })
|
|
3191
|
+
]
|
|
3192
|
+
}
|
|
3193
|
+
);
|
|
3194
|
+
return /* @__PURE__ */ jsxs4(
|
|
3195
|
+
"div",
|
|
3196
|
+
{
|
|
3197
|
+
ref: containerRef,
|
|
3198
|
+
className: `ya-video-container ${isSelected ? "ya-video-selected" : "ya-video-editable"} ${isSmallVideo ? "ya-video-small" : ""}`,
|
|
3199
|
+
onClick: handleClick,
|
|
3200
|
+
onMouseEnter: () => setIsHovered(true),
|
|
3201
|
+
onMouseLeave: () => setIsHovered(false),
|
|
3202
|
+
"data-ya-restricted": "true",
|
|
3203
|
+
"data-field-id": fieldId,
|
|
3204
|
+
"data-ya-video": "true",
|
|
3205
|
+
role: "button",
|
|
3206
|
+
tabIndex: 0,
|
|
3207
|
+
"aria-label": `Edit video: ${fieldId}`,
|
|
3208
|
+
onKeyDown: (e) => {
|
|
3209
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3210
|
+
e.preventDefault();
|
|
3211
|
+
handleClick();
|
|
3212
|
+
}
|
|
3213
|
+
},
|
|
3214
|
+
style: { aspectRatio },
|
|
3215
|
+
children: [
|
|
3216
|
+
renderVideo(false),
|
|
3217
|
+
isSmallVideo ? /* @__PURE__ */ jsxs4(YaTooltip, { anchorRef: containerRef, show: isHovered && !isSelected, children: [
|
|
3218
|
+
videoIcon,
|
|
3219
|
+
/* @__PURE__ */ jsx8("span", { children: "Click to edit" })
|
|
3220
|
+
] }) : (
|
|
3221
|
+
/* For large videos: show overlay inside the container */
|
|
3222
|
+
/* @__PURE__ */ jsxs4("div", { className: "ya-video-overlay", children: [
|
|
3223
|
+
/* @__PURE__ */ jsx8("div", { className: "ya-video-edit-icon", children: videoIcon }),
|
|
3224
|
+
/* @__PURE__ */ jsx8("span", { className: "ya-video-edit-label", children: "Click to edit" })
|
|
3225
|
+
] })
|
|
3226
|
+
)
|
|
3227
|
+
]
|
|
3228
|
+
}
|
|
3229
|
+
);
|
|
3230
|
+
}
|
|
3231
|
+
|
|
2754
3232
|
// src/components/YaLink.tsx
|
|
2755
|
-
import { useEffect as
|
|
2756
|
-
import { createPortal as
|
|
3233
|
+
import { useEffect as useEffect10, useRef as useRef10, useState as useState10, useCallback as useCallback10 } from "react";
|
|
3234
|
+
import { createPortal as createPortal5 } from "react-dom";
|
|
2757
3235
|
import { useEditor as useEditor2, EditorContent as EditorContent2 } from "@tiptap/react";
|
|
2758
3236
|
import { BubbleMenu as BubbleMenu2 } from "@tiptap/react/menus";
|
|
2759
3237
|
import StarterKit2 from "@tiptap/starter-kit";
|
|
@@ -2761,11 +3239,169 @@ import { TextStyle as TextStyle2 } from "@tiptap/extension-text-style";
|
|
|
2761
3239
|
import { Extension as Extension2 } from "@tiptap/core";
|
|
2762
3240
|
import { Link as WouterLink, useLocation } from "wouter";
|
|
2763
3241
|
|
|
3242
|
+
// src/components/SafeTriangleBelow.tsx
|
|
3243
|
+
import { useEffect as useEffect8, useState as useState8 } from "react";
|
|
3244
|
+
import { createPortal as createPortal4 } from "react-dom";
|
|
3245
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
3246
|
+
function SafeTriangleBelow({
|
|
3247
|
+
triggerRef,
|
|
3248
|
+
popoverRef,
|
|
3249
|
+
isVisible,
|
|
3250
|
+
onLeave
|
|
3251
|
+
}) {
|
|
3252
|
+
const [mousePos, setMousePos] = useState8({ x: 0, y: 0 });
|
|
3253
|
+
const [mounted, setMounted] = useState8(false);
|
|
3254
|
+
useEffect8(() => {
|
|
3255
|
+
setMounted(true);
|
|
3256
|
+
}, []);
|
|
3257
|
+
useEffect8(() => {
|
|
3258
|
+
if (!isVisible) return;
|
|
3259
|
+
const handleMouseMove = (e) => {
|
|
3260
|
+
setMousePos({ x: e.clientX, y: e.clientY });
|
|
3261
|
+
};
|
|
3262
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
3263
|
+
return () => document.removeEventListener("mousemove", handleMouseMove);
|
|
3264
|
+
}, [isVisible]);
|
|
3265
|
+
if (!mounted || !isVisible || !triggerRef.current || !popoverRef.current) {
|
|
3266
|
+
return null;
|
|
3267
|
+
}
|
|
3268
|
+
const popoverRect = popoverRef.current.getBoundingClientRect();
|
|
3269
|
+
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
3270
|
+
if (mousePos.y >= popoverRect.top) {
|
|
3271
|
+
return null;
|
|
3272
|
+
}
|
|
3273
|
+
const leftBound = Math.min(triggerRect.left, popoverRect.left) - 20;
|
|
3274
|
+
const rightBound = Math.max(triggerRect.right, popoverRect.right) + 20;
|
|
3275
|
+
if (mousePos.x < leftBound || mousePos.x > rightBound) {
|
|
3276
|
+
return null;
|
|
3277
|
+
}
|
|
3278
|
+
const svgTop = mousePos.y;
|
|
3279
|
+
const svgHeight = Math.max(popoverRect.top - mousePos.y, 1);
|
|
3280
|
+
const svgLeft = Math.min(mousePos.x, popoverRect.left);
|
|
3281
|
+
const svgWidth = Math.max(popoverRect.right - svgLeft, mousePos.x - svgLeft, 1);
|
|
3282
|
+
const cursorX = mousePos.x - svgLeft;
|
|
3283
|
+
const popoverLeftX = popoverRect.left - svgLeft;
|
|
3284
|
+
const popoverRightX = popoverRect.right - svgLeft;
|
|
3285
|
+
const path = `M ${cursorX},0 L ${popoverLeftX},${svgHeight} L ${popoverRightX},${svgHeight} z`;
|
|
3286
|
+
return createPortal4(
|
|
3287
|
+
/* @__PURE__ */ jsx9(
|
|
3288
|
+
"svg",
|
|
3289
|
+
{
|
|
3290
|
+
style: {
|
|
3291
|
+
position: "fixed",
|
|
3292
|
+
width: svgWidth,
|
|
3293
|
+
height: svgHeight,
|
|
3294
|
+
top: svgTop,
|
|
3295
|
+
left: svgLeft,
|
|
3296
|
+
pointerEvents: "none",
|
|
3297
|
+
zIndex: 9998
|
|
3298
|
+
},
|
|
3299
|
+
children: /* @__PURE__ */ jsx9(
|
|
3300
|
+
"path",
|
|
3301
|
+
{
|
|
3302
|
+
d: path,
|
|
3303
|
+
fill: "transparent",
|
|
3304
|
+
style: { pointerEvents: "auto" },
|
|
3305
|
+
onMouseLeave: onLeave
|
|
3306
|
+
}
|
|
3307
|
+
)
|
|
3308
|
+
}
|
|
3309
|
+
),
|
|
3310
|
+
document.body
|
|
3311
|
+
);
|
|
3312
|
+
}
|
|
3313
|
+
|
|
3314
|
+
// src/hooks/useSafeTriangle.ts
|
|
3315
|
+
import { useState as useState9, useRef as useRef9, useCallback as useCallback9, useEffect as useEffect9 } from "react";
|
|
3316
|
+
function useSafeTriangle(options = {}) {
|
|
3317
|
+
const { showDelay = 0, hideDelay = 150, enabled = true } = options;
|
|
3318
|
+
const [isVisible, setIsVisible] = useState9(false);
|
|
3319
|
+
const [isHovering, setIsHovering] = useState9(false);
|
|
3320
|
+
const triggerRef = useRef9(null);
|
|
3321
|
+
const popoverRef = useRef9(null);
|
|
3322
|
+
const showTimeoutRef = useRef9(null);
|
|
3323
|
+
const hideTimeoutRef = useRef9(null);
|
|
3324
|
+
useEffect9(() => {
|
|
3325
|
+
return () => {
|
|
3326
|
+
if (showTimeoutRef.current) clearTimeout(showTimeoutRef.current);
|
|
3327
|
+
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
|
3328
|
+
};
|
|
3329
|
+
}, []);
|
|
3330
|
+
const show = useCallback9(() => {
|
|
3331
|
+
if (!enabled) return;
|
|
3332
|
+
if (hideTimeoutRef.current) {
|
|
3333
|
+
clearTimeout(hideTimeoutRef.current);
|
|
3334
|
+
hideTimeoutRef.current = null;
|
|
3335
|
+
}
|
|
3336
|
+
setIsVisible(true);
|
|
3337
|
+
}, [enabled]);
|
|
3338
|
+
const hide = useCallback9(() => {
|
|
3339
|
+
if (showTimeoutRef.current) {
|
|
3340
|
+
clearTimeout(showTimeoutRef.current);
|
|
3341
|
+
showTimeoutRef.current = null;
|
|
3342
|
+
}
|
|
3343
|
+
setIsVisible(false);
|
|
3344
|
+
setIsHovering(false);
|
|
3345
|
+
}, []);
|
|
3346
|
+
const handleMouseEnter = useCallback9(() => {
|
|
3347
|
+
if (!enabled) return;
|
|
3348
|
+
setIsHovering(true);
|
|
3349
|
+
if (hideTimeoutRef.current) {
|
|
3350
|
+
clearTimeout(hideTimeoutRef.current);
|
|
3351
|
+
hideTimeoutRef.current = null;
|
|
3352
|
+
}
|
|
3353
|
+
if (showDelay > 0) {
|
|
3354
|
+
showTimeoutRef.current = setTimeout(() => {
|
|
3355
|
+
setIsVisible(true);
|
|
3356
|
+
}, showDelay);
|
|
3357
|
+
} else {
|
|
3358
|
+
setIsVisible(true);
|
|
3359
|
+
}
|
|
3360
|
+
}, [showDelay, enabled]);
|
|
3361
|
+
const handleMouseLeave = useCallback9(() => {
|
|
3362
|
+
setIsHovering(false);
|
|
3363
|
+
if (showTimeoutRef.current) {
|
|
3364
|
+
clearTimeout(showTimeoutRef.current);
|
|
3365
|
+
showTimeoutRef.current = null;
|
|
3366
|
+
}
|
|
3367
|
+
hideTimeoutRef.current = setTimeout(() => {
|
|
3368
|
+
setIsVisible(false);
|
|
3369
|
+
}, hideDelay);
|
|
3370
|
+
}, [hideDelay]);
|
|
3371
|
+
const handleFocus = useCallback9(() => {
|
|
3372
|
+
if (!enabled) return;
|
|
3373
|
+
setIsVisible(true);
|
|
3374
|
+
}, [enabled]);
|
|
3375
|
+
const handleTriangleLeave = useCallback9(() => {
|
|
3376
|
+
if (!isHovering) {
|
|
3377
|
+
setIsVisible(false);
|
|
3378
|
+
}
|
|
3379
|
+
}, [isHovering]);
|
|
3380
|
+
return {
|
|
3381
|
+
triggerRef,
|
|
3382
|
+
popoverRef,
|
|
3383
|
+
isVisible,
|
|
3384
|
+
handlers: {
|
|
3385
|
+
onMouseEnter: handleMouseEnter,
|
|
3386
|
+
onMouseLeave: handleMouseLeave,
|
|
3387
|
+
onFocus: handleFocus
|
|
3388
|
+
},
|
|
3389
|
+
triangleProps: {
|
|
3390
|
+
triggerRef,
|
|
3391
|
+
popoverRef,
|
|
3392
|
+
isVisible,
|
|
3393
|
+
onLeave: handleTriangleLeave
|
|
3394
|
+
},
|
|
3395
|
+
show,
|
|
3396
|
+
hide
|
|
3397
|
+
};
|
|
3398
|
+
}
|
|
3399
|
+
|
|
2764
3400
|
// src/components/ya-link.css
|
|
2765
3401
|
styleInject('.ya-link-wrapper {\n position: relative;\n display: inline;\n}\n.ya-link-editable {\n cursor: pointer;\n transition: outline 0.15s ease;\n}\n.ya-link-editable:hover {\n outline: 2px dashed var(--color-primary, #D4A574);\n outline-offset: 4px;\n border-radius: 4px;\n}\nbody.builder-selector-active .ya-link-editable:hover {\n outline: none;\n cursor: inherit;\n}\n.ya-link-editing {\n outline: 2px solid var(--color-primary, #D4A574);\n outline-offset: 4px;\n border-radius: 4px;\n position: relative;\n}\n.ya-link-actions {\n display: flex;\n gap: 8px;\n position: absolute;\n bottom: -60px;\n right: 0;\n z-index: 10;\n background: rgba(26, 26, 26, 0.95);\n padding: 8px 10px;\n border-radius: 8px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n font-family:\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n}\n.ya-link-btn {\n padding: 6px 14px;\n font-size: 12px;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.15s ease;\n border: none;\n}\n.ya-link-btn-cancel {\n background: #333333;\n color: #ffffff;\n border: 1px solid #555555;\n}\n.ya-link-btn-cancel:hover {\n background: #444444;\n color: #ffffff;\n border-color: #666666;\n}\n.ya-link-btn-save {\n background: #D4A574;\n color: #1a1a1a;\n}\n.ya-link-btn-save:hover {\n background: #c4956a;\n}\n.ya-href-popover {\n position: absolute;\n top: 100%;\n left: 50%;\n margin-top: 8px;\n z-index: 10;\n min-width: 280px;\n max-width: 320px;\n background: #1a1a1a;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);\n transform: translateX(-50%);\n animation: ya-href-popover-fade-in 0.15s ease;\n overflow: hidden;\n font-family:\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n}\n@keyframes ya-href-popover-fade-in {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n}\n.ya-href-popover::before {\n content: "";\n position: absolute;\n top: -6px;\n left: 50%;\n transform: translateX(-50%);\n border-left: 8px solid transparent;\n border-right: 8px solid transparent;\n border-bottom: 8px solid #1a1a1a;\n}\n.ya-href-popover-header {\n padding: 12px 16px;\n font-size: 13px;\n font-weight: 600;\n color: #ffffff;\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n.ya-href-popover-section {\n padding: 12px 16px;\n}\n.ya-href-popover-label {\n display: block;\n font-size: 11px;\n font-weight: 500;\n color: rgba(255, 255, 255, 0.6);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n}\n.ya-href-collapsible-header {\n display: flex;\n align-items: center;\n gap: 6px;\n width: 100%;\n padding: 0;\n background: transparent;\n border: none;\n cursor: pointer;\n transition: color 0.15s ease;\n}\n.ya-href-collapsible-header:hover {\n color: rgba(255, 255, 255, 0.8);\n}\n.ya-href-chevron {\n font-size: 8px;\n color: rgba(255, 255, 255, 0.4);\n}\n.ya-href-popover-pages {\n display: flex;\n flex-direction: column;\n gap: 4px;\n max-height: 200px;\n overflow-y: auto;\n}\n.ya-href-page-btn {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 4px;\n width: 100%;\n padding: 10px 12px;\n background: rgba(255, 255, 255, 0.05);\n border: 1px solid transparent;\n border-radius: 8px;\n color: #e0e0e0;\n font-size: 13px;\n font-weight: 500;\n text-align: left;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n.ya-href-page-btn:hover {\n background: rgba(255, 255, 255, 0.1);\n border-color: rgba(255, 255, 255, 0.2);\n}\n.ya-href-page-btn.is-selected {\n background: #D4A574;\n color: #1a1a1a;\n}\n.ya-href-page-btn.is-selected .ya-href-page-path {\n color: rgba(26, 26, 26, 0.6);\n}\n.ya-href-page-path {\n font-size: 11px;\n color: rgba(255, 255, 255, 0.4);\n font-family: monospace;\n word-break: break-all;\n}\n.ya-href-external-toggle {\n display: block;\n width: 100%;\n padding: 10px 16px;\n background: transparent;\n border: none;\n border-top: 1px solid rgba(255, 255, 255, 0.1);\n color: #D4A574;\n font-size: 12px;\n font-weight: 500;\n text-align: center;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n.ya-href-external-toggle:hover {\n background: rgba(255, 255, 255, 0.05);\n}\n.ya-href-url-input {\n width: 100%;\n padding: 10px 12px;\n background: rgba(255, 255, 255, 0.05);\n border: 1px solid rgba(255, 255, 255, 0.2);\n border-radius: 8px;\n color: #ffffff;\n font-size: 13px;\n outline: none;\n transition: border-color 0.15s ease;\n}\n.ya-href-url-input::placeholder {\n color: rgba(255, 255, 255, 0.4);\n}\n.ya-href-url-input:focus {\n border-color: var(--color-primary, #D4A574);\n}\n.ya-href-popover-actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 12px 16px;\n border-top: 1px solid rgba(255, 255, 255, 0.1);\n}\n.ya-link-edit-popover {\n position: absolute;\n top: 100%;\n left: 50%;\n margin-top: 8px;\n z-index: 10;\n background: #2a2a2a;\n border-radius: 6px;\n padding: 4px;\n display: flex;\n gap: 4px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\n transform: translateX(-50%);\n animation: ya-edit-popover-fade-in 0.1s ease;\n font-family:\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n white-space: nowrap;\n}\n@keyframes ya-edit-popover-fade-in {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-4px);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n }\n}\n.ya-link-edit-popover::before {\n content: "";\n position: absolute;\n top: -5px;\n left: 50%;\n transform: translateX(-50%);\n border-left: 6px solid transparent;\n border-right: 6px solid transparent;\n border-bottom: 6px solid #2a2a2a;\n}\n.ya-link-edit-popover button {\n background: #3a3a3a;\n border: none;\n color: #fff;\n padding: 6px 12px;\n border-radius: 4px;\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n transition: background 0.15s ease;\n}\n.ya-link-edit-popover button:hover {\n background: #4a4a4a;\n}\n');
|
|
2766
3402
|
|
|
2767
3403
|
// src/components/YaLink.tsx
|
|
2768
|
-
import { Fragment as Fragment3, jsx as
|
|
3404
|
+
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2769
3405
|
function isInternalPath(path) {
|
|
2770
3406
|
if (!path) return false;
|
|
2771
3407
|
if (path.startsWith("#")) return false;
|
|
@@ -2866,8 +3502,8 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
2866
3502
|
const { getValue, setValue, mode, saveToWorker, getPages } = useContentStore();
|
|
2867
3503
|
const [, navigate] = useLocation();
|
|
2868
3504
|
const pages = availablePages ?? getPages();
|
|
2869
|
-
const [sections, setSections] =
|
|
2870
|
-
const [sectionsExpanded, setSectionsExpanded] =
|
|
3505
|
+
const [sections, setSections] = useState10([]);
|
|
3506
|
+
const [sectionsExpanded, setSectionsExpanded] = useState10(false);
|
|
2871
3507
|
const textFieldId = `${fieldId}.text`;
|
|
2872
3508
|
const hrefFieldId = `${fieldId}.href`;
|
|
2873
3509
|
const storeText = getValue(textFieldId);
|
|
@@ -2878,16 +3514,25 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
2878
3514
|
const isExternal = isExternalHref(href);
|
|
2879
3515
|
const effectiveTarget = target ?? (isExternal ? "_blank" : void 0);
|
|
2880
3516
|
const effectiveRel = rel ?? (isExternal ? "noopener noreferrer" : void 0);
|
|
2881
|
-
const [editingMode, setEditingMode] =
|
|
2882
|
-
const [
|
|
2883
|
-
const [
|
|
2884
|
-
const [
|
|
2885
|
-
const [
|
|
2886
|
-
const [
|
|
2887
|
-
const
|
|
2888
|
-
const
|
|
2889
|
-
const
|
|
2890
|
-
|
|
3517
|
+
const [editingMode, setEditingMode] = useState10(null);
|
|
3518
|
+
const [originalText, setOriginalText] = useState10(text);
|
|
3519
|
+
const [originalHref, setOriginalHref] = useState10(href);
|
|
3520
|
+
const [currentHref, setCurrentHref] = useState10(href);
|
|
3521
|
+
const [isExternalUrl, setIsExternalUrl] = useState10(false);
|
|
3522
|
+
const [externalUrl, setExternalUrl] = useState10("");
|
|
3523
|
+
const containerRef = useRef10(null);
|
|
3524
|
+
const hrefPopoverRef = useRef10(null);
|
|
3525
|
+
const {
|
|
3526
|
+
popoverRef: editPopoverRef,
|
|
3527
|
+
isVisible: showEditPopover,
|
|
3528
|
+
handlers: safeTriangleHandlers,
|
|
3529
|
+
triangleProps,
|
|
3530
|
+
hide: hideEditPopover
|
|
3531
|
+
} = useSafeTriangle({
|
|
3532
|
+
enabled: mode === "inline-edit" && !editingMode,
|
|
3533
|
+
hideDelay: 150
|
|
3534
|
+
});
|
|
3535
|
+
const triggerRef = containerRef;
|
|
2891
3536
|
const editor = useEditor2({
|
|
2892
3537
|
extensions: [
|
|
2893
3538
|
StarterKit2.configure({
|
|
@@ -2910,26 +3555,19 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
2910
3555
|
}
|
|
2911
3556
|
}
|
|
2912
3557
|
});
|
|
2913
|
-
|
|
3558
|
+
useEffect10(() => {
|
|
2914
3559
|
if (editor && editingMode !== "text") {
|
|
2915
3560
|
if (editor.getHTML() !== text) {
|
|
2916
3561
|
editor.commands.setContent(text);
|
|
2917
3562
|
}
|
|
2918
3563
|
}
|
|
2919
3564
|
}, [text, editor, editingMode]);
|
|
2920
|
-
|
|
3565
|
+
useEffect10(() => {
|
|
2921
3566
|
if (editingMode !== "link") {
|
|
2922
3567
|
setCurrentHref(href);
|
|
2923
3568
|
}
|
|
2924
3569
|
}, [href, editingMode]);
|
|
2925
|
-
|
|
2926
|
-
return () => {
|
|
2927
|
-
if (hidePopoverTimeoutRef.current) {
|
|
2928
|
-
clearTimeout(hidePopoverTimeoutRef.current);
|
|
2929
|
-
}
|
|
2930
|
-
};
|
|
2931
|
-
}, []);
|
|
2932
|
-
useEffect7(() => {
|
|
3570
|
+
useEffect10(() => {
|
|
2933
3571
|
if (editingMode !== "link") return;
|
|
2934
3572
|
const handleClickOutside = (event) => {
|
|
2935
3573
|
const target2 = event.target;
|
|
@@ -2943,7 +3581,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
2943
3581
|
document.addEventListener("mousedown", handleClickOutside);
|
|
2944
3582
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2945
3583
|
}, [editingMode, originalHref]);
|
|
2946
|
-
const handleSaveText =
|
|
3584
|
+
const handleSaveText = useCallback10(() => {
|
|
2947
3585
|
if (!editor) return;
|
|
2948
3586
|
let html = editor.getHTML();
|
|
2949
3587
|
html = html.replace(/<\/p><p>/g, "<br><br>").replace(/^<p>/, "").replace(/<\/p>$/, "");
|
|
@@ -2951,26 +3589,26 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
2951
3589
|
saveToWorker?.(textFieldId, html);
|
|
2952
3590
|
setEditingMode(null);
|
|
2953
3591
|
}, [editor, textFieldId, setValue, saveToWorker]);
|
|
2954
|
-
const handleSaveLink =
|
|
3592
|
+
const handleSaveLink = useCallback10(() => {
|
|
2955
3593
|
setValue(hrefFieldId, currentHref);
|
|
2956
3594
|
saveToWorker?.(hrefFieldId, currentHref);
|
|
2957
3595
|
setEditingMode(null);
|
|
2958
3596
|
setIsExternalUrl(false);
|
|
2959
3597
|
setExternalUrl("");
|
|
2960
3598
|
}, [hrefFieldId, currentHref, setValue, saveToWorker]);
|
|
2961
|
-
const handleCancelText =
|
|
3599
|
+
const handleCancelText = useCallback10(() => {
|
|
2962
3600
|
if (editor) {
|
|
2963
3601
|
editor.commands.setContent(originalText);
|
|
2964
3602
|
}
|
|
2965
3603
|
setEditingMode(null);
|
|
2966
3604
|
}, [editor, originalText]);
|
|
2967
|
-
const handleCancelLink =
|
|
3605
|
+
const handleCancelLink = useCallback10(() => {
|
|
2968
3606
|
setCurrentHref(originalHref);
|
|
2969
3607
|
setEditingMode(null);
|
|
2970
3608
|
setIsExternalUrl(false);
|
|
2971
3609
|
setExternalUrl("");
|
|
2972
3610
|
}, [originalHref]);
|
|
2973
|
-
const handleClick =
|
|
3611
|
+
const handleClick = useCallback10(
|
|
2974
3612
|
(e) => {
|
|
2975
3613
|
const selectModeEnabled = window.__builderSelectModeEnabled;
|
|
2976
3614
|
if (selectModeEnabled) {
|
|
@@ -3002,43 +3640,22 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3002
3640
|
},
|
|
3003
3641
|
[href, navigate, onClick]
|
|
3004
3642
|
);
|
|
3005
|
-
const
|
|
3006
|
-
|
|
3007
|
-
clearTimeout(hidePopoverTimeoutRef.current);
|
|
3008
|
-
hidePopoverTimeoutRef.current = null;
|
|
3009
|
-
}
|
|
3010
|
-
if (mode === "inline-edit" && !editingMode) {
|
|
3011
|
-
setShowEditPopover(true);
|
|
3012
|
-
}
|
|
3013
|
-
}, [mode, editingMode]);
|
|
3014
|
-
const handleMouseLeave = useCallback8(() => {
|
|
3015
|
-
hidePopoverTimeoutRef.current = window.setTimeout(() => {
|
|
3016
|
-
if (!editingMode) {
|
|
3017
|
-
setShowEditPopover(false);
|
|
3018
|
-
}
|
|
3019
|
-
}, 150);
|
|
3020
|
-
}, [editingMode]);
|
|
3021
|
-
const handleFocus = useCallback8(() => {
|
|
3022
|
-
if (mode === "inline-edit" && !editingMode) {
|
|
3023
|
-
setShowEditPopover(true);
|
|
3024
|
-
}
|
|
3025
|
-
}, [mode, editingMode]);
|
|
3026
|
-
const startEditText = useCallback8(() => {
|
|
3027
|
-
setShowEditPopover(false);
|
|
3643
|
+
const startEditText = useCallback10(() => {
|
|
3644
|
+
hideEditPopover();
|
|
3028
3645
|
setEditingMode("text");
|
|
3029
3646
|
setOriginalText(text);
|
|
3030
3647
|
setTimeout(() => {
|
|
3031
3648
|
editor?.chain().focus().selectAll().run();
|
|
3032
3649
|
}, 20);
|
|
3033
|
-
}, [text, editor]);
|
|
3034
|
-
const startEditLink =
|
|
3035
|
-
|
|
3650
|
+
}, [text, editor, hideEditPopover]);
|
|
3651
|
+
const startEditLink = useCallback10(() => {
|
|
3652
|
+
hideEditPopover();
|
|
3036
3653
|
setEditingMode("link");
|
|
3037
3654
|
setOriginalHref(href);
|
|
3038
3655
|
setCurrentHref(href);
|
|
3039
3656
|
setSections(discoverSectionsFromDOM());
|
|
3040
|
-
}, [href]);
|
|
3041
|
-
const handleKeyDown =
|
|
3657
|
+
}, [href, hideEditPopover]);
|
|
3658
|
+
const handleKeyDown = useCallback10(
|
|
3042
3659
|
(event) => {
|
|
3043
3660
|
if (editingMode !== "text") return;
|
|
3044
3661
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
@@ -3059,7 +3676,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3059
3676
|
},
|
|
3060
3677
|
[editingMode, handleSaveText, handleCancelText]
|
|
3061
3678
|
);
|
|
3062
|
-
const handleFontSizeChange =
|
|
3679
|
+
const handleFontSizeChange = useCallback10(
|
|
3063
3680
|
(e) => {
|
|
3064
3681
|
if (!editor) return;
|
|
3065
3682
|
const size = e.target.value;
|
|
@@ -3071,7 +3688,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3071
3688
|
},
|
|
3072
3689
|
[editor]
|
|
3073
3690
|
);
|
|
3074
|
-
const handleFontWeightChange =
|
|
3691
|
+
const handleFontWeightChange = useCallback10(
|
|
3075
3692
|
(e) => {
|
|
3076
3693
|
if (!editor) return;
|
|
3077
3694
|
const weight = e.target.value;
|
|
@@ -3083,11 +3700,11 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3083
3700
|
},
|
|
3084
3701
|
[editor]
|
|
3085
3702
|
);
|
|
3086
|
-
const handlePageSelect =
|
|
3703
|
+
const handlePageSelect = useCallback10((path) => {
|
|
3087
3704
|
setCurrentHref(path);
|
|
3088
3705
|
setIsExternalUrl(false);
|
|
3089
3706
|
}, []);
|
|
3090
|
-
const handleExternalUrlApply =
|
|
3707
|
+
const handleExternalUrlApply = useCallback10(() => {
|
|
3091
3708
|
if (externalUrl) {
|
|
3092
3709
|
setCurrentHref(externalUrl);
|
|
3093
3710
|
}
|
|
@@ -3103,9 +3720,9 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3103
3720
|
return attrs.fontWeight || "";
|
|
3104
3721
|
};
|
|
3105
3722
|
if (mode === "read-only") {
|
|
3106
|
-
const content = isIconMode ? children : /* @__PURE__ */
|
|
3723
|
+
const content = isIconMode ? children : /* @__PURE__ */ jsx10(SafeHtml, { content: text, mode });
|
|
3107
3724
|
if (isInternalPath(href)) {
|
|
3108
|
-
return /* @__PURE__ */
|
|
3725
|
+
return /* @__PURE__ */ jsx10(
|
|
3109
3726
|
WouterLink,
|
|
3110
3727
|
{
|
|
3111
3728
|
href,
|
|
@@ -3117,7 +3734,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3117
3734
|
}
|
|
3118
3735
|
);
|
|
3119
3736
|
}
|
|
3120
|
-
return /* @__PURE__ */
|
|
3737
|
+
return /* @__PURE__ */ jsx10(
|
|
3121
3738
|
Component,
|
|
3122
3739
|
{
|
|
3123
3740
|
ref: containerRef,
|
|
@@ -3132,8 +3749,8 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3132
3749
|
}
|
|
3133
3750
|
);
|
|
3134
3751
|
}
|
|
3135
|
-
return /* @__PURE__ */
|
|
3136
|
-
/* @__PURE__ */
|
|
3752
|
+
return /* @__PURE__ */ jsxs5("span", { className: "ya-link-wrapper", children: [
|
|
3753
|
+
/* @__PURE__ */ jsx10(
|
|
3137
3754
|
Component,
|
|
3138
3755
|
{
|
|
3139
3756
|
ref: containerRef,
|
|
@@ -3145,16 +3762,16 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3145
3762
|
"data-ya-restricted": "true",
|
|
3146
3763
|
"data-field-id": fieldId,
|
|
3147
3764
|
onClick: handleClick,
|
|
3148
|
-
onMouseEnter:
|
|
3149
|
-
onMouseLeave:
|
|
3150
|
-
onFocus:
|
|
3765
|
+
onMouseEnter: safeTriangleHandlers.onMouseEnter,
|
|
3766
|
+
onMouseLeave: safeTriangleHandlers.onMouseLeave,
|
|
3767
|
+
onFocus: safeTriangleHandlers.onFocus,
|
|
3151
3768
|
onKeyDown: handleKeyDown,
|
|
3152
3769
|
children: isIconMode ? (
|
|
3153
3770
|
// Icon mode: render children directly, no text editing
|
|
3154
3771
|
children
|
|
3155
|
-
) : editor ? /* @__PURE__ */
|
|
3156
|
-
|
|
3157
|
-
/* @__PURE__ */
|
|
3772
|
+
) : editor ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3773
|
+
createPortal5(
|
|
3774
|
+
/* @__PURE__ */ jsxs5(
|
|
3158
3775
|
BubbleMenu2,
|
|
3159
3776
|
{
|
|
3160
3777
|
editor,
|
|
@@ -3162,28 +3779,28 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3162
3779
|
options: { offset: 6, placement: "top" },
|
|
3163
3780
|
className: "ya-bubble-menu",
|
|
3164
3781
|
children: [
|
|
3165
|
-
/* @__PURE__ */
|
|
3782
|
+
/* @__PURE__ */ jsx10(
|
|
3166
3783
|
"button",
|
|
3167
3784
|
{
|
|
3168
3785
|
type: "button",
|
|
3169
3786
|
onClick: () => editor.chain().focus().toggleBold().run(),
|
|
3170
3787
|
className: `ya-bubble-btn ${editor.isActive("bold") ? "is-active" : ""}`,
|
|
3171
3788
|
title: "Bold",
|
|
3172
|
-
children: /* @__PURE__ */
|
|
3789
|
+
children: /* @__PURE__ */ jsx10("strong", { children: "B" })
|
|
3173
3790
|
}
|
|
3174
3791
|
),
|
|
3175
|
-
/* @__PURE__ */
|
|
3792
|
+
/* @__PURE__ */ jsx10(
|
|
3176
3793
|
"button",
|
|
3177
3794
|
{
|
|
3178
3795
|
type: "button",
|
|
3179
3796
|
onClick: () => editor.chain().focus().toggleItalic().run(),
|
|
3180
3797
|
className: `ya-bubble-btn ${editor.isActive("italic") ? "is-active" : ""}`,
|
|
3181
3798
|
title: "Italic",
|
|
3182
|
-
children: /* @__PURE__ */
|
|
3799
|
+
children: /* @__PURE__ */ jsx10("em", { children: "I" })
|
|
3183
3800
|
}
|
|
3184
3801
|
),
|
|
3185
|
-
/* @__PURE__ */
|
|
3186
|
-
/* @__PURE__ */
|
|
3802
|
+
/* @__PURE__ */ jsx10("span", { className: "ya-bubble-divider" }),
|
|
3803
|
+
/* @__PURE__ */ jsxs5(
|
|
3187
3804
|
"select",
|
|
3188
3805
|
{
|
|
3189
3806
|
value: getCurrentFontSize(),
|
|
@@ -3191,12 +3808,12 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3191
3808
|
className: "ya-bubble-select",
|
|
3192
3809
|
title: "Font Size",
|
|
3193
3810
|
children: [
|
|
3194
|
-
/* @__PURE__ */
|
|
3195
|
-
Object.entries(SIZE_PRESETS2).map(([name, size]) => /* @__PURE__ */
|
|
3811
|
+
/* @__PURE__ */ jsx10("option", { value: "", children: "Size" }),
|
|
3812
|
+
Object.entries(SIZE_PRESETS2).map(([name, size]) => /* @__PURE__ */ jsx10("option", { value: size, children: name }, name))
|
|
3196
3813
|
]
|
|
3197
3814
|
}
|
|
3198
3815
|
),
|
|
3199
|
-
/* @__PURE__ */
|
|
3816
|
+
/* @__PURE__ */ jsxs5(
|
|
3200
3817
|
"select",
|
|
3201
3818
|
{
|
|
3202
3819
|
value: getCurrentFontWeight(),
|
|
@@ -3204,8 +3821,8 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3204
3821
|
className: "ya-bubble-select",
|
|
3205
3822
|
title: "Font Weight",
|
|
3206
3823
|
children: [
|
|
3207
|
-
/* @__PURE__ */
|
|
3208
|
-
Object.entries(WEIGHT_PRESETS2).map(([name, weight]) => /* @__PURE__ */
|
|
3824
|
+
/* @__PURE__ */ jsx10("option", { value: "", children: "Weight" }),
|
|
3825
|
+
Object.entries(WEIGHT_PRESETS2).map(([name, weight]) => /* @__PURE__ */ jsx10("option", { value: weight, children: name }, name))
|
|
3209
3826
|
]
|
|
3210
3827
|
}
|
|
3211
3828
|
)
|
|
@@ -3214,39 +3831,57 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3214
3831
|
),
|
|
3215
3832
|
document.body
|
|
3216
3833
|
),
|
|
3217
|
-
editingMode === "text" ? /* @__PURE__ */
|
|
3218
|
-
/* @__PURE__ */
|
|
3219
|
-
/* @__PURE__ */
|
|
3220
|
-
/* @__PURE__ */
|
|
3221
|
-
/* @__PURE__ */
|
|
3834
|
+
editingMode === "text" ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3835
|
+
/* @__PURE__ */ jsx10(EditorContent2, { editor }),
|
|
3836
|
+
/* @__PURE__ */ jsxs5("div", { className: "ya-link-actions", children: [
|
|
3837
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: handleCancelText, className: "ya-link-btn ya-link-btn-cancel", children: "Cancel" }),
|
|
3838
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: handleSaveText, className: "ya-link-btn ya-link-btn-save", children: "Save" })
|
|
3222
3839
|
] })
|
|
3223
|
-
] }) : /* @__PURE__ */
|
|
3224
|
-
] }) : /* @__PURE__ */
|
|
3840
|
+
] }) : /* @__PURE__ */ jsx10(SafeHtml, { content: text, mode })
|
|
3841
|
+
] }) : /* @__PURE__ */ jsx10(SafeHtml, { content: text, mode })
|
|
3842
|
+
}
|
|
3843
|
+
),
|
|
3844
|
+
showEditPopover && !editingMode && mode === "inline-edit" && /* @__PURE__ */ jsxs5(
|
|
3845
|
+
"div",
|
|
3846
|
+
{
|
|
3847
|
+
ref: editPopoverRef,
|
|
3848
|
+
className: "ya-link-edit-popover",
|
|
3849
|
+
onMouseEnter: safeTriangleHandlers.onMouseEnter,
|
|
3850
|
+
onMouseLeave: safeTriangleHandlers.onMouseLeave,
|
|
3851
|
+
children: [
|
|
3852
|
+
!isIconMode && /* @__PURE__ */ jsx10("button", { type: "button", onClick: startEditText, children: "Edit text" }),
|
|
3853
|
+
/* @__PURE__ */ jsx10("button", { type: "button", onClick: startEditLink, children: "Edit link" })
|
|
3854
|
+
]
|
|
3855
|
+
}
|
|
3856
|
+
),
|
|
3857
|
+
/* @__PURE__ */ jsx10(
|
|
3858
|
+
SafeTriangleBelow,
|
|
3859
|
+
{
|
|
3860
|
+
triggerRef,
|
|
3861
|
+
popoverRef: editPopoverRef,
|
|
3862
|
+
isVisible: showEditPopover && !editingMode && mode === "inline-edit",
|
|
3863
|
+
onLeave: triangleProps.onLeave
|
|
3225
3864
|
}
|
|
3226
3865
|
),
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
/* @__PURE__ */
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
/* @__PURE__ */ jsx8("div", { className: "ya-href-popover-header", children: "Link destination" }),
|
|
3233
|
-
!isExternalUrl ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
3234
|
-
sections.length > 0 && /* @__PURE__ */ jsxs4("div", { className: "ya-href-popover-section", children: [
|
|
3235
|
-
/* @__PURE__ */ jsxs4(
|
|
3866
|
+
editingMode === "link" && /* @__PURE__ */ jsxs5("div", { ref: hrefPopoverRef, className: "ya-href-popover", children: [
|
|
3867
|
+
/* @__PURE__ */ jsx10("div", { className: "ya-href-popover-header", children: "Link destination" }),
|
|
3868
|
+
!isExternalUrl ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3869
|
+
sections.length > 0 && /* @__PURE__ */ jsxs5("div", { className: "ya-href-popover-section", children: [
|
|
3870
|
+
/* @__PURE__ */ jsxs5(
|
|
3236
3871
|
"button",
|
|
3237
3872
|
{
|
|
3238
3873
|
type: "button",
|
|
3239
3874
|
className: "ya-href-popover-label ya-href-collapsible-header",
|
|
3240
3875
|
onClick: () => setSectionsExpanded(!sectionsExpanded),
|
|
3241
3876
|
children: [
|
|
3242
|
-
/* @__PURE__ */
|
|
3877
|
+
/* @__PURE__ */ jsx10("span", { className: "ya-href-chevron", children: sectionsExpanded ? "\u25BC" : "\u25B6" }),
|
|
3243
3878
|
"Scroll to section (",
|
|
3244
3879
|
sections.length,
|
|
3245
3880
|
")"
|
|
3246
3881
|
]
|
|
3247
3882
|
}
|
|
3248
3883
|
),
|
|
3249
|
-
sectionsExpanded && /* @__PURE__ */
|
|
3884
|
+
sectionsExpanded && /* @__PURE__ */ jsx10("div", { className: "ya-href-popover-pages", children: sections.map((section) => /* @__PURE__ */ jsxs5(
|
|
3250
3885
|
"button",
|
|
3251
3886
|
{
|
|
3252
3887
|
type: "button",
|
|
@@ -3254,15 +3889,15 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3254
3889
|
onClick: () => handlePageSelect(section.path),
|
|
3255
3890
|
children: [
|
|
3256
3891
|
section.label,
|
|
3257
|
-
/* @__PURE__ */
|
|
3892
|
+
/* @__PURE__ */ jsx10("span", { className: "ya-href-page-path", children: section.path })
|
|
3258
3893
|
]
|
|
3259
3894
|
},
|
|
3260
3895
|
section.path
|
|
3261
3896
|
)) })
|
|
3262
3897
|
] }),
|
|
3263
|
-
pages.length > 0 && /* @__PURE__ */
|
|
3264
|
-
/* @__PURE__ */
|
|
3265
|
-
/* @__PURE__ */
|
|
3898
|
+
pages.length > 0 && /* @__PURE__ */ jsxs5("div", { className: "ya-href-popover-section", children: [
|
|
3899
|
+
/* @__PURE__ */ jsx10("label", { className: "ya-href-popover-label", children: "Navigate to page" }),
|
|
3900
|
+
/* @__PURE__ */ jsx10("div", { className: "ya-href-popover-pages", children: pages.map((page) => /* @__PURE__ */ jsxs5(
|
|
3266
3901
|
"button",
|
|
3267
3902
|
{
|
|
3268
3903
|
type: "button",
|
|
@@ -3270,13 +3905,13 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3270
3905
|
onClick: () => handlePageSelect(page.path),
|
|
3271
3906
|
children: [
|
|
3272
3907
|
page.label,
|
|
3273
|
-
/* @__PURE__ */
|
|
3908
|
+
/* @__PURE__ */ jsx10("span", { className: "ya-href-page-path", children: page.path })
|
|
3274
3909
|
]
|
|
3275
3910
|
},
|
|
3276
3911
|
page.path
|
|
3277
3912
|
)) })
|
|
3278
3913
|
] }),
|
|
3279
|
-
/* @__PURE__ */
|
|
3914
|
+
/* @__PURE__ */ jsx10(
|
|
3280
3915
|
"button",
|
|
3281
3916
|
{
|
|
3282
3917
|
type: "button",
|
|
@@ -3288,10 +3923,10 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3288
3923
|
children: "Use external URL instead"
|
|
3289
3924
|
}
|
|
3290
3925
|
)
|
|
3291
|
-
] }) : /* @__PURE__ */
|
|
3292
|
-
/* @__PURE__ */
|
|
3293
|
-
/* @__PURE__ */
|
|
3294
|
-
/* @__PURE__ */
|
|
3926
|
+
] }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3927
|
+
/* @__PURE__ */ jsxs5("div", { className: "ya-href-popover-section", children: [
|
|
3928
|
+
/* @__PURE__ */ jsx10("label", { className: "ya-href-popover-label", children: "External URL" }),
|
|
3929
|
+
/* @__PURE__ */ jsx10(
|
|
3295
3930
|
"input",
|
|
3296
3931
|
{
|
|
3297
3932
|
type: "url",
|
|
@@ -3303,21 +3938,444 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3303
3938
|
}
|
|
3304
3939
|
)
|
|
3305
3940
|
] }),
|
|
3306
|
-
/* @__PURE__ */
|
|
3941
|
+
/* @__PURE__ */ jsx10("button", { type: "button", className: "ya-href-external-toggle", onClick: () => setIsExternalUrl(false), children: "\u2190 Back to pages" })
|
|
3307
3942
|
] }),
|
|
3308
|
-
/* @__PURE__ */
|
|
3309
|
-
/* @__PURE__ */
|
|
3310
|
-
isExternalUrl ? /* @__PURE__ */
|
|
3943
|
+
/* @__PURE__ */ jsxs5("div", { className: "ya-href-popover-actions", children: [
|
|
3944
|
+
/* @__PURE__ */ jsx10("button", { type: "button", className: "ya-link-btn ya-link-btn-cancel", onClick: handleCancelLink, children: "Cancel" }),
|
|
3945
|
+
isExternalUrl ? /* @__PURE__ */ jsx10("button", { type: "button", className: "ya-link-btn ya-link-btn-save", onClick: handleExternalUrlApply, children: "Apply" }) : /* @__PURE__ */ jsx10("button", { type: "button", className: "ya-link-btn ya-link-btn-save", onClick: handleSaveLink, children: "Save" })
|
|
3311
3946
|
] })
|
|
3312
3947
|
] })
|
|
3313
3948
|
] });
|
|
3314
3949
|
}
|
|
3315
3950
|
|
|
3951
|
+
// src/components/YaContainer.tsx
|
|
3952
|
+
import { useCallback as useCallback11, useEffect as useEffect11, useRef as useRef11, useState as useState11 } from "react";
|
|
3953
|
+
import { createPortal as createPortal6 } from "react-dom";
|
|
3954
|
+
|
|
3955
|
+
// src/components/ya-container.css
|
|
3956
|
+
styleInject('.ya-container {\n position: relative;\n}\n.ya-container-has-overlay::after {\n content: "";\n position: absolute;\n inset: 0;\n background: var(--ya-overlay-color, transparent);\n opacity: var(--ya-overlay-opacity, 0);\n pointer-events: none;\n z-index: 0;\n}\n.ya-container > *:not(.ya-container-toolbar) {\n position: relative;\n z-index: 1;\n}\n.ya-container-editable {\n transition: outline 0.15s ease;\n}\n.ya-container-editable:hover {\n outline: 2px dashed var(--color-primary, #D4A574);\n outline-offset: -2px;\n}\nbody.builder-selector-active .ya-container-editable:hover {\n outline: none;\n}\n.ya-container-selected {\n outline: 3px solid var(--color-primary, #D4A574);\n outline-offset: -3px;\n}\n.ya-container-toolbar {\n display: flex;\n gap: 4px;\n background: rgba(26, 26, 26, 0.95);\n padding: 6px 8px;\n border-radius: 8px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n z-index: 9999;\n animation: ya-container-toolbar-fade-in 0.15s ease;\n}\n@keyframes ya-container-toolbar-fade-in {\n from {\n opacity: 0;\n transform: translateY(-4px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n.ya-container-toolbar button {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n background: #3a3a3a;\n border: none;\n border-radius: 6px;\n color: #ffffff;\n cursor: pointer;\n transition: background 0.15s ease, transform 0.1s ease;\n}\n.ya-container-toolbar button:hover {\n background: #4a4a4a;\n transform: scale(1.05);\n}\n.ya-container-toolbar button:active {\n transform: scale(0.98);\n}\n.ya-container-toolbar button.active {\n background: var(--color-primary, #D4A574);\n color: #1a1a1a;\n}\n.ya-container-toolbar button svg {\n width: 16px;\n height: 16px;\n}\n.ya-container-toolbar button[aria-label="Clear background"] {\n background: #3a2a2a;\n}\n.ya-container-toolbar button[aria-label="Clear background"]:hover {\n background: #5a3a3a;\n}\n.ya-container:focus-visible {\n outline: 3px solid var(--color-primary, #D4A574);\n outline-offset: -3px;\n}\n.ya-container-toolbar button:focus-visible {\n outline: 2px solid var(--color-primary, #D4A574);\n outline-offset: 2px;\n}\n.ya-container-drop-target {\n outline: 2px dashed var(--ya-drop-color, #3b82f6) !important;\n outline-offset: -2px;\n}\n.ya-container-drop-target .ya-container-toolbar {\n display: none !important;\n}\n.ya-container-drop-hover {\n outline: 3px solid var(--ya-drop-color, #3b82f6) !important;\n outline-offset: -3px;\n}\n.ya-container-drop-hover::before {\n content: "";\n position: absolute;\n inset: 0;\n background: rgba(59, 130, 246, 0.08);\n pointer-events: none;\n z-index: 10;\n animation: ya-container-drop-pulse 1s ease-in-out infinite;\n}\n@keyframes ya-container-drop-pulse {\n 0%, 100% {\n background: rgba(59, 130, 246, 0.05);\n }\n 50% {\n background: rgba(59, 130, 246, 0.12);\n }\n}\n');
|
|
3957
|
+
|
|
3958
|
+
// src/components/YaContainer.tsx
|
|
3959
|
+
import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3960
|
+
function parseBackgroundConfig(value) {
|
|
3961
|
+
if (!value) {
|
|
3962
|
+
return { type: "none" };
|
|
3963
|
+
}
|
|
3964
|
+
try {
|
|
3965
|
+
const parsed = JSON.parse(value);
|
|
3966
|
+
if (typeof parsed === "object" && parsed.type) {
|
|
3967
|
+
return parsed;
|
|
3968
|
+
}
|
|
3969
|
+
} catch {
|
|
3970
|
+
}
|
|
3971
|
+
return { type: "none" };
|
|
3972
|
+
}
|
|
3973
|
+
function serializeBackgroundConfig(config) {
|
|
3974
|
+
return JSON.stringify(config);
|
|
3975
|
+
}
|
|
3976
|
+
function getObjectPosition2(imageConfig) {
|
|
3977
|
+
if (imageConfig.focalPoint) {
|
|
3978
|
+
return `${imageConfig.focalPoint.x}% ${imageConfig.focalPoint.y}%`;
|
|
3979
|
+
}
|
|
3980
|
+
return imageConfig.objectPosition || "50% 50%";
|
|
3981
|
+
}
|
|
3982
|
+
function deriveContainerLabel(element) {
|
|
3983
|
+
if (!element) return "Section";
|
|
3984
|
+
const tagName = element.tagName.toLowerCase();
|
|
3985
|
+
const id = element.id;
|
|
3986
|
+
const ariaLabel = element.getAttribute("aria-label");
|
|
3987
|
+
if (ariaLabel) return ariaLabel;
|
|
3988
|
+
if (id) return id.replace(/-/g, " ").replace(/([A-Z])/g, " $1").trim();
|
|
3989
|
+
const tagLabels = {
|
|
3990
|
+
section: "Section",
|
|
3991
|
+
header: "Header",
|
|
3992
|
+
footer: "Footer",
|
|
3993
|
+
main: "Main Content",
|
|
3994
|
+
article: "Article",
|
|
3995
|
+
aside: "Sidebar",
|
|
3996
|
+
div: "Container"
|
|
3997
|
+
};
|
|
3998
|
+
return tagLabels[tagName] || "Section";
|
|
3999
|
+
}
|
|
4000
|
+
function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearClick, hasBackground }) {
|
|
4001
|
+
const [position, setPosition] = useState11(null);
|
|
4002
|
+
useEffect11(() => {
|
|
4003
|
+
const updatePosition = () => {
|
|
4004
|
+
if (containerRef.current) {
|
|
4005
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
4006
|
+
setPosition({
|
|
4007
|
+
top: rect.top + 8,
|
|
4008
|
+
left: rect.left + 8
|
|
4009
|
+
});
|
|
4010
|
+
}
|
|
4011
|
+
};
|
|
4012
|
+
updatePosition();
|
|
4013
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
4014
|
+
window.addEventListener("resize", updatePosition);
|
|
4015
|
+
return () => {
|
|
4016
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
4017
|
+
window.removeEventListener("resize", updatePosition);
|
|
4018
|
+
};
|
|
4019
|
+
}, [containerRef]);
|
|
4020
|
+
if (!position) return null;
|
|
4021
|
+
return createPortal6(
|
|
4022
|
+
/* @__PURE__ */ jsxs6(
|
|
4023
|
+
"div",
|
|
4024
|
+
{
|
|
4025
|
+
className: "ya-container-toolbar",
|
|
4026
|
+
style: {
|
|
4027
|
+
position: "fixed",
|
|
4028
|
+
top: position.top,
|
|
4029
|
+
left: position.left
|
|
4030
|
+
},
|
|
4031
|
+
onClick: (e) => e.stopPropagation(),
|
|
4032
|
+
children: [
|
|
4033
|
+
/* @__PURE__ */ jsx11(
|
|
4034
|
+
"button",
|
|
4035
|
+
{
|
|
4036
|
+
type: "button",
|
|
4037
|
+
onClick: onImageClick,
|
|
4038
|
+
"aria-label": "Edit background image",
|
|
4039
|
+
title: "Background Image",
|
|
4040
|
+
children: /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
4041
|
+
/* @__PURE__ */ jsx11("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
|
|
4042
|
+
/* @__PURE__ */ jsx11("circle", { cx: "8.5", cy: "8.5", r: "1.5" }),
|
|
4043
|
+
/* @__PURE__ */ jsx11("polyline", { points: "21 15 16 10 5 21" })
|
|
4044
|
+
] })
|
|
4045
|
+
}
|
|
4046
|
+
),
|
|
4047
|
+
/* @__PURE__ */ jsx11(
|
|
4048
|
+
"button",
|
|
4049
|
+
{
|
|
4050
|
+
type: "button",
|
|
4051
|
+
onClick: onColorClick,
|
|
4052
|
+
"aria-label": "Edit background color",
|
|
4053
|
+
title: "Background Color",
|
|
4054
|
+
children: /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
4055
|
+
/* @__PURE__ */ jsx11("circle", { cx: "12", cy: "12", r: "10" }),
|
|
4056
|
+
/* @__PURE__ */ jsx11("path", { d: "M12 2a10 10 0 0 1 0 20", fill: "currentColor" })
|
|
4057
|
+
] })
|
|
4058
|
+
}
|
|
4059
|
+
),
|
|
4060
|
+
/* @__PURE__ */ jsx11(
|
|
4061
|
+
"button",
|
|
4062
|
+
{
|
|
4063
|
+
type: "button",
|
|
4064
|
+
onClick: onAIClick,
|
|
4065
|
+
"aria-label": "Ask AI for help",
|
|
4066
|
+
title: "AI Assist",
|
|
4067
|
+
children: /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
4068
|
+
/* @__PURE__ */ jsx11("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
|
|
4069
|
+
/* @__PURE__ */ jsx11("path", { d: "M2 17l10 5 10-5" }),
|
|
4070
|
+
/* @__PURE__ */ jsx11("path", { d: "M2 12l10 5 10-5" })
|
|
4071
|
+
] })
|
|
4072
|
+
}
|
|
4073
|
+
),
|
|
4074
|
+
hasBackground && /* @__PURE__ */ jsx11(
|
|
4075
|
+
"button",
|
|
4076
|
+
{
|
|
4077
|
+
type: "button",
|
|
4078
|
+
onClick: onClearClick,
|
|
4079
|
+
"aria-label": "Clear background",
|
|
4080
|
+
title: "Clear Background",
|
|
4081
|
+
children: /* @__PURE__ */ jsxs6("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
4082
|
+
/* @__PURE__ */ jsx11("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
4083
|
+
/* @__PURE__ */ jsx11("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
4084
|
+
] })
|
|
4085
|
+
}
|
|
4086
|
+
)
|
|
4087
|
+
]
|
|
4088
|
+
}
|
|
4089
|
+
),
|
|
4090
|
+
document.body
|
|
4091
|
+
);
|
|
4092
|
+
}
|
|
4093
|
+
function YaContainer({
|
|
4094
|
+
fieldId,
|
|
4095
|
+
className,
|
|
4096
|
+
style,
|
|
4097
|
+
as: Tag = "section",
|
|
4098
|
+
children,
|
|
4099
|
+
defaultBackground
|
|
4100
|
+
}) {
|
|
4101
|
+
const { getValue, setValue, saveToWorker, mode } = useContentStore();
|
|
4102
|
+
const containerRef = useRef11(null);
|
|
4103
|
+
const [isHovered, setIsHovered] = useState11(false);
|
|
4104
|
+
const [isSelected, setIsSelected] = useState11(false);
|
|
4105
|
+
const [isDropMode, setIsDropMode] = useState11(false);
|
|
4106
|
+
const [isDropHover, setIsDropHover] = useState11(false);
|
|
4107
|
+
const rawValue = getValue(fieldId);
|
|
4108
|
+
const backgroundConfig = rawValue ? parseBackgroundConfig(rawValue) : defaultBackground || { type: "none" };
|
|
4109
|
+
const hasBackground = backgroundConfig.type !== "none";
|
|
4110
|
+
const backgroundStyles = {};
|
|
4111
|
+
if (backgroundConfig.type === "color" && backgroundConfig.backgroundColor) {
|
|
4112
|
+
backgroundStyles.backgroundColor = backgroundConfig.backgroundColor;
|
|
4113
|
+
}
|
|
4114
|
+
if (backgroundConfig.type === "image" && backgroundConfig.backgroundImage) {
|
|
4115
|
+
const img = backgroundConfig.backgroundImage;
|
|
4116
|
+
const resolvedSrc = resolveAssetUrl(img.src);
|
|
4117
|
+
backgroundStyles.backgroundImage = `url(${resolvedSrc})`;
|
|
4118
|
+
backgroundStyles.backgroundSize = img.objectFit || "cover";
|
|
4119
|
+
backgroundStyles.backgroundPosition = getObjectPosition2(img);
|
|
4120
|
+
backgroundStyles.backgroundRepeat = "no-repeat";
|
|
4121
|
+
}
|
|
4122
|
+
const overlayCustomProps = {};
|
|
4123
|
+
if (backgroundConfig.overlay) {
|
|
4124
|
+
overlayCustomProps["--ya-overlay-color"] = backgroundConfig.overlay.color;
|
|
4125
|
+
overlayCustomProps["--ya-overlay-opacity"] = backgroundConfig.overlay.opacity;
|
|
4126
|
+
}
|
|
4127
|
+
const handleImageClick = useCallback11(() => {
|
|
4128
|
+
if (mode !== "inline-edit") return;
|
|
4129
|
+
setIsSelected(true);
|
|
4130
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
4131
|
+
window.parent.postMessage(
|
|
4132
|
+
{
|
|
4133
|
+
type: "YA_CONTAINER_EDIT_REQUEST",
|
|
4134
|
+
fieldId,
|
|
4135
|
+
currentValue: backgroundConfig,
|
|
4136
|
+
editType: "image",
|
|
4137
|
+
elementRect: rect ? {
|
|
4138
|
+
top: rect.top,
|
|
4139
|
+
left: rect.left,
|
|
4140
|
+
width: rect.width,
|
|
4141
|
+
height: rect.height
|
|
4142
|
+
} : void 0
|
|
4143
|
+
},
|
|
4144
|
+
"*"
|
|
4145
|
+
);
|
|
4146
|
+
}, [mode, fieldId, backgroundConfig]);
|
|
4147
|
+
const handleColorClick = useCallback11(() => {
|
|
4148
|
+
if (mode !== "inline-edit") return;
|
|
4149
|
+
setIsSelected(true);
|
|
4150
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
4151
|
+
window.parent.postMessage(
|
|
4152
|
+
{
|
|
4153
|
+
type: "YA_CONTAINER_EDIT_REQUEST",
|
|
4154
|
+
fieldId,
|
|
4155
|
+
currentValue: backgroundConfig,
|
|
4156
|
+
editType: "color",
|
|
4157
|
+
elementRect: rect ? {
|
|
4158
|
+
top: rect.top,
|
|
4159
|
+
left: rect.left,
|
|
4160
|
+
width: rect.width,
|
|
4161
|
+
height: rect.height
|
|
4162
|
+
} : void 0
|
|
4163
|
+
},
|
|
4164
|
+
"*"
|
|
4165
|
+
);
|
|
4166
|
+
}, [mode, fieldId, backgroundConfig]);
|
|
4167
|
+
const handleAIClick = useCallback11(() => {
|
|
4168
|
+
if (mode !== "inline-edit") return;
|
|
4169
|
+
const label = deriveContainerLabel(containerRef.current);
|
|
4170
|
+
window.parent.postMessage(
|
|
4171
|
+
{
|
|
4172
|
+
type: "YA_CONTAINER_SELECT_FOR_AI",
|
|
4173
|
+
fieldId,
|
|
4174
|
+
label: `Background: ${label}`,
|
|
4175
|
+
currentValue: backgroundConfig
|
|
4176
|
+
},
|
|
4177
|
+
"*"
|
|
4178
|
+
);
|
|
4179
|
+
}, [mode, fieldId, backgroundConfig]);
|
|
4180
|
+
const handleClearClick = useCallback11(() => {
|
|
4181
|
+
if (mode !== "inline-edit") return;
|
|
4182
|
+
const clearedConfig = { type: "none" };
|
|
4183
|
+
const serialized = serializeBackgroundConfig(clearedConfig);
|
|
4184
|
+
setValue(fieldId, serialized);
|
|
4185
|
+
saveToWorker?.(fieldId, serialized);
|
|
4186
|
+
}, [mode, fieldId, setValue, saveToWorker]);
|
|
4187
|
+
useEffect11(() => {
|
|
4188
|
+
if (mode !== "inline-edit") return;
|
|
4189
|
+
const handleMessage2 = (event) => {
|
|
4190
|
+
if (event.data?.type === "YA_CONTAINER_EDIT_COMPLETE" && event.data.fieldId === fieldId) {
|
|
4191
|
+
setIsSelected(false);
|
|
4192
|
+
}
|
|
4193
|
+
if (event.data?.type === "YA_CONTAINER_EDIT_CANCEL" && event.data.fieldId === fieldId) {
|
|
4194
|
+
setIsSelected(false);
|
|
4195
|
+
}
|
|
4196
|
+
};
|
|
4197
|
+
window.addEventListener("message", handleMessage2);
|
|
4198
|
+
return () => window.removeEventListener("message", handleMessage2);
|
|
4199
|
+
}, [mode, fieldId]);
|
|
4200
|
+
useEffect11(() => {
|
|
4201
|
+
if (mode !== "inline-edit") return;
|
|
4202
|
+
const handleDropModeMessage = (event) => {
|
|
4203
|
+
if (event.data?.type === "DROP_MODE_START") {
|
|
4204
|
+
setIsDropMode(true);
|
|
4205
|
+
}
|
|
4206
|
+
if (event.data?.type === "DROP_MODE_END") {
|
|
4207
|
+
setIsDropMode(false);
|
|
4208
|
+
setIsDropHover(false);
|
|
4209
|
+
}
|
|
4210
|
+
};
|
|
4211
|
+
window.addEventListener("message", handleDropModeMessage);
|
|
4212
|
+
return () => window.removeEventListener("message", handleDropModeMessage);
|
|
4213
|
+
}, [mode]);
|
|
4214
|
+
const handleDragEnter = useCallback11(
|
|
4215
|
+
(e) => {
|
|
4216
|
+
if (!isDropMode) return;
|
|
4217
|
+
e.preventDefault();
|
|
4218
|
+
e.stopPropagation();
|
|
4219
|
+
setIsDropHover(true);
|
|
4220
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
4221
|
+
window.parent.postMessage(
|
|
4222
|
+
{
|
|
4223
|
+
type: "DROP_ZONE_ENTER",
|
|
4224
|
+
fieldId,
|
|
4225
|
+
zoneType: "background",
|
|
4226
|
+
rect: rect ? {
|
|
4227
|
+
top: rect.top,
|
|
4228
|
+
left: rect.left,
|
|
4229
|
+
width: rect.width,
|
|
4230
|
+
height: rect.height
|
|
4231
|
+
} : { top: 0, left: 0, width: 0, height: 0 }
|
|
4232
|
+
},
|
|
4233
|
+
"*"
|
|
4234
|
+
);
|
|
4235
|
+
},
|
|
4236
|
+
[isDropMode, fieldId]
|
|
4237
|
+
);
|
|
4238
|
+
const handleDragOver = useCallback11(
|
|
4239
|
+
(e) => {
|
|
4240
|
+
if (!isDropMode) return;
|
|
4241
|
+
e.preventDefault();
|
|
4242
|
+
e.stopPropagation();
|
|
4243
|
+
},
|
|
4244
|
+
[isDropMode]
|
|
4245
|
+
);
|
|
4246
|
+
const handleDragLeave = useCallback11(
|
|
4247
|
+
(e) => {
|
|
4248
|
+
if (!isDropMode) return;
|
|
4249
|
+
e.preventDefault();
|
|
4250
|
+
e.stopPropagation();
|
|
4251
|
+
const target = e.currentTarget;
|
|
4252
|
+
const relatedTarget = e.relatedTarget;
|
|
4253
|
+
if (!relatedTarget || !target.contains(relatedTarget)) {
|
|
4254
|
+
setIsDropHover(false);
|
|
4255
|
+
window.parent.postMessage({ type: "DROP_ZONE_LEAVE" }, "*");
|
|
4256
|
+
}
|
|
4257
|
+
},
|
|
4258
|
+
[isDropMode]
|
|
4259
|
+
);
|
|
4260
|
+
const handleDrop = useCallback11(
|
|
4261
|
+
(e) => {
|
|
4262
|
+
if (!isDropMode) return;
|
|
4263
|
+
e.preventDefault();
|
|
4264
|
+
e.stopPropagation();
|
|
4265
|
+
setIsDropHover(false);
|
|
4266
|
+
setIsDropMode(false);
|
|
4267
|
+
window.parent.postMessage(
|
|
4268
|
+
{
|
|
4269
|
+
type: "DROP_ZONE_DROP",
|
|
4270
|
+
fieldId,
|
|
4271
|
+
zoneType: "background"
|
|
4272
|
+
},
|
|
4273
|
+
"*"
|
|
4274
|
+
);
|
|
4275
|
+
},
|
|
4276
|
+
[isDropMode, fieldId]
|
|
4277
|
+
);
|
|
4278
|
+
useEffect11(() => {
|
|
4279
|
+
if (!isSelected || mode !== "inline-edit") return;
|
|
4280
|
+
let lastRectKey = "";
|
|
4281
|
+
let lastTime = 0;
|
|
4282
|
+
let rafId;
|
|
4283
|
+
const loop = (time) => {
|
|
4284
|
+
if (time - lastTime >= 50) {
|
|
4285
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
4286
|
+
if (rect) {
|
|
4287
|
+
const rectKey = `${Math.round(rect.top)},${Math.round(rect.left)},${Math.round(rect.width)},${Math.round(rect.height)}`;
|
|
4288
|
+
if (rectKey !== lastRectKey) {
|
|
4289
|
+
lastRectKey = rectKey;
|
|
4290
|
+
window.parent.postMessage(
|
|
4291
|
+
{
|
|
4292
|
+
type: "YA_CONTAINER_POSITION_UPDATE",
|
|
4293
|
+
fieldId,
|
|
4294
|
+
elementRect: {
|
|
4295
|
+
top: rect.top,
|
|
4296
|
+
left: rect.left,
|
|
4297
|
+
width: rect.width,
|
|
4298
|
+
height: rect.height
|
|
4299
|
+
}
|
|
4300
|
+
},
|
|
4301
|
+
"*"
|
|
4302
|
+
);
|
|
4303
|
+
}
|
|
4304
|
+
}
|
|
4305
|
+
lastTime = time;
|
|
4306
|
+
}
|
|
4307
|
+
rafId = requestAnimationFrame(loop);
|
|
4308
|
+
};
|
|
4309
|
+
rafId = requestAnimationFrame(loop);
|
|
4310
|
+
return () => cancelAnimationFrame(rafId);
|
|
4311
|
+
}, [isSelected, fieldId, mode]);
|
|
4312
|
+
if (mode === "read-only") {
|
|
4313
|
+
return /* @__PURE__ */ jsx11(
|
|
4314
|
+
Tag,
|
|
4315
|
+
{
|
|
4316
|
+
className: `ya-container ${className || ""}`,
|
|
4317
|
+
style: {
|
|
4318
|
+
...backgroundStyles,
|
|
4319
|
+
...overlayCustomProps,
|
|
4320
|
+
...style
|
|
4321
|
+
},
|
|
4322
|
+
"data-ya-restricted": "true",
|
|
4323
|
+
"data-field-id": fieldId,
|
|
4324
|
+
children
|
|
4325
|
+
}
|
|
4326
|
+
);
|
|
4327
|
+
}
|
|
4328
|
+
const containerClasses = [
|
|
4329
|
+
"ya-container",
|
|
4330
|
+
mode === "inline-edit" ? "ya-container-editable" : "",
|
|
4331
|
+
isSelected ? "ya-container-selected" : "",
|
|
4332
|
+
hasBackground ? "ya-container-has-overlay" : "",
|
|
4333
|
+
isDropMode ? "ya-container-drop-target" : "",
|
|
4334
|
+
isDropHover ? "ya-container-drop-hover" : "",
|
|
4335
|
+
className || ""
|
|
4336
|
+
].filter(Boolean).join(" ");
|
|
4337
|
+
return /* @__PURE__ */ jsxs6(
|
|
4338
|
+
Tag,
|
|
4339
|
+
{
|
|
4340
|
+
ref: containerRef,
|
|
4341
|
+
className: containerClasses,
|
|
4342
|
+
style: {
|
|
4343
|
+
...backgroundStyles,
|
|
4344
|
+
...overlayCustomProps,
|
|
4345
|
+
...style
|
|
4346
|
+
},
|
|
4347
|
+
"data-ya-restricted": "true",
|
|
4348
|
+
"data-field-id": fieldId,
|
|
4349
|
+
"data-ya-container": "true",
|
|
4350
|
+
onMouseEnter: () => setIsHovered(true),
|
|
4351
|
+
onMouseLeave: () => setIsHovered(false),
|
|
4352
|
+
onDragEnter: handleDragEnter,
|
|
4353
|
+
onDragOver: handleDragOver,
|
|
4354
|
+
onDragLeave: handleDragLeave,
|
|
4355
|
+
onDrop: handleDrop,
|
|
4356
|
+
children: [
|
|
4357
|
+
children,
|
|
4358
|
+
mode === "inline-edit" && (isHovered || isSelected) && !document.body.classList.contains("builder-selector-active") && /* @__PURE__ */ jsx11(
|
|
4359
|
+
Toolbar,
|
|
4360
|
+
{
|
|
4361
|
+
containerRef,
|
|
4362
|
+
onImageClick: handleImageClick,
|
|
4363
|
+
onColorClick: handleColorClick,
|
|
4364
|
+
onAIClick: handleAIClick,
|
|
4365
|
+
onClearClick: handleClearClick,
|
|
4366
|
+
hasBackground
|
|
4367
|
+
}
|
|
4368
|
+
)
|
|
4369
|
+
]
|
|
4370
|
+
}
|
|
4371
|
+
);
|
|
4372
|
+
}
|
|
4373
|
+
|
|
3316
4374
|
// src/components/StaticText.tsx
|
|
3317
|
-
import { jsx as
|
|
4375
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
3318
4376
|
function MpText({ fieldId, className, as: Component = "span", children }) {
|
|
3319
4377
|
const content = getContent(fieldId) || (typeof children === "string" ? children : "");
|
|
3320
|
-
return /* @__PURE__ */
|
|
4378
|
+
return /* @__PURE__ */ jsx12(
|
|
3321
4379
|
Component,
|
|
3322
4380
|
{
|
|
3323
4381
|
className,
|
|
@@ -3328,7 +4386,7 @@ function MpText({ fieldId, className, as: Component = "span", children }) {
|
|
|
3328
4386
|
}
|
|
3329
4387
|
|
|
3330
4388
|
// src/components/StaticImage.tsx
|
|
3331
|
-
import { jsx as
|
|
4389
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
3332
4390
|
function parseImageValue2(value) {
|
|
3333
4391
|
if (!value) {
|
|
3334
4392
|
return { src: "" };
|
|
@@ -3342,7 +4400,7 @@ function parseImageValue2(value) {
|
|
|
3342
4400
|
}
|
|
3343
4401
|
return { src: value };
|
|
3344
4402
|
}
|
|
3345
|
-
function
|
|
4403
|
+
function getObjectPosition3(imageData) {
|
|
3346
4404
|
if (imageData.focalPoint) {
|
|
3347
4405
|
return `${imageData.focalPoint.x}% ${imageData.focalPoint.y}%`;
|
|
3348
4406
|
}
|
|
@@ -3363,8 +4421,8 @@ function MpImage({
|
|
|
3363
4421
|
const src = imageData.src || fallbackSrc || "";
|
|
3364
4422
|
const altText = imageData.alt || alt || fallbackAlt || "";
|
|
3365
4423
|
const objectFit = imageData.objectFit || propObjectFit || "cover";
|
|
3366
|
-
const objectPosition =
|
|
3367
|
-
return /* @__PURE__ */
|
|
4424
|
+
const objectPosition = getObjectPosition3(imageData) || propObjectPosition || "50% 50%";
|
|
4425
|
+
return /* @__PURE__ */ jsx13(
|
|
3368
4426
|
"img",
|
|
3369
4427
|
{
|
|
3370
4428
|
src: resolveAssetUrl(src),
|
|
@@ -3382,7 +4440,7 @@ function MpImage({
|
|
|
3382
4440
|
|
|
3383
4441
|
// src/components/MarkdownText.tsx
|
|
3384
4442
|
import { Fragment as Fragment4 } from "react";
|
|
3385
|
-
import { jsx as
|
|
4443
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
3386
4444
|
function tokenize(text) {
|
|
3387
4445
|
const tokens = [];
|
|
3388
4446
|
let remaining = text;
|
|
@@ -3444,13 +4502,13 @@ function tokensToElements(tokens) {
|
|
|
3444
4502
|
return tokens.map((token, index) => {
|
|
3445
4503
|
switch (token.type) {
|
|
3446
4504
|
case "text":
|
|
3447
|
-
return /* @__PURE__ */
|
|
4505
|
+
return /* @__PURE__ */ jsx14(Fragment4, { children: token.content }, index);
|
|
3448
4506
|
case "bold":
|
|
3449
|
-
return /* @__PURE__ */
|
|
4507
|
+
return /* @__PURE__ */ jsx14("strong", { children: token.content }, index);
|
|
3450
4508
|
case "italic":
|
|
3451
|
-
return /* @__PURE__ */
|
|
4509
|
+
return /* @__PURE__ */ jsx14("em", { children: token.content }, index);
|
|
3452
4510
|
case "link":
|
|
3453
|
-
return /* @__PURE__ */
|
|
4511
|
+
return /* @__PURE__ */ jsx14(
|
|
3454
4512
|
"a",
|
|
3455
4513
|
{
|
|
3456
4514
|
href: token.url,
|
|
@@ -3462,7 +4520,7 @@ function tokensToElements(tokens) {
|
|
|
3462
4520
|
index
|
|
3463
4521
|
);
|
|
3464
4522
|
case "newline":
|
|
3465
|
-
return /* @__PURE__ */
|
|
4523
|
+
return /* @__PURE__ */ jsx14("br", {}, index);
|
|
3466
4524
|
default:
|
|
3467
4525
|
return null;
|
|
3468
4526
|
}
|
|
@@ -3474,15 +4532,15 @@ function parseMarkdownToElements(content) {
|
|
|
3474
4532
|
}
|
|
3475
4533
|
function MarkdownText({ content, className }) {
|
|
3476
4534
|
const elements = parseMarkdownToElements(content);
|
|
3477
|
-
return /* @__PURE__ */
|
|
4535
|
+
return /* @__PURE__ */ jsx14("span", { className, children: elements });
|
|
3478
4536
|
}
|
|
3479
4537
|
|
|
3480
4538
|
// src/router/Link.tsx
|
|
3481
4539
|
import { Link as WouterLink2 } from "wouter";
|
|
3482
|
-
import { jsx as
|
|
4540
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
3483
4541
|
function Link2({ to, href, children, className, onClick, replace, ...props }) {
|
|
3484
4542
|
const target = href ?? to ?? "/";
|
|
3485
|
-
return /* @__PURE__ */
|
|
4543
|
+
return /* @__PURE__ */ jsx15(WouterLink2, { href: target, className, onClick, replace, ...props, children });
|
|
3486
4544
|
}
|
|
3487
4545
|
|
|
3488
4546
|
// src/router/useNavigate.ts
|
|
@@ -3501,7 +4559,7 @@ function useNavigate() {
|
|
|
3501
4559
|
|
|
3502
4560
|
// src/router/Router.tsx
|
|
3503
4561
|
import { Router as WouterRouter } from "wouter";
|
|
3504
|
-
import { jsx as
|
|
4562
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
3505
4563
|
function detectBasename() {
|
|
3506
4564
|
if (typeof window === "undefined") return "";
|
|
3507
4565
|
const sessionMatch = window.location.pathname.match(/^\/session\/[^/]+/);
|
|
@@ -3516,7 +4574,7 @@ function detectBasename() {
|
|
|
3516
4574
|
}
|
|
3517
4575
|
function Router({ children, base }) {
|
|
3518
4576
|
const basename = base ?? detectBasename();
|
|
3519
|
-
return /* @__PURE__ */
|
|
4577
|
+
return /* @__PURE__ */ jsx16(WouterRouter, { base: basename, children });
|
|
3520
4578
|
}
|
|
3521
4579
|
|
|
3522
4580
|
// src/router/index.ts
|
|
@@ -3530,12 +4588,15 @@ export {
|
|
|
3530
4588
|
Route,
|
|
3531
4589
|
Router,
|
|
3532
4590
|
SafeHtml,
|
|
4591
|
+
SafeTriangleBelow,
|
|
3533
4592
|
MpImage as StaticImage,
|
|
3534
4593
|
MpText as StaticText,
|
|
3535
4594
|
Switch,
|
|
4595
|
+
YaContainer,
|
|
3536
4596
|
YaImage,
|
|
3537
4597
|
YaLink,
|
|
3538
4598
|
YaText,
|
|
4599
|
+
YaVideo,
|
|
3539
4600
|
buildIntermediateText,
|
|
3540
4601
|
calculateAnimationTiming,
|
|
3541
4602
|
computeTextDiff,
|
|
@@ -3548,9 +4609,12 @@ export {
|
|
|
3548
4609
|
imageCrossfadeStrategy,
|
|
3549
4610
|
initBuilderSelection,
|
|
3550
4611
|
linkTransitionStrategy,
|
|
4612
|
+
parseBackgroundConfig,
|
|
3551
4613
|
registerContent,
|
|
3552
4614
|
resolveAssetUrl,
|
|
4615
|
+
serializeBackgroundConfig,
|
|
3553
4616
|
serializeImageValue,
|
|
4617
|
+
serializeVideoValue,
|
|
3554
4618
|
setAssetResolver,
|
|
3555
4619
|
stripHtml,
|
|
3556
4620
|
textTypingStrategy,
|
|
@@ -3561,5 +4625,6 @@ export {
|
|
|
3561
4625
|
useContentStore,
|
|
3562
4626
|
useContentStore2 as useContentStoreProd,
|
|
3563
4627
|
useNavigate,
|
|
3564
|
-
useParams
|
|
4628
|
+
useParams,
|
|
4629
|
+
useSafeTriangle
|
|
3565
4630
|
};
|