@yoamigo.com/core 0.3.1 → 0.3.3
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-Nvkeyr1z.d.ts} +46 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +619 -180
- package/dist/lib.js +30 -5
- package/dist/plugin.js +6 -0
- package/dist/prod.d.ts +41 -2
- package/dist/prod.js +295 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -157,6 +157,9 @@ var BuilderSelectionManager = class {
|
|
|
157
157
|
elementMap = /* @__PURE__ */ new Map();
|
|
158
158
|
// Current selections from parent (for re-rendering on mode change)
|
|
159
159
|
currentSelections = [];
|
|
160
|
+
// Throttle screenshot captures to prevent overlapping
|
|
161
|
+
lastCaptureTime = 0;
|
|
162
|
+
CAPTURE_THROTTLE_MS = 3e3;
|
|
160
163
|
constructor() {
|
|
161
164
|
if (window.parent === window) {
|
|
162
165
|
console.log("[BuilderSelection] Not in iframe, skipping initialization");
|
|
@@ -280,6 +283,16 @@ var BuilderSelectionManager = class {
|
|
|
280
283
|
});
|
|
281
284
|
};
|
|
282
285
|
handleKeyDown = (e) => {
|
|
286
|
+
const isMac = navigator.platform.toUpperCase().indexOf("MAC") >= 0;
|
|
287
|
+
const modifier = isMac ? e.metaKey : e.ctrlKey;
|
|
288
|
+
if (modifier) {
|
|
289
|
+
if (e.key === "=" || e.key === "+" || e.key === "-" || e.key === "0" || e.key === "1") {
|
|
290
|
+
e.preventDefault();
|
|
291
|
+
const normalizedKey = e.key === "=" ? "+" : e.key;
|
|
292
|
+
this.sendToParent({ type: "IFRAME_KEYBOARD_ZOOM", key: normalizedKey });
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
283
296
|
if (e.key === "Shift") {
|
|
284
297
|
const activeElement = document.activeElement;
|
|
285
298
|
const isEditing = activeElement?.closest(".ya-text-editing") || activeElement?.closest(".ya-link-editing");
|
|
@@ -596,10 +609,16 @@ var BuilderSelectionManager = class {
|
|
|
596
609
|
/**
|
|
597
610
|
* Capture a full-page screenshot for loading placeholder
|
|
598
611
|
* Uses html2canvas to render the page at reduced quality for smaller file size
|
|
612
|
+
* Throttled to prevent overlapping captures (3 second minimum between captures)
|
|
599
613
|
*/
|
|
600
614
|
async captureFullPageScreenshot() {
|
|
615
|
+
const now = Date.now();
|
|
616
|
+
if (now - this.lastCaptureTime < this.CAPTURE_THROTTLE_MS) {
|
|
617
|
+
console.log("[BuilderSelection] Screenshot throttled");
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
this.lastCaptureTime = now;
|
|
601
621
|
try {
|
|
602
|
-
console.log("[BuilderSelection] Capturing full-page screenshot");
|
|
603
622
|
const html2canvas = (await import("html2canvas-pro")).default;
|
|
604
623
|
const overlays = document.querySelectorAll(".builder-selection-container, #builder-hover-overlay");
|
|
605
624
|
overlays.forEach((el) => {
|
|
@@ -612,14 +631,14 @@ var BuilderSelectionManager = class {
|
|
|
612
631
|
logging: false,
|
|
613
632
|
useCORS: true,
|
|
614
633
|
allowTaint: true,
|
|
615
|
-
backgroundColor:
|
|
634
|
+
backgroundColor: "#ffffff"
|
|
635
|
+
// White background for JPEG (null would render as black)
|
|
616
636
|
});
|
|
617
637
|
overlays.forEach((el) => {
|
|
618
638
|
;
|
|
619
639
|
el.style.display = "";
|
|
620
640
|
});
|
|
621
641
|
const dataUrl = canvas.toDataURL("image/jpeg", 0.6);
|
|
622
|
-
console.log("[BuilderSelection] Full-page screenshot captured, size:", dataUrl.length);
|
|
623
642
|
this.sendToParent({
|
|
624
643
|
type: "SCREENSHOT_READY",
|
|
625
644
|
dataUrl
|
|
@@ -739,12 +758,18 @@ var BuilderSelectionManager = class {
|
|
|
739
758
|
this.selections.set(selectionId, { element, container, badge, border });
|
|
740
759
|
}
|
|
741
760
|
};
|
|
761
|
+
var instance = null;
|
|
742
762
|
function initBuilderSelection() {
|
|
743
763
|
if (typeof window !== "undefined" && window.parent !== window) {
|
|
764
|
+
if (instance) {
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
744
767
|
if (document.readyState === "loading") {
|
|
745
|
-
document.addEventListener("DOMContentLoaded", () =>
|
|
768
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
769
|
+
instance = new BuilderSelectionManager();
|
|
770
|
+
});
|
|
746
771
|
} else {
|
|
747
|
-
new BuilderSelectionManager();
|
|
772
|
+
instance = new BuilderSelectionManager();
|
|
748
773
|
}
|
|
749
774
|
}
|
|
750
775
|
}
|
|
@@ -3146,7 +3171,7 @@ function YaTooltip({
|
|
|
3146
3171
|
}
|
|
3147
3172
|
|
|
3148
3173
|
// src/components/ya-image.css
|
|
3149
|
-
styleInject('.ya-image-container {\n position: relative;\n display: inline-
|
|
3174
|
+
styleInject('.ya-image-container {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\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');
|
|
3150
3175
|
|
|
3151
3176
|
// src/components/YaImage.tsx
|
|
3152
3177
|
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
@@ -3867,8 +3892,419 @@ function YaVideo({
|
|
|
3867
3892
|
);
|
|
3868
3893
|
}
|
|
3869
3894
|
|
|
3895
|
+
// src/components/YaEmbed.tsx
|
|
3896
|
+
import { useCallback as useCallback11, useEffect as useEffect10, useRef as useRef10, useState as useState9 } from "react";
|
|
3897
|
+
|
|
3898
|
+
// src/components/ya-embed.css
|
|
3899
|
+
styleInject('.ya-embed-wrapper {\n position: relative;\n display: block;\n width: 100%;\n}\n.ya-embed-wrapper iframe {\n display: block;\n width: 100%;\n height: 100%;\n}\n.ya-embed-container {\n position: relative;\n display: block;\n width: 100%;\n min-width: 80px;\n min-height: 80px;\n cursor: pointer;\n transition: outline 0.15s ease;\n}\n.ya-embed-container iframe {\n display: block;\n width: 100%;\n height: 100%;\n pointer-events: none;\n}\n.ya-embed-editable {\n cursor: pointer;\n}\n.ya-embed-editable:hover {\n outline: 2px dashed var(--color-primary, #d4a574);\n outline-offset: 4px;\n}\n.ya-embed-selected {\n outline: 3px solid var(--color-primary, #d4a574);\n outline-offset: 4px;\n}\n.ya-embed-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-embed-editable:hover .ya-embed-overlay {\n opacity: 1;\n}\n.ya-embed-selected .ya-embed-overlay {\n opacity: 0;\n}\n.ya-embed-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-embed-edit-icon svg {\n width: 24px;\n height: 24px;\n}\n.ya-embed-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-embed-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-embed-placeholder img {\n width: 64px;\n height: auto;\n opacity: 0.5;\n}\n@keyframes ya-embed-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-embed-success {\n animation: ya-embed-success 0.4s ease;\n}\n.ya-embed-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-embed-shimmer 1.5s infinite;\n}\n@keyframes ya-embed-shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.ya-embed-container:focus {\n outline: 3px solid var(--color-primary, #d4a574);\n outline-offset: 4px;\n}\n.ya-embed-container:focus:not(:focus-visible) {\n outline: none;\n}\n.ya-embed-container:focus-visible {\n outline: 3px solid var(--color-primary, #d4a574);\n outline-offset: 4px;\n}\n.ya-embed-small .ya-embed-overlay {\n display: none;\n}\n.ya-embed-twitter {\n min-height: 200px;\n}\n.ya-embed-twitter .twitter-tweet {\n margin: 0 auto !important;\n}\n.ya-embed-wrapper[data-embed-type=spotify],\n.ya-embed-container[data-embed-type=spotify] {\n min-height: 80px;\n}\n.ya-embed-wrapper[data-embed-type=soundcloud],\n.ya-embed-container[data-embed-type=soundcloud] {\n min-height: 166px;\n}\n.ya-embed-wrapper[data-embed-type=instagram] iframe,\n.ya-embed-container[data-embed-type=instagram] iframe {\n min-height: 400px;\n}\n');
|
|
3900
|
+
|
|
3901
|
+
// src/components/YaEmbed.tsx
|
|
3902
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
3903
|
+
function parseEmbedUrl(url) {
|
|
3904
|
+
if (!url) return null;
|
|
3905
|
+
const trimmedUrl = url.trim();
|
|
3906
|
+
const spotifyMatch = trimmedUrl.match(
|
|
3907
|
+
/open\.spotify\.com\/(track|album|playlist|episode|show)\/([a-zA-Z0-9]+)/
|
|
3908
|
+
);
|
|
3909
|
+
if (spotifyMatch) {
|
|
3910
|
+
const spotifyType = spotifyMatch[1];
|
|
3911
|
+
const spotifyId = spotifyMatch[2];
|
|
3912
|
+
const height = spotifyType === "track" ? 152 : 352;
|
|
3913
|
+
return {
|
|
3914
|
+
type: "spotify",
|
|
3915
|
+
src: `${spotifyType}/${spotifyId}`,
|
|
3916
|
+
originalUrl: trimmedUrl,
|
|
3917
|
+
height,
|
|
3918
|
+
spotifyType
|
|
3919
|
+
};
|
|
3920
|
+
}
|
|
3921
|
+
const soundcloudMatch = trimmedUrl.match(/soundcloud\.com\/([^/]+)\/([^/?]+)/);
|
|
3922
|
+
if (soundcloudMatch) {
|
|
3923
|
+
return {
|
|
3924
|
+
type: "soundcloud",
|
|
3925
|
+
src: trimmedUrl,
|
|
3926
|
+
// SoundCloud embeds use full URL
|
|
3927
|
+
originalUrl: trimmedUrl,
|
|
3928
|
+
height: 166
|
|
3929
|
+
};
|
|
3930
|
+
}
|
|
3931
|
+
const twitterMatch = trimmedUrl.match(/(?:twitter\.com|x\.com)\/\w+\/status\/(\d+)/);
|
|
3932
|
+
if (twitterMatch) {
|
|
3933
|
+
return {
|
|
3934
|
+
type: "twitter",
|
|
3935
|
+
src: twitterMatch[1],
|
|
3936
|
+
// Tweet ID
|
|
3937
|
+
originalUrl: trimmedUrl,
|
|
3938
|
+
aspectRatio: "1/1"
|
|
3939
|
+
// Twitter embeds are roughly square
|
|
3940
|
+
};
|
|
3941
|
+
}
|
|
3942
|
+
const instagramMatch = trimmedUrl.match(/instagram\.com\/(?:p|reel)\/([a-zA-Z0-9_-]+)/);
|
|
3943
|
+
if (instagramMatch) {
|
|
3944
|
+
return {
|
|
3945
|
+
type: "instagram",
|
|
3946
|
+
src: instagramMatch[1],
|
|
3947
|
+
// Post shortcode
|
|
3948
|
+
originalUrl: trimmedUrl,
|
|
3949
|
+
aspectRatio: "1/1"
|
|
3950
|
+
};
|
|
3951
|
+
}
|
|
3952
|
+
if (trimmedUrl.startsWith("https://")) {
|
|
3953
|
+
if (trimmedUrl.startsWith("javascript:") || trimmedUrl.startsWith("data:") || trimmedUrl.includes("<script")) {
|
|
3954
|
+
return null;
|
|
3955
|
+
}
|
|
3956
|
+
return {
|
|
3957
|
+
type: "custom",
|
|
3958
|
+
src: trimmedUrl,
|
|
3959
|
+
originalUrl: trimmedUrl,
|
|
3960
|
+
aspectRatio: "16/9"
|
|
3961
|
+
};
|
|
3962
|
+
}
|
|
3963
|
+
return null;
|
|
3964
|
+
}
|
|
3965
|
+
function parseEmbedValue(value) {
|
|
3966
|
+
if (!value) {
|
|
3967
|
+
return { type: "custom", src: "" };
|
|
3968
|
+
}
|
|
3969
|
+
try {
|
|
3970
|
+
const parsed = JSON.parse(value);
|
|
3971
|
+
if (typeof parsed === "object" && parsed.src) {
|
|
3972
|
+
return {
|
|
3973
|
+
type: parsed.type || "custom",
|
|
3974
|
+
...parsed
|
|
3975
|
+
};
|
|
3976
|
+
}
|
|
3977
|
+
} catch {
|
|
3978
|
+
const detected = parseEmbedUrl(value);
|
|
3979
|
+
if (detected) {
|
|
3980
|
+
return detected;
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
return { type: "custom", src: value, originalUrl: value };
|
|
3984
|
+
}
|
|
3985
|
+
function serializeEmbedValue(value) {
|
|
3986
|
+
return JSON.stringify(value);
|
|
3987
|
+
}
|
|
3988
|
+
function buildSpotifyEmbedUrl(src) {
|
|
3989
|
+
return `https://open.spotify.com/embed/${src}?utm_source=generator&theme=0`;
|
|
3990
|
+
}
|
|
3991
|
+
function buildSoundCloudEmbedUrl(src) {
|
|
3992
|
+
return `https://w.soundcloud.com/player/?url=${encodeURIComponent(src)}&color=%23ff5500&auto_play=false&hide_related=true&show_comments=false&show_user=true&show_reposts=false&show_teaser=false`;
|
|
3993
|
+
}
|
|
3994
|
+
function buildInstagramEmbedUrl(shortcode) {
|
|
3995
|
+
return `https://www.instagram.com/p/${shortcode}/embed`;
|
|
3996
|
+
}
|
|
3997
|
+
var SMALL_EMBED_THRESHOLD = 100;
|
|
3998
|
+
var PLACEHOLDER_SVG3 = `data:image/svg+xml,${encodeURIComponent(`
|
|
3999
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="225" viewBox="0 0 400 225">
|
|
4000
|
+
<rect fill="#e5e7eb" width="400" height="225"/>
|
|
4001
|
+
<g fill="#9ca3af" transform="translate(175, 87)">
|
|
4002
|
+
<rect x="5" y="5" width="40" height="30" rx="4" stroke="currentColor" stroke-width="2" fill="none"/>
|
|
4003
|
+
<path d="M15 15 L25 22 L15 29 Z" fill="currentColor"/>
|
|
4004
|
+
</g>
|
|
4005
|
+
</svg>
|
|
4006
|
+
`)}`;
|
|
4007
|
+
function YaEmbed({
|
|
4008
|
+
fieldId,
|
|
4009
|
+
className,
|
|
4010
|
+
aspectRatio: propAspectRatio,
|
|
4011
|
+
maxWidth,
|
|
4012
|
+
loading = "lazy",
|
|
4013
|
+
defaultValue
|
|
4014
|
+
}) {
|
|
4015
|
+
const { getValue, mode } = useContentStore();
|
|
4016
|
+
const containerRef = useRef10(null);
|
|
4017
|
+
const [isSelected, setIsSelected] = useState9(false);
|
|
4018
|
+
const [isHovered, setIsHovered] = useState9(false);
|
|
4019
|
+
const [isSmallEmbed, setIsSmallEmbed] = useState9(false);
|
|
4020
|
+
const [isInView, setIsInView] = useState9(loading === "eager");
|
|
4021
|
+
const rawValue = getValue(fieldId);
|
|
4022
|
+
const parsedValue = parseEmbedValue(rawValue);
|
|
4023
|
+
const embedData = parsedValue.src ? parsedValue : defaultValue || parsedValue;
|
|
4024
|
+
const src = embedData.src || "";
|
|
4025
|
+
const embedType = embedData.type || "custom";
|
|
4026
|
+
const height = embedData.height;
|
|
4027
|
+
const aspectRatio = embedData.aspectRatio || propAspectRatio || "16/9";
|
|
4028
|
+
useEffect10(() => {
|
|
4029
|
+
if (loading === "eager" || isInView) return;
|
|
4030
|
+
const observer = new IntersectionObserver(
|
|
4031
|
+
(entries) => {
|
|
4032
|
+
if (entries[0]?.isIntersecting) {
|
|
4033
|
+
setIsInView(true);
|
|
4034
|
+
observer.disconnect();
|
|
4035
|
+
}
|
|
4036
|
+
},
|
|
4037
|
+
{ rootMargin: "200px" }
|
|
4038
|
+
// Start loading 200px before visible
|
|
4039
|
+
);
|
|
4040
|
+
if (containerRef.current) {
|
|
4041
|
+
observer.observe(containerRef.current);
|
|
4042
|
+
}
|
|
4043
|
+
return () => observer.disconnect();
|
|
4044
|
+
}, [loading, isInView]);
|
|
4045
|
+
const handleClick = useCallback11(() => {
|
|
4046
|
+
if (mode !== "inline-edit") return;
|
|
4047
|
+
if (document.body.classList.contains("builder-selector-active")) return;
|
|
4048
|
+
setIsSelected(true);
|
|
4049
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
4050
|
+
window.parent.postMessage(
|
|
4051
|
+
{
|
|
4052
|
+
type: "YA_EMBED_EDIT_REQUEST",
|
|
4053
|
+
fieldId,
|
|
4054
|
+
currentValue: embedData,
|
|
4055
|
+
elementRect: rect ? {
|
|
4056
|
+
top: rect.top,
|
|
4057
|
+
left: rect.left,
|
|
4058
|
+
width: rect.width,
|
|
4059
|
+
height: rect.height
|
|
4060
|
+
} : void 0
|
|
4061
|
+
},
|
|
4062
|
+
"*"
|
|
4063
|
+
);
|
|
4064
|
+
}, [mode, fieldId, embedData]);
|
|
4065
|
+
useEffect10(() => {
|
|
4066
|
+
if (mode !== "inline-edit") return;
|
|
4067
|
+
const handleMessage2 = (event) => {
|
|
4068
|
+
if (event.data?.type === "YA_EMBED_EDIT_COMPLETE" && event.data.fieldId === fieldId) {
|
|
4069
|
+
setIsSelected(false);
|
|
4070
|
+
}
|
|
4071
|
+
if (event.data?.type === "YA_EMBED_EDIT_CANCEL" && event.data.fieldId === fieldId) {
|
|
4072
|
+
setIsSelected(false);
|
|
4073
|
+
}
|
|
4074
|
+
};
|
|
4075
|
+
window.addEventListener("message", handleMessage2);
|
|
4076
|
+
return () => window.removeEventListener("message", handleMessage2);
|
|
4077
|
+
}, [mode, fieldId]);
|
|
4078
|
+
useEffect10(() => {
|
|
4079
|
+
if (mode !== "inline-edit") return;
|
|
4080
|
+
const checkSize = () => {
|
|
4081
|
+
if (containerRef.current) {
|
|
4082
|
+
const { width, height: height2 } = containerRef.current.getBoundingClientRect();
|
|
4083
|
+
setIsSmallEmbed(width < SMALL_EMBED_THRESHOLD || height2 < SMALL_EMBED_THRESHOLD);
|
|
4084
|
+
}
|
|
4085
|
+
};
|
|
4086
|
+
checkSize();
|
|
4087
|
+
window.addEventListener("resize", checkSize);
|
|
4088
|
+
return () => window.removeEventListener("resize", checkSize);
|
|
4089
|
+
}, [mode]);
|
|
4090
|
+
useEffect10(() => {
|
|
4091
|
+
if (!isSelected || mode !== "inline-edit") return;
|
|
4092
|
+
let lastRectKey = "";
|
|
4093
|
+
let lastTime = 0;
|
|
4094
|
+
let rafId;
|
|
4095
|
+
const loop = (time) => {
|
|
4096
|
+
if (time - lastTime >= 50) {
|
|
4097
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
4098
|
+
if (rect) {
|
|
4099
|
+
const rectKey = `${Math.round(rect.top)},${Math.round(rect.left)},${Math.round(rect.width)},${Math.round(rect.height)}`;
|
|
4100
|
+
if (rectKey !== lastRectKey) {
|
|
4101
|
+
lastRectKey = rectKey;
|
|
4102
|
+
window.parent.postMessage(
|
|
4103
|
+
{
|
|
4104
|
+
type: "YA_EMBED_POSITION_UPDATE",
|
|
4105
|
+
fieldId,
|
|
4106
|
+
elementRect: {
|
|
4107
|
+
top: rect.top,
|
|
4108
|
+
left: rect.left,
|
|
4109
|
+
width: rect.width,
|
|
4110
|
+
height: rect.height
|
|
4111
|
+
}
|
|
4112
|
+
},
|
|
4113
|
+
"*"
|
|
4114
|
+
);
|
|
4115
|
+
}
|
|
4116
|
+
}
|
|
4117
|
+
lastTime = time;
|
|
4118
|
+
}
|
|
4119
|
+
rafId = requestAnimationFrame(loop);
|
|
4120
|
+
};
|
|
4121
|
+
rafId = requestAnimationFrame(loop);
|
|
4122
|
+
return () => cancelAnimationFrame(rafId);
|
|
4123
|
+
}, [isSelected, fieldId, mode]);
|
|
4124
|
+
const renderEmbed = (isReadOnly) => {
|
|
4125
|
+
if (!src && !isReadOnly) {
|
|
4126
|
+
return /* @__PURE__ */ jsxs8("div", { className: "ya-embed-placeholder", children: [
|
|
4127
|
+
/* @__PURE__ */ jsx14("img", { src: PLACEHOLDER_SVG3, alt: "" }),
|
|
4128
|
+
/* @__PURE__ */ jsx14("span", { children: "No embed selected" })
|
|
4129
|
+
] });
|
|
4130
|
+
}
|
|
4131
|
+
if (!isInView && loading === "lazy" && !isReadOnly) {
|
|
4132
|
+
return /* @__PURE__ */ jsx14("div", { className: "ya-embed-placeholder", style: { aspectRatio }, children: /* @__PURE__ */ jsx14("img", { src: PLACEHOLDER_SVG3, alt: "" }) });
|
|
4133
|
+
}
|
|
4134
|
+
if (embedType === "spotify" && src) {
|
|
4135
|
+
const embedUrl = buildSpotifyEmbedUrl(src);
|
|
4136
|
+
return /* @__PURE__ */ jsx14(
|
|
4137
|
+
"iframe",
|
|
4138
|
+
{
|
|
4139
|
+
src: embedUrl,
|
|
4140
|
+
style: {
|
|
4141
|
+
width: "100%",
|
|
4142
|
+
height: height ? `${height}px` : "100%",
|
|
4143
|
+
border: "none",
|
|
4144
|
+
borderRadius: "12px"
|
|
4145
|
+
},
|
|
4146
|
+
allow: "autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture",
|
|
4147
|
+
loading,
|
|
4148
|
+
title: "Spotify embed"
|
|
4149
|
+
}
|
|
4150
|
+
);
|
|
4151
|
+
}
|
|
4152
|
+
if (embedType === "soundcloud" && src) {
|
|
4153
|
+
const embedUrl = buildSoundCloudEmbedUrl(src);
|
|
4154
|
+
return /* @__PURE__ */ jsx14(
|
|
4155
|
+
"iframe",
|
|
4156
|
+
{
|
|
4157
|
+
src: embedUrl,
|
|
4158
|
+
style: {
|
|
4159
|
+
width: "100%",
|
|
4160
|
+
height: height ? `${height}px` : "166px",
|
|
4161
|
+
border: "none"
|
|
4162
|
+
},
|
|
4163
|
+
allow: "autoplay",
|
|
4164
|
+
loading,
|
|
4165
|
+
title: "SoundCloud embed"
|
|
4166
|
+
}
|
|
4167
|
+
);
|
|
4168
|
+
}
|
|
4169
|
+
if (embedType === "twitter" && src) {
|
|
4170
|
+
return /* @__PURE__ */ jsxs8("div", { className: "ya-embed-twitter", children: [
|
|
4171
|
+
/* @__PURE__ */ jsx14("blockquote", { className: "twitter-tweet", "data-dnt": "true", children: /* @__PURE__ */ jsx14("a", { href: embedData.originalUrl || `https://twitter.com/i/status/${src}`, children: "Loading tweet..." }) }),
|
|
4172
|
+
/* @__PURE__ */ jsx14(TwitterWidgetLoader, {})
|
|
4173
|
+
] });
|
|
4174
|
+
}
|
|
4175
|
+
if (embedType === "instagram" && src) {
|
|
4176
|
+
const embedUrl = buildInstagramEmbedUrl(src);
|
|
4177
|
+
return /* @__PURE__ */ jsx14(
|
|
4178
|
+
"iframe",
|
|
4179
|
+
{
|
|
4180
|
+
src: embedUrl,
|
|
4181
|
+
style: {
|
|
4182
|
+
width: "100%",
|
|
4183
|
+
height: "100%",
|
|
4184
|
+
aspectRatio,
|
|
4185
|
+
border: "none",
|
|
4186
|
+
minHeight: "400px"
|
|
4187
|
+
},
|
|
4188
|
+
allow: "encrypted-media",
|
|
4189
|
+
loading,
|
|
4190
|
+
title: "Instagram embed"
|
|
4191
|
+
}
|
|
4192
|
+
);
|
|
4193
|
+
}
|
|
4194
|
+
if (embedType === "custom" && src) {
|
|
4195
|
+
return /* @__PURE__ */ jsx14(
|
|
4196
|
+
"iframe",
|
|
4197
|
+
{
|
|
4198
|
+
src,
|
|
4199
|
+
style: {
|
|
4200
|
+
width: "100%",
|
|
4201
|
+
height: "100%",
|
|
4202
|
+
border: "none",
|
|
4203
|
+
aspectRatio
|
|
4204
|
+
},
|
|
4205
|
+
sandbox: "allow-scripts allow-same-origin allow-popups allow-forms",
|
|
4206
|
+
loading,
|
|
4207
|
+
title: "Embedded content"
|
|
4208
|
+
}
|
|
4209
|
+
);
|
|
4210
|
+
}
|
|
4211
|
+
return null;
|
|
4212
|
+
};
|
|
4213
|
+
const wrapperStyle = {
|
|
4214
|
+
aspectRatio: height ? void 0 : aspectRatio,
|
|
4215
|
+
height: height ? `${height}px` : void 0,
|
|
4216
|
+
maxWidth: maxWidth ? `${maxWidth}px` : void 0
|
|
4217
|
+
};
|
|
4218
|
+
if (mode === "read-only") {
|
|
4219
|
+
return /* @__PURE__ */ jsx14(
|
|
4220
|
+
"div",
|
|
4221
|
+
{
|
|
4222
|
+
ref: containerRef,
|
|
4223
|
+
className: `ya-embed-wrapper ${className || ""}`,
|
|
4224
|
+
style: wrapperStyle,
|
|
4225
|
+
"data-ya-restricted": "true",
|
|
4226
|
+
"data-field-id": fieldId,
|
|
4227
|
+
children: renderEmbed(true)
|
|
4228
|
+
}
|
|
4229
|
+
);
|
|
4230
|
+
}
|
|
4231
|
+
const embedIcon = /* @__PURE__ */ jsxs8(
|
|
4232
|
+
"svg",
|
|
4233
|
+
{
|
|
4234
|
+
width: "24",
|
|
4235
|
+
height: "24",
|
|
4236
|
+
viewBox: "0 0 24 24",
|
|
4237
|
+
fill: "none",
|
|
4238
|
+
stroke: "currentColor",
|
|
4239
|
+
strokeWidth: "2",
|
|
4240
|
+
strokeLinecap: "round",
|
|
4241
|
+
strokeLinejoin: "round",
|
|
4242
|
+
children: [
|
|
4243
|
+
/* @__PURE__ */ jsx14("polyline", { points: "16 18 22 12 16 6" }),
|
|
4244
|
+
/* @__PURE__ */ jsx14("polyline", { points: "8 6 2 12 8 18" })
|
|
4245
|
+
]
|
|
4246
|
+
}
|
|
4247
|
+
);
|
|
4248
|
+
return /* @__PURE__ */ jsxs8(
|
|
4249
|
+
"div",
|
|
4250
|
+
{
|
|
4251
|
+
ref: containerRef,
|
|
4252
|
+
className: `ya-embed-container ${isSelected ? "ya-embed-selected" : "ya-embed-editable"} ${isSmallEmbed ? "ya-embed-small" : ""}`,
|
|
4253
|
+
onClick: handleClick,
|
|
4254
|
+
onMouseEnter: () => setIsHovered(true),
|
|
4255
|
+
onMouseLeave: () => setIsHovered(false),
|
|
4256
|
+
"data-ya-restricted": "true",
|
|
4257
|
+
"data-field-id": fieldId,
|
|
4258
|
+
"data-ya-embed": "true",
|
|
4259
|
+
role: "button",
|
|
4260
|
+
tabIndex: 0,
|
|
4261
|
+
"aria-label": `Edit embed: ${fieldId}`,
|
|
4262
|
+
onKeyDown: (e) => {
|
|
4263
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
4264
|
+
e.preventDefault();
|
|
4265
|
+
handleClick();
|
|
4266
|
+
}
|
|
4267
|
+
},
|
|
4268
|
+
style: wrapperStyle,
|
|
4269
|
+
children: [
|
|
4270
|
+
renderEmbed(false),
|
|
4271
|
+
isSmallEmbed ? /* @__PURE__ */ jsxs8(YaTooltip, { anchorRef: containerRef, show: isHovered && !isSelected, children: [
|
|
4272
|
+
embedIcon,
|
|
4273
|
+
/* @__PURE__ */ jsx14("span", { children: "Click to edit" })
|
|
4274
|
+
] }) : (
|
|
4275
|
+
/* For large embeds: show overlay inside the container */
|
|
4276
|
+
/* @__PURE__ */ jsxs8("div", { className: "ya-embed-overlay", children: [
|
|
4277
|
+
/* @__PURE__ */ jsx14("div", { className: "ya-embed-edit-icon", children: embedIcon }),
|
|
4278
|
+
/* @__PURE__ */ jsx14("span", { className: "ya-embed-edit-label", children: "Click to edit" })
|
|
4279
|
+
] })
|
|
4280
|
+
)
|
|
4281
|
+
]
|
|
4282
|
+
}
|
|
4283
|
+
);
|
|
4284
|
+
}
|
|
4285
|
+
function TwitterWidgetLoader() {
|
|
4286
|
+
useEffect10(() => {
|
|
4287
|
+
if (window.twttr?.widgets) {
|
|
4288
|
+
;
|
|
4289
|
+
window.twttr.widgets.load();
|
|
4290
|
+
return;
|
|
4291
|
+
}
|
|
4292
|
+
if (document.getElementById("twitter-wjs")) {
|
|
4293
|
+
return;
|
|
4294
|
+
}
|
|
4295
|
+
const script = document.createElement("script");
|
|
4296
|
+
script.id = "twitter-wjs";
|
|
4297
|
+
script.src = "https://platform.twitter.com/widgets.js";
|
|
4298
|
+
script.async = true;
|
|
4299
|
+
document.body.appendChild(script);
|
|
4300
|
+
return () => {
|
|
4301
|
+
};
|
|
4302
|
+
}, []);
|
|
4303
|
+
return null;
|
|
4304
|
+
}
|
|
4305
|
+
|
|
3870
4306
|
// src/components/YaLink.tsx
|
|
3871
|
-
import { useEffect as
|
|
4307
|
+
import { useEffect as useEffect13, useRef as useRef13, useState as useState12, useCallback as useCallback14, useId } from "react";
|
|
3872
4308
|
import { createPortal as createPortal5 } from "react-dom";
|
|
3873
4309
|
import { useEditor as useEditor2, EditorContent as EditorContent2 } from "@tiptap/react";
|
|
3874
4310
|
import { BubbleMenu } from "@tiptap/react/menus";
|
|
@@ -3878,7 +4314,7 @@ import { Extension as Extension2 } from "@tiptap/core";
|
|
|
3878
4314
|
import { Link as WouterLink, useLocation } from "wouter";
|
|
3879
4315
|
|
|
3880
4316
|
// src/components/SafeTriangleBelow.tsx
|
|
3881
|
-
import { useEffect as
|
|
4317
|
+
import { useEffect as useEffect11, useState as useState10, useRef as useRef11, useCallback as useCallback12 } from "react";
|
|
3882
4318
|
function SafeTriangleBelow({
|
|
3883
4319
|
triggerRef,
|
|
3884
4320
|
popoverRef,
|
|
@@ -3886,10 +4322,10 @@ function SafeTriangleBelow({
|
|
|
3886
4322
|
onLeave,
|
|
3887
4323
|
onStayInside
|
|
3888
4324
|
}) {
|
|
3889
|
-
const [bounds, setBounds] =
|
|
3890
|
-
const boundsRef =
|
|
4325
|
+
const [bounds, setBounds] = useState10(null);
|
|
4326
|
+
const boundsRef = useRef11(bounds);
|
|
3891
4327
|
boundsRef.current = bounds;
|
|
3892
|
-
|
|
4328
|
+
useEffect11(() => {
|
|
3893
4329
|
if (!isVisible || !triggerRef.current || !popoverRef.current) {
|
|
3894
4330
|
setBounds(null);
|
|
3895
4331
|
return;
|
|
@@ -3907,7 +4343,7 @@ function SafeTriangleBelow({
|
|
|
3907
4343
|
}, 10);
|
|
3908
4344
|
return () => clearTimeout(timer);
|
|
3909
4345
|
}, [isVisible, triggerRef, popoverRef]);
|
|
3910
|
-
const checkMousePosition =
|
|
4346
|
+
const checkMousePosition = useCallback12((e) => {
|
|
3911
4347
|
const b = boundsRef.current;
|
|
3912
4348
|
if (!b) return;
|
|
3913
4349
|
const { clientX: x, clientY: y } = e;
|
|
@@ -3919,7 +4355,7 @@ function SafeTriangleBelow({
|
|
|
3919
4355
|
onStayInside?.();
|
|
3920
4356
|
}
|
|
3921
4357
|
}, [onLeave, onStayInside]);
|
|
3922
|
-
|
|
4358
|
+
useEffect11(() => {
|
|
3923
4359
|
if (!isVisible || !bounds) return;
|
|
3924
4360
|
document.addEventListener("mousemove", checkMousePosition);
|
|
3925
4361
|
return () => document.removeEventListener("mousemove", checkMousePosition);
|
|
@@ -3928,22 +4364,22 @@ function SafeTriangleBelow({
|
|
|
3928
4364
|
}
|
|
3929
4365
|
|
|
3930
4366
|
// src/hooks/useSafeTriangle.ts
|
|
3931
|
-
import { useState as
|
|
4367
|
+
import { useState as useState11, useRef as useRef12, useCallback as useCallback13, useEffect as useEffect12 } from "react";
|
|
3932
4368
|
function useSafeTriangle(options = {}) {
|
|
3933
4369
|
const { showDelay = 0, hideDelay = 150, enabled = true } = options;
|
|
3934
|
-
const [isVisible, setIsVisible] =
|
|
3935
|
-
const [isHovering, setIsHovering] =
|
|
3936
|
-
const triggerRef =
|
|
3937
|
-
const popoverRef =
|
|
3938
|
-
const showTimeoutRef =
|
|
3939
|
-
const hideTimeoutRef =
|
|
3940
|
-
|
|
4370
|
+
const [isVisible, setIsVisible] = useState11(false);
|
|
4371
|
+
const [isHovering, setIsHovering] = useState11(false);
|
|
4372
|
+
const triggerRef = useRef12(null);
|
|
4373
|
+
const popoverRef = useRef12(null);
|
|
4374
|
+
const showTimeoutRef = useRef12(null);
|
|
4375
|
+
const hideTimeoutRef = useRef12(null);
|
|
4376
|
+
useEffect12(() => {
|
|
3941
4377
|
return () => {
|
|
3942
4378
|
if (showTimeoutRef.current) clearTimeout(showTimeoutRef.current);
|
|
3943
4379
|
if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);
|
|
3944
4380
|
};
|
|
3945
4381
|
}, []);
|
|
3946
|
-
const show =
|
|
4382
|
+
const show = useCallback13(() => {
|
|
3947
4383
|
if (!enabled) return;
|
|
3948
4384
|
if (hideTimeoutRef.current) {
|
|
3949
4385
|
clearTimeout(hideTimeoutRef.current);
|
|
@@ -3951,7 +4387,7 @@ function useSafeTriangle(options = {}) {
|
|
|
3951
4387
|
}
|
|
3952
4388
|
setIsVisible(true);
|
|
3953
4389
|
}, [enabled]);
|
|
3954
|
-
const hide =
|
|
4390
|
+
const hide = useCallback13(() => {
|
|
3955
4391
|
if (showTimeoutRef.current) {
|
|
3956
4392
|
clearTimeout(showTimeoutRef.current);
|
|
3957
4393
|
showTimeoutRef.current = null;
|
|
@@ -3959,7 +4395,7 @@ function useSafeTriangle(options = {}) {
|
|
|
3959
4395
|
setIsVisible(false);
|
|
3960
4396
|
setIsHovering(false);
|
|
3961
4397
|
}, []);
|
|
3962
|
-
const handleMouseEnter =
|
|
4398
|
+
const handleMouseEnter = useCallback13(() => {
|
|
3963
4399
|
if (!enabled) return;
|
|
3964
4400
|
setIsHovering(true);
|
|
3965
4401
|
if (hideTimeoutRef.current) {
|
|
@@ -3974,7 +4410,7 @@ function useSafeTriangle(options = {}) {
|
|
|
3974
4410
|
setIsVisible(true);
|
|
3975
4411
|
}
|
|
3976
4412
|
}, [showDelay, enabled]);
|
|
3977
|
-
const handleMouseLeave =
|
|
4413
|
+
const handleMouseLeave = useCallback13(() => {
|
|
3978
4414
|
setIsHovering(false);
|
|
3979
4415
|
if (showTimeoutRef.current) {
|
|
3980
4416
|
clearTimeout(showTimeoutRef.current);
|
|
@@ -3984,16 +4420,16 @@ function useSafeTriangle(options = {}) {
|
|
|
3984
4420
|
setIsVisible(false);
|
|
3985
4421
|
}, hideDelay);
|
|
3986
4422
|
}, [hideDelay]);
|
|
3987
|
-
const handleFocus =
|
|
4423
|
+
const handleFocus = useCallback13(() => {
|
|
3988
4424
|
if (!enabled) return;
|
|
3989
4425
|
setIsVisible(true);
|
|
3990
4426
|
}, [enabled]);
|
|
3991
|
-
const handleTriangleLeave =
|
|
4427
|
+
const handleTriangleLeave = useCallback13(() => {
|
|
3992
4428
|
if (!isHovering) {
|
|
3993
4429
|
setIsVisible(false);
|
|
3994
4430
|
}
|
|
3995
4431
|
}, [isHovering]);
|
|
3996
|
-
const handleStayInside =
|
|
4432
|
+
const handleStayInside = useCallback13(() => {
|
|
3997
4433
|
if (hideTimeoutRef.current) {
|
|
3998
4434
|
clearTimeout(hideTimeoutRef.current);
|
|
3999
4435
|
hideTimeoutRef.current = null;
|
|
@@ -4024,7 +4460,7 @@ function useSafeTriangle(options = {}) {
|
|
|
4024
4460
|
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-editing .ProseMirror {\n color: #1a1a1a !important;\n caret-color: #1a1a1a;\n}\n.ya-link-editing .ProseMirror p::selection,\n.ya-link-editing .ProseMirror::selection {\n background-color: rgba(212, 165, 116, 0.4);\n color: inherit;\n}\n.ya-link-editing .ProseMirror p::-moz-selection,\n.ya-link-editing .ProseMirror::-moz-selection {\n background-color: rgba(212, 165, 116, 0.4);\n color: inherit;\n}\nbody.builder-selector-active .ya-link-editable:not(.ya-link-editing)::selection,\nbody.builder-selector-active .ya-link-editable:not(.ya-link-editing) *::selection {\n color: inherit;\n}\nbody.builder-selector-active .ya-link-editable:not(.ya-link-editing)::-moz-selection,\nbody.builder-selector-active .ya-link-editable:not(.ya-link-editing) *::-moz-selection {\n color: inherit;\n}\n.ya-link-actions {\n display: flex;\n gap: 8px;\n z-index: 9999;\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: 100;\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-href-popover--above {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: 8px;\n animation: ya-href-popover-fade-in-above 0.15s ease;\n}\n@keyframes ya-href-popover-fade-in-above {\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--above::before {\n top: auto;\n bottom: -6px;\n border-bottom: none;\n border-top: 8px solid #1a1a1a;\n}\n.ya-link-edit-popover {\n position: absolute;\n top: 100%;\n left: 50%;\n margin-top: 8px;\n z-index: 100;\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');
|
|
4025
4461
|
|
|
4026
4462
|
// src/components/YaLink.tsx
|
|
4027
|
-
import { Fragment as Fragment4, jsx as
|
|
4463
|
+
import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4028
4464
|
function isInternalPath(path) {
|
|
4029
4465
|
if (!path) return false;
|
|
4030
4466
|
if (path.startsWith("#")) return false;
|
|
@@ -4125,8 +4561,8 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4125
4561
|
const { getValue, setValue, mode, saveToWorker, getPages } = useContentStore();
|
|
4126
4562
|
const [, navigate] = useLocation();
|
|
4127
4563
|
const pages = availablePages ?? getPages();
|
|
4128
|
-
const [sections, setSections] =
|
|
4129
|
-
const [sectionsExpanded, setSectionsExpanded] =
|
|
4564
|
+
const [sections, setSections] = useState12([]);
|
|
4565
|
+
const [sectionsExpanded, setSectionsExpanded] = useState12(false);
|
|
4130
4566
|
const textFieldId = `${fieldId}.text`;
|
|
4131
4567
|
const hrefFieldId = `${fieldId}.href`;
|
|
4132
4568
|
const storeText = getValue(textFieldId);
|
|
@@ -4137,19 +4573,19 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4137
4573
|
const isExternal = isExternalHref(href);
|
|
4138
4574
|
const effectiveTarget = target ?? (isExternal ? "_blank" : void 0);
|
|
4139
4575
|
const effectiveRel = rel ?? (isExternal ? "noopener noreferrer" : void 0);
|
|
4140
|
-
const [editingMode, setEditingMode] =
|
|
4141
|
-
const [originalText, setOriginalText] =
|
|
4142
|
-
const [originalHref, setOriginalHref] =
|
|
4143
|
-
const [currentHref, setCurrentHref] =
|
|
4144
|
-
const [isExternalUrl, setIsExternalUrl] =
|
|
4145
|
-
const [externalUrl, setExternalUrl] =
|
|
4146
|
-
const [popoverPosition, setPopoverPosition] =
|
|
4147
|
-
const containerRef =
|
|
4148
|
-
const hrefPopoverRef =
|
|
4149
|
-
const [actionButtonsPos, setActionButtonsPos] =
|
|
4150
|
-
const handleSaveTextRef =
|
|
4576
|
+
const [editingMode, setEditingMode] = useState12(null);
|
|
4577
|
+
const [originalText, setOriginalText] = useState12(text);
|
|
4578
|
+
const [originalHref, setOriginalHref] = useState12(href);
|
|
4579
|
+
const [currentHref, setCurrentHref] = useState12(href);
|
|
4580
|
+
const [isExternalUrl, setIsExternalUrl] = useState12(false);
|
|
4581
|
+
const [externalUrl, setExternalUrl] = useState12("");
|
|
4582
|
+
const [popoverPosition, setPopoverPosition] = useState12("below");
|
|
4583
|
+
const containerRef = useRef13(null);
|
|
4584
|
+
const hrefPopoverRef = useRef13(null);
|
|
4585
|
+
const [actionButtonsPos, setActionButtonsPos] = useState12(null);
|
|
4586
|
+
const handleSaveTextRef = useRef13(() => {
|
|
4151
4587
|
});
|
|
4152
|
-
const handleCancelTextRef =
|
|
4588
|
+
const handleCancelTextRef = useRef13(() => {
|
|
4153
4589
|
});
|
|
4154
4590
|
const {
|
|
4155
4591
|
popoverRef: editPopoverRef,
|
|
@@ -4163,12 +4599,12 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4163
4599
|
});
|
|
4164
4600
|
const triggerRef = containerRef;
|
|
4165
4601
|
const instanceId = useId();
|
|
4166
|
-
|
|
4602
|
+
useEffect13(() => {
|
|
4167
4603
|
if (showEditPopover && mode === "inline-edit" && !editingMode) {
|
|
4168
4604
|
window.dispatchEvent(new CustomEvent("yalink:popover-open", { detail: { id: instanceId } }));
|
|
4169
4605
|
}
|
|
4170
4606
|
}, [showEditPopover, mode, editingMode, instanceId]);
|
|
4171
|
-
|
|
4607
|
+
useEffect13(() => {
|
|
4172
4608
|
const handleOtherPopoverOpen = (event) => {
|
|
4173
4609
|
const customEvent = event;
|
|
4174
4610
|
if (customEvent.detail.id !== instanceId && showEditPopover) {
|
|
@@ -4219,19 +4655,19 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4219
4655
|
}
|
|
4220
4656
|
}
|
|
4221
4657
|
});
|
|
4222
|
-
|
|
4658
|
+
useEffect13(() => {
|
|
4223
4659
|
if (editor && editingMode !== "text") {
|
|
4224
4660
|
if (editor.getHTML() !== text) {
|
|
4225
4661
|
editor.commands.setContent(text);
|
|
4226
4662
|
}
|
|
4227
4663
|
}
|
|
4228
4664
|
}, [text, editor, editingMode]);
|
|
4229
|
-
|
|
4665
|
+
useEffect13(() => {
|
|
4230
4666
|
if (editingMode !== "link") {
|
|
4231
4667
|
setCurrentHref(href);
|
|
4232
4668
|
}
|
|
4233
4669
|
}, [href, editingMode]);
|
|
4234
|
-
|
|
4670
|
+
useEffect13(() => {
|
|
4235
4671
|
if (editingMode !== "text" || !containerRef.current) {
|
|
4236
4672
|
setActionButtonsPos(null);
|
|
4237
4673
|
return;
|
|
@@ -4252,7 +4688,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4252
4688
|
window.removeEventListener("resize", updatePosition);
|
|
4253
4689
|
};
|
|
4254
4690
|
}, [editingMode]);
|
|
4255
|
-
|
|
4691
|
+
useEffect13(() => {
|
|
4256
4692
|
if (editingMode !== "link") return;
|
|
4257
4693
|
const handleClickOutside = (event) => {
|
|
4258
4694
|
const target2 = event.target;
|
|
@@ -4266,7 +4702,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4266
4702
|
document.addEventListener("mousedown", handleClickOutside);
|
|
4267
4703
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
4268
4704
|
}, [editingMode, originalHref]);
|
|
4269
|
-
|
|
4705
|
+
useEffect13(() => {
|
|
4270
4706
|
if (editingMode !== "link" || !containerRef.current) return;
|
|
4271
4707
|
const updatePosition = () => {
|
|
4272
4708
|
if (!containerRef.current) return;
|
|
@@ -4279,7 +4715,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4279
4715
|
window.addEventListener("resize", updatePosition);
|
|
4280
4716
|
return () => window.removeEventListener("resize", updatePosition);
|
|
4281
4717
|
}, [editingMode]);
|
|
4282
|
-
const handleSaveText =
|
|
4718
|
+
const handleSaveText = useCallback14(() => {
|
|
4283
4719
|
if (!editor) return;
|
|
4284
4720
|
let html = editor.getHTML();
|
|
4285
4721
|
html = html.replace(/<\/p><p>/g, "<br><br>").replace(/^<p>/, "").replace(/<\/p>$/, "");
|
|
@@ -4287,30 +4723,30 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4287
4723
|
saveToWorker?.(textFieldId, html);
|
|
4288
4724
|
setEditingMode(null);
|
|
4289
4725
|
}, [editor, textFieldId, setValue, saveToWorker]);
|
|
4290
|
-
const handleSaveLink =
|
|
4726
|
+
const handleSaveLink = useCallback14(() => {
|
|
4291
4727
|
setValue(hrefFieldId, currentHref, "user");
|
|
4292
4728
|
saveToWorker?.(hrefFieldId, currentHref);
|
|
4293
4729
|
setEditingMode(null);
|
|
4294
4730
|
setIsExternalUrl(false);
|
|
4295
4731
|
setExternalUrl("");
|
|
4296
4732
|
}, [hrefFieldId, currentHref, setValue, saveToWorker]);
|
|
4297
|
-
const handleCancelText =
|
|
4733
|
+
const handleCancelText = useCallback14(() => {
|
|
4298
4734
|
if (editor) {
|
|
4299
4735
|
editor.commands.setContent(originalText);
|
|
4300
4736
|
}
|
|
4301
4737
|
setEditingMode(null);
|
|
4302
4738
|
}, [editor, originalText]);
|
|
4303
|
-
const handleCancelLink =
|
|
4739
|
+
const handleCancelLink = useCallback14(() => {
|
|
4304
4740
|
setCurrentHref(originalHref);
|
|
4305
4741
|
setEditingMode(null);
|
|
4306
4742
|
setIsExternalUrl(false);
|
|
4307
4743
|
setExternalUrl("");
|
|
4308
4744
|
}, [originalHref]);
|
|
4309
|
-
|
|
4745
|
+
useEffect13(() => {
|
|
4310
4746
|
handleSaveTextRef.current = handleSaveText;
|
|
4311
4747
|
handleCancelTextRef.current = handleCancelText;
|
|
4312
4748
|
}, [handleSaveText, handleCancelText]);
|
|
4313
|
-
const handleClick =
|
|
4749
|
+
const handleClick = useCallback14(
|
|
4314
4750
|
(e) => {
|
|
4315
4751
|
const selectModeEnabled = window.__builderSelectModeEnabled;
|
|
4316
4752
|
if (selectModeEnabled) {
|
|
@@ -4342,7 +4778,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4342
4778
|
},
|
|
4343
4779
|
[href, navigate, onClick]
|
|
4344
4780
|
);
|
|
4345
|
-
const startEditText =
|
|
4781
|
+
const startEditText = useCallback14(() => {
|
|
4346
4782
|
hideEditPopover();
|
|
4347
4783
|
if (isIconMode) {
|
|
4348
4784
|
window.dispatchEvent(new CustomEvent("yatext:edit-mode", {
|
|
@@ -4356,7 +4792,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4356
4792
|
}, 20);
|
|
4357
4793
|
}
|
|
4358
4794
|
}, [text, editor, hideEditPopover, isIconMode, fieldId]);
|
|
4359
|
-
const startEditLink =
|
|
4795
|
+
const startEditLink = useCallback14(() => {
|
|
4360
4796
|
hideEditPopover();
|
|
4361
4797
|
setEditingMode("link");
|
|
4362
4798
|
setOriginalHref(href);
|
|
@@ -4370,7 +4806,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4370
4806
|
setPopoverPosition(spaceBelow < popoverHeight && spaceAbove > spaceBelow ? "above" : "below");
|
|
4371
4807
|
}
|
|
4372
4808
|
}, [href, hideEditPopover]);
|
|
4373
|
-
const handleKeyDown =
|
|
4809
|
+
const handleKeyDown = useCallback14(
|
|
4374
4810
|
(event) => {
|
|
4375
4811
|
if (editingMode !== "text") return;
|
|
4376
4812
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
@@ -4391,7 +4827,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4391
4827
|
},
|
|
4392
4828
|
[editingMode, handleSaveText, handleCancelText]
|
|
4393
4829
|
);
|
|
4394
|
-
const handleFontSizeChange =
|
|
4830
|
+
const handleFontSizeChange = useCallback14(
|
|
4395
4831
|
(e) => {
|
|
4396
4832
|
if (!editor) return;
|
|
4397
4833
|
const size = e.target.value;
|
|
@@ -4403,7 +4839,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4403
4839
|
},
|
|
4404
4840
|
[editor]
|
|
4405
4841
|
);
|
|
4406
|
-
const handleFontWeightChange =
|
|
4842
|
+
const handleFontWeightChange = useCallback14(
|
|
4407
4843
|
(e) => {
|
|
4408
4844
|
if (!editor) return;
|
|
4409
4845
|
const weight = e.target.value;
|
|
@@ -4415,11 +4851,11 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4415
4851
|
},
|
|
4416
4852
|
[editor]
|
|
4417
4853
|
);
|
|
4418
|
-
const handlePageSelect =
|
|
4854
|
+
const handlePageSelect = useCallback14((path) => {
|
|
4419
4855
|
setCurrentHref(path);
|
|
4420
4856
|
setIsExternalUrl(false);
|
|
4421
4857
|
}, []);
|
|
4422
|
-
const handleExternalUrlApply =
|
|
4858
|
+
const handleExternalUrlApply = useCallback14(() => {
|
|
4423
4859
|
if (externalUrl) {
|
|
4424
4860
|
setCurrentHref(externalUrl);
|
|
4425
4861
|
}
|
|
@@ -4435,9 +4871,9 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4435
4871
|
return attrs.fontWeight || "";
|
|
4436
4872
|
};
|
|
4437
4873
|
if (mode === "read-only") {
|
|
4438
|
-
const content = isIconMode ? children : /* @__PURE__ */
|
|
4874
|
+
const content = isIconMode ? children : /* @__PURE__ */ jsx15(SafeHtml, { content: text, mode });
|
|
4439
4875
|
if (isInternalPath(href)) {
|
|
4440
|
-
return /* @__PURE__ */
|
|
4876
|
+
return /* @__PURE__ */ jsx15(
|
|
4441
4877
|
WouterLink,
|
|
4442
4878
|
{
|
|
4443
4879
|
href,
|
|
@@ -4449,7 +4885,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4449
4885
|
}
|
|
4450
4886
|
);
|
|
4451
4887
|
}
|
|
4452
|
-
return /* @__PURE__ */
|
|
4888
|
+
return /* @__PURE__ */ jsx15(
|
|
4453
4889
|
Component,
|
|
4454
4890
|
{
|
|
4455
4891
|
ref: containerRef,
|
|
@@ -4464,8 +4900,8 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4464
4900
|
}
|
|
4465
4901
|
);
|
|
4466
4902
|
}
|
|
4467
|
-
return /* @__PURE__ */
|
|
4468
|
-
/* @__PURE__ */
|
|
4903
|
+
return /* @__PURE__ */ jsxs9("span", { className: "ya-link-wrapper", children: [
|
|
4904
|
+
/* @__PURE__ */ jsx15(
|
|
4469
4905
|
Component,
|
|
4470
4906
|
{
|
|
4471
4907
|
ref: containerRef,
|
|
@@ -4484,9 +4920,9 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4484
4920
|
children: isIconMode ? (
|
|
4485
4921
|
// Icon mode: render children directly, no text editing
|
|
4486
4922
|
children
|
|
4487
|
-
) : editor ? /* @__PURE__ */
|
|
4923
|
+
) : editor ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
4488
4924
|
createPortal5(
|
|
4489
|
-
/* @__PURE__ */
|
|
4925
|
+
/* @__PURE__ */ jsxs9(
|
|
4490
4926
|
BubbleMenu,
|
|
4491
4927
|
{
|
|
4492
4928
|
editor,
|
|
@@ -4494,28 +4930,28 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4494
4930
|
options: { offset: 6, placement: "top" },
|
|
4495
4931
|
className: "ya-bubble-menu",
|
|
4496
4932
|
children: [
|
|
4497
|
-
/* @__PURE__ */
|
|
4933
|
+
/* @__PURE__ */ jsx15(
|
|
4498
4934
|
"button",
|
|
4499
4935
|
{
|
|
4500
4936
|
type: "button",
|
|
4501
4937
|
onClick: () => editor.chain().focus().toggleBold().run(),
|
|
4502
4938
|
className: `ya-bubble-btn ${editor.isActive("bold") ? "is-active" : ""}`,
|
|
4503
4939
|
title: "Bold",
|
|
4504
|
-
children: /* @__PURE__ */
|
|
4940
|
+
children: /* @__PURE__ */ jsx15("strong", { children: "B" })
|
|
4505
4941
|
}
|
|
4506
4942
|
),
|
|
4507
|
-
/* @__PURE__ */
|
|
4943
|
+
/* @__PURE__ */ jsx15(
|
|
4508
4944
|
"button",
|
|
4509
4945
|
{
|
|
4510
4946
|
type: "button",
|
|
4511
4947
|
onClick: () => editor.chain().focus().toggleItalic().run(),
|
|
4512
4948
|
className: `ya-bubble-btn ${editor.isActive("italic") ? "is-active" : ""}`,
|
|
4513
4949
|
title: "Italic",
|
|
4514
|
-
children: /* @__PURE__ */
|
|
4950
|
+
children: /* @__PURE__ */ jsx15("em", { children: "I" })
|
|
4515
4951
|
}
|
|
4516
4952
|
),
|
|
4517
|
-
/* @__PURE__ */
|
|
4518
|
-
/* @__PURE__ */
|
|
4953
|
+
/* @__PURE__ */ jsx15("span", { className: "ya-bubble-divider" }),
|
|
4954
|
+
/* @__PURE__ */ jsxs9(
|
|
4519
4955
|
"select",
|
|
4520
4956
|
{
|
|
4521
4957
|
value: getCurrentFontSize(),
|
|
@@ -4523,12 +4959,12 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4523
4959
|
className: "ya-bubble-select",
|
|
4524
4960
|
title: "Font Size",
|
|
4525
4961
|
children: [
|
|
4526
|
-
/* @__PURE__ */
|
|
4527
|
-
Object.entries(SIZE_PRESETS2).map(([name, size]) => /* @__PURE__ */
|
|
4962
|
+
/* @__PURE__ */ jsx15("option", { value: "", children: "Size" }),
|
|
4963
|
+
Object.entries(SIZE_PRESETS2).map(([name, size]) => /* @__PURE__ */ jsx15("option", { value: size, children: name }, name))
|
|
4528
4964
|
]
|
|
4529
4965
|
}
|
|
4530
4966
|
),
|
|
4531
|
-
/* @__PURE__ */
|
|
4967
|
+
/* @__PURE__ */ jsxs9(
|
|
4532
4968
|
"select",
|
|
4533
4969
|
{
|
|
4534
4970
|
value: getCurrentFontWeight(),
|
|
@@ -4536,8 +4972,8 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4536
4972
|
className: "ya-bubble-select",
|
|
4537
4973
|
title: "Font Weight",
|
|
4538
4974
|
children: [
|
|
4539
|
-
/* @__PURE__ */
|
|
4540
|
-
Object.entries(WEIGHT_PRESETS2).map(([name, weight]) => /* @__PURE__ */
|
|
4975
|
+
/* @__PURE__ */ jsx15("option", { value: "", children: "Weight" }),
|
|
4976
|
+
Object.entries(WEIGHT_PRESETS2).map(([name, weight]) => /* @__PURE__ */ jsx15("option", { value: weight, children: name }, name))
|
|
4541
4977
|
]
|
|
4542
4978
|
}
|
|
4543
4979
|
)
|
|
@@ -4546,10 +4982,10 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4546
4982
|
),
|
|
4547
4983
|
document.body
|
|
4548
4984
|
),
|
|
4549
|
-
editingMode === "text" ? /* @__PURE__ */
|
|
4550
|
-
/* @__PURE__ */
|
|
4985
|
+
editingMode === "text" ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
4986
|
+
/* @__PURE__ */ jsx15(EditorContent2, { editor }),
|
|
4551
4987
|
actionButtonsPos && createPortal5(
|
|
4552
|
-
/* @__PURE__ */
|
|
4988
|
+
/* @__PURE__ */ jsxs9(
|
|
4553
4989
|
"div",
|
|
4554
4990
|
{
|
|
4555
4991
|
className: "ya-link-actions",
|
|
@@ -4559,18 +4995,18 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4559
4995
|
right: actionButtonsPos.right
|
|
4560
4996
|
},
|
|
4561
4997
|
children: [
|
|
4562
|
-
/* @__PURE__ */
|
|
4563
|
-
/* @__PURE__ */
|
|
4998
|
+
/* @__PURE__ */ jsx15("button", { type: "button", onClick: handleCancelText, className: "ya-link-btn ya-link-btn-cancel", children: "Cancel" }),
|
|
4999
|
+
/* @__PURE__ */ jsx15("button", { type: "button", onClick: handleSaveText, className: "ya-link-btn ya-link-btn-save", children: "Save" })
|
|
4564
5000
|
]
|
|
4565
5001
|
}
|
|
4566
5002
|
),
|
|
4567
5003
|
document.body
|
|
4568
5004
|
)
|
|
4569
|
-
] }) : /* @__PURE__ */
|
|
4570
|
-
] }) : /* @__PURE__ */
|
|
5005
|
+
] }) : /* @__PURE__ */ jsx15(SafeHtml, { content: text, mode })
|
|
5006
|
+
] }) : /* @__PURE__ */ jsx15(SafeHtml, { content: text, mode })
|
|
4571
5007
|
}
|
|
4572
5008
|
),
|
|
4573
|
-
showEditPopover && !editingMode && mode === "inline-edit" && /* @__PURE__ */
|
|
5009
|
+
showEditPopover && !editingMode && mode === "inline-edit" && /* @__PURE__ */ jsxs9(
|
|
4574
5010
|
"div",
|
|
4575
5011
|
{
|
|
4576
5012
|
ref: editPopoverRef,
|
|
@@ -4578,12 +5014,12 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4578
5014
|
onMouseEnter: safeTriangleHandlers.onMouseEnter,
|
|
4579
5015
|
onMouseLeave: safeTriangleHandlers.onMouseLeave,
|
|
4580
5016
|
children: [
|
|
4581
|
-
/* @__PURE__ */
|
|
4582
|
-
/* @__PURE__ */
|
|
5017
|
+
/* @__PURE__ */ jsx15("button", { type: "button", onClick: startEditText, children: "Edit text" }),
|
|
5018
|
+
/* @__PURE__ */ jsx15("button", { type: "button", onClick: startEditLink, children: "Edit link" })
|
|
4583
5019
|
]
|
|
4584
5020
|
}
|
|
4585
5021
|
),
|
|
4586
|
-
/* @__PURE__ */
|
|
5022
|
+
/* @__PURE__ */ jsx15(
|
|
4587
5023
|
SafeTriangleBelow,
|
|
4588
5024
|
{
|
|
4589
5025
|
triggerRef,
|
|
@@ -4593,25 +5029,25 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4593
5029
|
onStayInside: triangleProps.onStayInside
|
|
4594
5030
|
}
|
|
4595
5031
|
),
|
|
4596
|
-
editingMode === "link" && /* @__PURE__ */
|
|
4597
|
-
/* @__PURE__ */
|
|
4598
|
-
!isExternalUrl ? /* @__PURE__ */
|
|
4599
|
-
sections.length > 0 && /* @__PURE__ */
|
|
4600
|
-
/* @__PURE__ */
|
|
5032
|
+
editingMode === "link" && /* @__PURE__ */ jsxs9("div", { ref: hrefPopoverRef, className: `ya-href-popover ${popoverPosition === "above" ? "ya-href-popover--above" : ""}`, children: [
|
|
5033
|
+
/* @__PURE__ */ jsx15("div", { className: "ya-href-popover-header", children: "Link destination" }),
|
|
5034
|
+
!isExternalUrl ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
5035
|
+
sections.length > 0 && /* @__PURE__ */ jsxs9("div", { className: "ya-href-popover-section", children: [
|
|
5036
|
+
/* @__PURE__ */ jsxs9(
|
|
4601
5037
|
"button",
|
|
4602
5038
|
{
|
|
4603
5039
|
type: "button",
|
|
4604
5040
|
className: "ya-href-popover-label ya-href-collapsible-header",
|
|
4605
5041
|
onClick: () => setSectionsExpanded(!sectionsExpanded),
|
|
4606
5042
|
children: [
|
|
4607
|
-
/* @__PURE__ */
|
|
5043
|
+
/* @__PURE__ */ jsx15("span", { className: "ya-href-chevron", children: sectionsExpanded ? "\u25BC" : "\u25B6" }),
|
|
4608
5044
|
"Scroll to section (",
|
|
4609
5045
|
sections.length,
|
|
4610
5046
|
")"
|
|
4611
5047
|
]
|
|
4612
5048
|
}
|
|
4613
5049
|
),
|
|
4614
|
-
sectionsExpanded && /* @__PURE__ */
|
|
5050
|
+
sectionsExpanded && /* @__PURE__ */ jsx15("div", { className: "ya-href-popover-pages", children: sections.map((section) => /* @__PURE__ */ jsxs9(
|
|
4615
5051
|
"button",
|
|
4616
5052
|
{
|
|
4617
5053
|
type: "button",
|
|
@@ -4619,15 +5055,15 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4619
5055
|
onClick: () => handlePageSelect(section.path),
|
|
4620
5056
|
children: [
|
|
4621
5057
|
section.label,
|
|
4622
|
-
/* @__PURE__ */
|
|
5058
|
+
/* @__PURE__ */ jsx15("span", { className: "ya-href-page-path", children: section.path })
|
|
4623
5059
|
]
|
|
4624
5060
|
},
|
|
4625
5061
|
section.path
|
|
4626
5062
|
)) })
|
|
4627
5063
|
] }),
|
|
4628
|
-
pages.length > 0 && /* @__PURE__ */
|
|
4629
|
-
/* @__PURE__ */
|
|
4630
|
-
/* @__PURE__ */
|
|
5064
|
+
pages.length > 0 && /* @__PURE__ */ jsxs9("div", { className: "ya-href-popover-section", children: [
|
|
5065
|
+
/* @__PURE__ */ jsx15("label", { className: "ya-href-popover-label", children: "Navigate to page" }),
|
|
5066
|
+
/* @__PURE__ */ jsx15("div", { className: "ya-href-popover-pages", children: pages.map((page) => /* @__PURE__ */ jsxs9(
|
|
4631
5067
|
"button",
|
|
4632
5068
|
{
|
|
4633
5069
|
type: "button",
|
|
@@ -4635,13 +5071,13 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4635
5071
|
onClick: () => handlePageSelect(page.path),
|
|
4636
5072
|
children: [
|
|
4637
5073
|
page.label,
|
|
4638
|
-
/* @__PURE__ */
|
|
5074
|
+
/* @__PURE__ */ jsx15("span", { className: "ya-href-page-path", children: page.path })
|
|
4639
5075
|
]
|
|
4640
5076
|
},
|
|
4641
5077
|
page.path
|
|
4642
5078
|
)) })
|
|
4643
5079
|
] }),
|
|
4644
|
-
/* @__PURE__ */
|
|
5080
|
+
/* @__PURE__ */ jsx15(
|
|
4645
5081
|
"button",
|
|
4646
5082
|
{
|
|
4647
5083
|
type: "button",
|
|
@@ -4653,10 +5089,10 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4653
5089
|
children: "Use external URL instead"
|
|
4654
5090
|
}
|
|
4655
5091
|
)
|
|
4656
|
-
] }) : /* @__PURE__ */
|
|
4657
|
-
/* @__PURE__ */
|
|
4658
|
-
/* @__PURE__ */
|
|
4659
|
-
/* @__PURE__ */
|
|
5092
|
+
] }) : /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
5093
|
+
/* @__PURE__ */ jsxs9("div", { className: "ya-href-popover-section", children: [
|
|
5094
|
+
/* @__PURE__ */ jsx15("label", { className: "ya-href-popover-label", children: "External URL" }),
|
|
5095
|
+
/* @__PURE__ */ jsx15(
|
|
4660
5096
|
"input",
|
|
4661
5097
|
{
|
|
4662
5098
|
type: "url",
|
|
@@ -4668,18 +5104,18 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
4668
5104
|
}
|
|
4669
5105
|
)
|
|
4670
5106
|
] }),
|
|
4671
|
-
/* @__PURE__ */
|
|
5107
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "ya-href-external-toggle", onClick: () => setIsExternalUrl(false), children: "\u2190 Back to pages" })
|
|
4672
5108
|
] }),
|
|
4673
|
-
/* @__PURE__ */
|
|
4674
|
-
/* @__PURE__ */
|
|
4675
|
-
isExternalUrl ? /* @__PURE__ */
|
|
5109
|
+
/* @__PURE__ */ jsxs9("div", { className: "ya-href-popover-actions", children: [
|
|
5110
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "ya-link-btn ya-link-btn-cancel", onClick: handleCancelLink, children: "Cancel" }),
|
|
5111
|
+
isExternalUrl ? /* @__PURE__ */ jsx15("button", { type: "button", className: "ya-link-btn ya-link-btn-save", onClick: handleExternalUrlApply, children: "Apply" }) : /* @__PURE__ */ jsx15("button", { type: "button", className: "ya-link-btn ya-link-btn-save", onClick: handleSaveLink, children: "Save" })
|
|
4676
5112
|
] })
|
|
4677
5113
|
] })
|
|
4678
5114
|
] });
|
|
4679
5115
|
}
|
|
4680
5116
|
|
|
4681
5117
|
// src/components/YaContainer.tsx
|
|
4682
|
-
import { useCallback as
|
|
5118
|
+
import { useCallback as useCallback15, useEffect as useEffect14, useRef as useRef14, useState as useState13 } from "react";
|
|
4683
5119
|
import { createPortal as createPortal6 } from "react-dom";
|
|
4684
5120
|
import {
|
|
4685
5121
|
useFloating as useFloating3,
|
|
@@ -4695,7 +5131,7 @@ import {
|
|
|
4695
5131
|
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 pointer-events: none;\n}\n.ya-container-editable > * {\n pointer-events: auto;\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: 36px;\n height: 36px;\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: 18px;\n height: 18px;\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 pointer-events: auto !important;\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.ya-container-tooltip {\n background: #1a1a1a;\n color: white;\n padding: 8px 12px;\n border-radius: 6px;\n font-size: 13px;\n font-weight: 500;\n font-family:\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n white-space: nowrap;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);\n z-index: 10000;\n pointer-events: none;\n animation: ya-container-tooltip-fade-in 0.1s ease;\n}\n@keyframes ya-container-tooltip-fade-in {\n from {\n opacity: 0;\n transform: scale(0.95);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n');
|
|
4696
5132
|
|
|
4697
5133
|
// src/components/YaContainer.tsx
|
|
4698
|
-
import { Fragment as Fragment5, jsx as
|
|
5134
|
+
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4699
5135
|
function parseBackgroundConfig(value) {
|
|
4700
5136
|
if (!value) {
|
|
4701
5137
|
return { type: "none" };
|
|
@@ -4737,11 +5173,11 @@ function deriveContainerLabel(element) {
|
|
|
4737
5173
|
return tagLabels[tagName] || "Section";
|
|
4738
5174
|
}
|
|
4739
5175
|
function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearClick, hasBackground }) {
|
|
4740
|
-
const [position, setPosition] =
|
|
4741
|
-
const [imageOpen, setImageOpen] =
|
|
4742
|
-
const [colorOpen, setColorOpen] =
|
|
4743
|
-
const [aiOpen, setAiOpen] =
|
|
4744
|
-
const [clearOpen, setClearOpen] =
|
|
5176
|
+
const [position, setPosition] = useState13(null);
|
|
5177
|
+
const [imageOpen, setImageOpen] = useState13(false);
|
|
5178
|
+
const [colorOpen, setColorOpen] = useState13(false);
|
|
5179
|
+
const [aiOpen, setAiOpen] = useState13(false);
|
|
5180
|
+
const [clearOpen, setClearOpen] = useState13(false);
|
|
4745
5181
|
const {
|
|
4746
5182
|
refs: imageRefs,
|
|
4747
5183
|
floatingStyles: imageStyles,
|
|
@@ -4790,7 +5226,7 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
4790
5226
|
});
|
|
4791
5227
|
const clearHover = useHover(clearContext, { delay: { open: 0, close: 0 } });
|
|
4792
5228
|
const { getReferenceProps: getClearRefProps, getFloatingProps: getClearFloatProps } = useInteractions2([clearHover]);
|
|
4793
|
-
|
|
5229
|
+
useEffect14(() => {
|
|
4794
5230
|
const updatePosition = () => {
|
|
4795
5231
|
if (containerRef.current) {
|
|
4796
5232
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -4810,7 +5246,7 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
4810
5246
|
}, [containerRef]);
|
|
4811
5247
|
if (!position) return null;
|
|
4812
5248
|
return createPortal6(
|
|
4813
|
-
/* @__PURE__ */
|
|
5249
|
+
/* @__PURE__ */ jsxs10(
|
|
4814
5250
|
"div",
|
|
4815
5251
|
{
|
|
4816
5252
|
className: "ya-container-toolbar",
|
|
@@ -4821,7 +5257,7 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
4821
5257
|
},
|
|
4822
5258
|
onClick: (e) => e.stopPropagation(),
|
|
4823
5259
|
children: [
|
|
4824
|
-
/* @__PURE__ */
|
|
5260
|
+
/* @__PURE__ */ jsx16(
|
|
4825
5261
|
"button",
|
|
4826
5262
|
{
|
|
4827
5263
|
ref: imageRefs.setReference,
|
|
@@ -4829,14 +5265,14 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
4829
5265
|
onClick: onImageClick,
|
|
4830
5266
|
"aria-label": "Edit background image",
|
|
4831
5267
|
...getImageRefProps(),
|
|
4832
|
-
children: /* @__PURE__ */
|
|
4833
|
-
/* @__PURE__ */
|
|
4834
|
-
/* @__PURE__ */
|
|
4835
|
-
/* @__PURE__ */
|
|
5268
|
+
children: /* @__PURE__ */ jsxs10("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
5269
|
+
/* @__PURE__ */ jsx16("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
|
|
5270
|
+
/* @__PURE__ */ jsx16("circle", { cx: "8.5", cy: "8.5", r: "1.5" }),
|
|
5271
|
+
/* @__PURE__ */ jsx16("polyline", { points: "21 15 16 10 5 21" })
|
|
4836
5272
|
] })
|
|
4837
5273
|
}
|
|
4838
5274
|
),
|
|
4839
|
-
imageOpen && /* @__PURE__ */
|
|
5275
|
+
imageOpen && /* @__PURE__ */ jsx16(FloatingPortal2, { children: /* @__PURE__ */ jsx16(
|
|
4840
5276
|
"div",
|
|
4841
5277
|
{
|
|
4842
5278
|
ref: imageRefs.setFloating,
|
|
@@ -4846,7 +5282,7 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
4846
5282
|
children: "Background Image"
|
|
4847
5283
|
}
|
|
4848
5284
|
) }),
|
|
4849
|
-
/* @__PURE__ */
|
|
5285
|
+
/* @__PURE__ */ jsx16(
|
|
4850
5286
|
"button",
|
|
4851
5287
|
{
|
|
4852
5288
|
ref: colorRefs.setReference,
|
|
@@ -4854,13 +5290,13 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
4854
5290
|
onClick: onColorClick,
|
|
4855
5291
|
"aria-label": "Edit background color",
|
|
4856
5292
|
...getColorRefProps(),
|
|
4857
|
-
children: /* @__PURE__ */
|
|
4858
|
-
/* @__PURE__ */
|
|
4859
|
-
/* @__PURE__ */
|
|
5293
|
+
children: /* @__PURE__ */ jsxs10("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
5294
|
+
/* @__PURE__ */ jsx16("circle", { cx: "12", cy: "12", r: "10" }),
|
|
5295
|
+
/* @__PURE__ */ jsx16("path", { d: "M12 2a10 10 0 0 1 0 20", fill: "currentColor" })
|
|
4860
5296
|
] })
|
|
4861
5297
|
}
|
|
4862
5298
|
),
|
|
4863
|
-
colorOpen && /* @__PURE__ */
|
|
5299
|
+
colorOpen && /* @__PURE__ */ jsx16(FloatingPortal2, { children: /* @__PURE__ */ jsx16(
|
|
4864
5300
|
"div",
|
|
4865
5301
|
{
|
|
4866
5302
|
ref: colorRefs.setFloating,
|
|
@@ -4870,7 +5306,7 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
4870
5306
|
children: "Background Color"
|
|
4871
5307
|
}
|
|
4872
5308
|
) }),
|
|
4873
|
-
/* @__PURE__ */
|
|
5309
|
+
/* @__PURE__ */ jsx16(
|
|
4874
5310
|
"button",
|
|
4875
5311
|
{
|
|
4876
5312
|
ref: aiRefs.setReference,
|
|
@@ -4878,14 +5314,14 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
4878
5314
|
onClick: onAIClick,
|
|
4879
5315
|
"aria-label": "Ask AI for help",
|
|
4880
5316
|
...getAiRefProps(),
|
|
4881
|
-
children: /* @__PURE__ */
|
|
4882
|
-
/* @__PURE__ */
|
|
4883
|
-
/* @__PURE__ */
|
|
4884
|
-
/* @__PURE__ */
|
|
5317
|
+
children: /* @__PURE__ */ jsxs10("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
5318
|
+
/* @__PURE__ */ jsx16("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
|
|
5319
|
+
/* @__PURE__ */ jsx16("path", { d: "M2 17l10 5 10-5" }),
|
|
5320
|
+
/* @__PURE__ */ jsx16("path", { d: "M2 12l10 5 10-5" })
|
|
4885
5321
|
] })
|
|
4886
5322
|
}
|
|
4887
5323
|
),
|
|
4888
|
-
aiOpen && /* @__PURE__ */
|
|
5324
|
+
aiOpen && /* @__PURE__ */ jsx16(FloatingPortal2, { children: /* @__PURE__ */ jsx16(
|
|
4889
5325
|
"div",
|
|
4890
5326
|
{
|
|
4891
5327
|
ref: aiRefs.setFloating,
|
|
@@ -4895,8 +5331,8 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
4895
5331
|
children: "AI Assist"
|
|
4896
5332
|
}
|
|
4897
5333
|
) }),
|
|
4898
|
-
hasBackground && /* @__PURE__ */
|
|
4899
|
-
/* @__PURE__ */
|
|
5334
|
+
hasBackground && /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
5335
|
+
/* @__PURE__ */ jsx16(
|
|
4900
5336
|
"button",
|
|
4901
5337
|
{
|
|
4902
5338
|
ref: clearRefs.setReference,
|
|
@@ -4904,13 +5340,13 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
4904
5340
|
onClick: onClearClick,
|
|
4905
5341
|
"aria-label": "Clear background",
|
|
4906
5342
|
...getClearRefProps(),
|
|
4907
|
-
children: /* @__PURE__ */
|
|
4908
|
-
/* @__PURE__ */
|
|
4909
|
-
/* @__PURE__ */
|
|
5343
|
+
children: /* @__PURE__ */ jsxs10("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
5344
|
+
/* @__PURE__ */ jsx16("circle", { cx: "12", cy: "12", r: "10" }),
|
|
5345
|
+
/* @__PURE__ */ jsx16("line", { x1: "4.93", y1: "4.93", x2: "19.07", y2: "19.07" })
|
|
4910
5346
|
] })
|
|
4911
5347
|
}
|
|
4912
5348
|
),
|
|
4913
|
-
clearOpen && /* @__PURE__ */
|
|
5349
|
+
clearOpen && /* @__PURE__ */ jsx16(FloatingPortal2, { children: /* @__PURE__ */ jsx16(
|
|
4914
5350
|
"div",
|
|
4915
5351
|
{
|
|
4916
5352
|
ref: clearRefs.setFloating,
|
|
@@ -4936,12 +5372,12 @@ function YaContainer({
|
|
|
4936
5372
|
defaultBackground
|
|
4937
5373
|
}) {
|
|
4938
5374
|
const { getValue, setValue, saveToWorker, mode } = useContentStore();
|
|
4939
|
-
const containerRef =
|
|
4940
|
-
const [isHovered, setIsHovered] =
|
|
4941
|
-
const [isSelected, setIsSelected] =
|
|
4942
|
-
const [isDropMode, setIsDropMode] =
|
|
4943
|
-
const [isDropHover, setIsDropHover] =
|
|
4944
|
-
|
|
5375
|
+
const containerRef = useRef14(null);
|
|
5376
|
+
const [isHovered, setIsHovered] = useState13(false);
|
|
5377
|
+
const [isSelected, setIsSelected] = useState13(false);
|
|
5378
|
+
const [isDropMode, setIsDropMode] = useState13(false);
|
|
5379
|
+
const [isDropHover, setIsDropHover] = useState13(false);
|
|
5380
|
+
useEffect14(() => {
|
|
4945
5381
|
if (mode !== "inline-edit") return;
|
|
4946
5382
|
const containerEl = containerRef.current;
|
|
4947
5383
|
if (!containerEl) return;
|
|
@@ -4983,7 +5419,7 @@ function YaContainer({
|
|
|
4983
5419
|
overlayCustomProps["--ya-overlay-color"] = backgroundConfig.overlay.color;
|
|
4984
5420
|
overlayCustomProps["--ya-overlay-opacity"] = backgroundConfig.overlay.opacity;
|
|
4985
5421
|
}
|
|
4986
|
-
const handleImageClick =
|
|
5422
|
+
const handleImageClick = useCallback15(() => {
|
|
4987
5423
|
if (mode !== "inline-edit") return;
|
|
4988
5424
|
setIsSelected(true);
|
|
4989
5425
|
const rect = containerRef.current?.getBoundingClientRect();
|
|
@@ -5003,7 +5439,7 @@ function YaContainer({
|
|
|
5003
5439
|
"*"
|
|
5004
5440
|
);
|
|
5005
5441
|
}, [mode, fieldId, backgroundConfig]);
|
|
5006
|
-
const handleColorClick =
|
|
5442
|
+
const handleColorClick = useCallback15(() => {
|
|
5007
5443
|
if (mode !== "inline-edit") return;
|
|
5008
5444
|
setIsSelected(true);
|
|
5009
5445
|
const rect = containerRef.current?.getBoundingClientRect();
|
|
@@ -5023,7 +5459,7 @@ function YaContainer({
|
|
|
5023
5459
|
"*"
|
|
5024
5460
|
);
|
|
5025
5461
|
}, [mode, fieldId, backgroundConfig]);
|
|
5026
|
-
const handleAIClick =
|
|
5462
|
+
const handleAIClick = useCallback15(() => {
|
|
5027
5463
|
if (mode !== "inline-edit") return;
|
|
5028
5464
|
const label = deriveContainerLabel(containerRef.current);
|
|
5029
5465
|
window.parent.postMessage(
|
|
@@ -5036,14 +5472,14 @@ function YaContainer({
|
|
|
5036
5472
|
"*"
|
|
5037
5473
|
);
|
|
5038
5474
|
}, [mode, fieldId, backgroundConfig]);
|
|
5039
|
-
const handleClearClick =
|
|
5475
|
+
const handleClearClick = useCallback15(() => {
|
|
5040
5476
|
if (mode !== "inline-edit") return;
|
|
5041
5477
|
const clearedConfig = { type: "none" };
|
|
5042
5478
|
const serialized = serializeBackgroundConfig(clearedConfig);
|
|
5043
5479
|
setValue(fieldId, serialized);
|
|
5044
5480
|
saveToWorker?.(fieldId, serialized);
|
|
5045
5481
|
}, [mode, fieldId, setValue, saveToWorker]);
|
|
5046
|
-
|
|
5482
|
+
useEffect14(() => {
|
|
5047
5483
|
if (mode !== "inline-edit") return;
|
|
5048
5484
|
const handleMessage2 = (event) => {
|
|
5049
5485
|
if (event.data?.type === "YA_CONTAINER_EDIT_COMPLETE" && event.data.fieldId === fieldId) {
|
|
@@ -5056,7 +5492,7 @@ function YaContainer({
|
|
|
5056
5492
|
window.addEventListener("message", handleMessage2);
|
|
5057
5493
|
return () => window.removeEventListener("message", handleMessage2);
|
|
5058
5494
|
}, [mode, fieldId]);
|
|
5059
|
-
|
|
5495
|
+
useEffect14(() => {
|
|
5060
5496
|
if (mode !== "inline-edit") return;
|
|
5061
5497
|
const handleDropModeMessage = (event) => {
|
|
5062
5498
|
if (event.data?.type === "DROP_MODE_START") {
|
|
@@ -5070,7 +5506,7 @@ function YaContainer({
|
|
|
5070
5506
|
window.addEventListener("message", handleDropModeMessage);
|
|
5071
5507
|
return () => window.removeEventListener("message", handleDropModeMessage);
|
|
5072
5508
|
}, [mode]);
|
|
5073
|
-
const handleDragEnter =
|
|
5509
|
+
const handleDragEnter = useCallback15(
|
|
5074
5510
|
(e) => {
|
|
5075
5511
|
if (!isDropMode) return;
|
|
5076
5512
|
e.preventDefault();
|
|
@@ -5094,7 +5530,7 @@ function YaContainer({
|
|
|
5094
5530
|
},
|
|
5095
5531
|
[isDropMode, fieldId]
|
|
5096
5532
|
);
|
|
5097
|
-
const handleDragOver =
|
|
5533
|
+
const handleDragOver = useCallback15(
|
|
5098
5534
|
(e) => {
|
|
5099
5535
|
if (!isDropMode) return;
|
|
5100
5536
|
e.preventDefault();
|
|
@@ -5102,7 +5538,7 @@ function YaContainer({
|
|
|
5102
5538
|
},
|
|
5103
5539
|
[isDropMode]
|
|
5104
5540
|
);
|
|
5105
|
-
const handleDragLeave =
|
|
5541
|
+
const handleDragLeave = useCallback15(
|
|
5106
5542
|
(e) => {
|
|
5107
5543
|
if (!isDropMode) return;
|
|
5108
5544
|
e.preventDefault();
|
|
@@ -5116,7 +5552,7 @@ function YaContainer({
|
|
|
5116
5552
|
},
|
|
5117
5553
|
[isDropMode]
|
|
5118
5554
|
);
|
|
5119
|
-
const handleDrop =
|
|
5555
|
+
const handleDrop = useCallback15(
|
|
5120
5556
|
(e) => {
|
|
5121
5557
|
if (!isDropMode) return;
|
|
5122
5558
|
e.preventDefault();
|
|
@@ -5134,7 +5570,7 @@ function YaContainer({
|
|
|
5134
5570
|
},
|
|
5135
5571
|
[isDropMode, fieldId]
|
|
5136
5572
|
);
|
|
5137
|
-
|
|
5573
|
+
useEffect14(() => {
|
|
5138
5574
|
if (!isSelected || mode !== "inline-edit") return;
|
|
5139
5575
|
let lastRectKey = "";
|
|
5140
5576
|
let lastTime = 0;
|
|
@@ -5169,7 +5605,7 @@ function YaContainer({
|
|
|
5169
5605
|
return () => cancelAnimationFrame(rafId);
|
|
5170
5606
|
}, [isSelected, fieldId, mode]);
|
|
5171
5607
|
if (mode === "read-only") {
|
|
5172
|
-
return /* @__PURE__ */
|
|
5608
|
+
return /* @__PURE__ */ jsx16(
|
|
5173
5609
|
Tag,
|
|
5174
5610
|
{
|
|
5175
5611
|
className: `ya-container ${className || ""}`,
|
|
@@ -5193,7 +5629,7 @@ function YaContainer({
|
|
|
5193
5629
|
isDropHover ? "ya-container-drop-hover" : "",
|
|
5194
5630
|
className || ""
|
|
5195
5631
|
].filter(Boolean).join(" ");
|
|
5196
|
-
return /* @__PURE__ */
|
|
5632
|
+
return /* @__PURE__ */ jsxs10(
|
|
5197
5633
|
Tag,
|
|
5198
5634
|
{
|
|
5199
5635
|
ref: containerRef,
|
|
@@ -5212,7 +5648,7 @@ function YaContainer({
|
|
|
5212
5648
|
onDrop: handleDrop,
|
|
5213
5649
|
children: [
|
|
5214
5650
|
children,
|
|
5215
|
-
mode === "inline-edit" && (isHovered || isSelected) && !document.body.classList.contains("builder-selector-active") && /* @__PURE__ */
|
|
5651
|
+
mode === "inline-edit" && (isHovered || isSelected) && !document.body.classList.contains("builder-selector-active") && /* @__PURE__ */ jsx16(
|
|
5216
5652
|
Toolbar,
|
|
5217
5653
|
{
|
|
5218
5654
|
containerRef,
|
|
@@ -5229,10 +5665,10 @@ function YaContainer({
|
|
|
5229
5665
|
}
|
|
5230
5666
|
|
|
5231
5667
|
// src/components/StaticText.tsx
|
|
5232
|
-
import { jsx as
|
|
5668
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
5233
5669
|
function MpText({ fieldId, className, as: Component = "span", children }) {
|
|
5234
5670
|
const content = getContent(fieldId) || (typeof children === "string" ? children : "");
|
|
5235
|
-
return /* @__PURE__ */
|
|
5671
|
+
return /* @__PURE__ */ jsx17(
|
|
5236
5672
|
Component,
|
|
5237
5673
|
{
|
|
5238
5674
|
className,
|
|
@@ -5243,7 +5679,7 @@ function MpText({ fieldId, className, as: Component = "span", children }) {
|
|
|
5243
5679
|
}
|
|
5244
5680
|
|
|
5245
5681
|
// src/components/StaticImage.tsx
|
|
5246
|
-
import { jsx as
|
|
5682
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
5247
5683
|
function parseImageValue2(value) {
|
|
5248
5684
|
if (!value) {
|
|
5249
5685
|
return { src: "" };
|
|
@@ -5279,7 +5715,7 @@ function MpImage({
|
|
|
5279
5715
|
const altText = imageData.alt || alt || fallbackAlt || "";
|
|
5280
5716
|
const objectFit = imageData.objectFit || propObjectFit || "cover";
|
|
5281
5717
|
const objectPosition = getObjectPosition3(imageData) || propObjectPosition || "50% 50%";
|
|
5282
|
-
return /* @__PURE__ */
|
|
5718
|
+
return /* @__PURE__ */ jsx18(
|
|
5283
5719
|
"img",
|
|
5284
5720
|
{
|
|
5285
5721
|
src: resolveAssetUrl(src),
|
|
@@ -5297,7 +5733,7 @@ function MpImage({
|
|
|
5297
5733
|
|
|
5298
5734
|
// src/components/MarkdownText.tsx
|
|
5299
5735
|
import { Fragment as Fragment6 } from "react";
|
|
5300
|
-
import { jsx as
|
|
5736
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
5301
5737
|
function tokenize(text) {
|
|
5302
5738
|
const tokens = [];
|
|
5303
5739
|
let remaining = text;
|
|
@@ -5359,13 +5795,13 @@ function tokensToElements(tokens) {
|
|
|
5359
5795
|
return tokens.map((token, index) => {
|
|
5360
5796
|
switch (token.type) {
|
|
5361
5797
|
case "text":
|
|
5362
|
-
return /* @__PURE__ */
|
|
5798
|
+
return /* @__PURE__ */ jsx19(Fragment6, { children: token.content }, index);
|
|
5363
5799
|
case "bold":
|
|
5364
|
-
return /* @__PURE__ */
|
|
5800
|
+
return /* @__PURE__ */ jsx19("strong", { children: token.content }, index);
|
|
5365
5801
|
case "italic":
|
|
5366
|
-
return /* @__PURE__ */
|
|
5802
|
+
return /* @__PURE__ */ jsx19("em", { children: token.content }, index);
|
|
5367
5803
|
case "link":
|
|
5368
|
-
return /* @__PURE__ */
|
|
5804
|
+
return /* @__PURE__ */ jsx19(
|
|
5369
5805
|
"a",
|
|
5370
5806
|
{
|
|
5371
5807
|
href: token.url,
|
|
@@ -5377,7 +5813,7 @@ function tokensToElements(tokens) {
|
|
|
5377
5813
|
index
|
|
5378
5814
|
);
|
|
5379
5815
|
case "newline":
|
|
5380
|
-
return /* @__PURE__ */
|
|
5816
|
+
return /* @__PURE__ */ jsx19("br", {}, index);
|
|
5381
5817
|
default:
|
|
5382
5818
|
return null;
|
|
5383
5819
|
}
|
|
@@ -5389,15 +5825,15 @@ function parseMarkdownToElements(content) {
|
|
|
5389
5825
|
}
|
|
5390
5826
|
function MarkdownText({ content, className }) {
|
|
5391
5827
|
const elements = parseMarkdownToElements(content);
|
|
5392
|
-
return /* @__PURE__ */
|
|
5828
|
+
return /* @__PURE__ */ jsx19("span", { className, children: elements });
|
|
5393
5829
|
}
|
|
5394
5830
|
|
|
5395
5831
|
// src/router/Link.tsx
|
|
5396
5832
|
import { Link as WouterLink2 } from "wouter";
|
|
5397
|
-
import { jsx as
|
|
5833
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
5398
5834
|
function Link2({ to, href, children, className, onClick, replace, ...props }) {
|
|
5399
5835
|
const target = href ?? to ?? "/";
|
|
5400
|
-
return /* @__PURE__ */
|
|
5836
|
+
return /* @__PURE__ */ jsx20(WouterLink2, { href: target, className, onClick, replace, ...props, children });
|
|
5401
5837
|
}
|
|
5402
5838
|
|
|
5403
5839
|
// src/router/useNavigate.ts
|
|
@@ -5416,7 +5852,7 @@ function useNavigate() {
|
|
|
5416
5852
|
|
|
5417
5853
|
// src/router/Router.tsx
|
|
5418
5854
|
import { Router as WouterRouter } from "wouter";
|
|
5419
|
-
import { jsx as
|
|
5855
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
5420
5856
|
function detectBasename() {
|
|
5421
5857
|
if (typeof window === "undefined") return "";
|
|
5422
5858
|
const sessionMatch = window.location.pathname.match(/^\/session\/[^/]+/);
|
|
@@ -5431,7 +5867,7 @@ function detectBasename() {
|
|
|
5431
5867
|
}
|
|
5432
5868
|
function Router({ children, base }) {
|
|
5433
5869
|
const basename = base ?? detectBasename();
|
|
5434
|
-
return /* @__PURE__ */
|
|
5870
|
+
return /* @__PURE__ */ jsx21(WouterRouter, { base: basename, children });
|
|
5435
5871
|
}
|
|
5436
5872
|
|
|
5437
5873
|
// src/router/index.ts
|
|
@@ -5450,6 +5886,7 @@ export {
|
|
|
5450
5886
|
MpText as StaticText,
|
|
5451
5887
|
Switch,
|
|
5452
5888
|
YaContainer,
|
|
5889
|
+
YaEmbed,
|
|
5453
5890
|
YaImage,
|
|
5454
5891
|
YaLink,
|
|
5455
5892
|
YaText,
|
|
@@ -5467,9 +5904,11 @@ export {
|
|
|
5467
5904
|
initBuilderSelection,
|
|
5468
5905
|
linkTransitionStrategy,
|
|
5469
5906
|
parseBackgroundConfig,
|
|
5907
|
+
parseEmbedUrl,
|
|
5470
5908
|
registerContent,
|
|
5471
5909
|
resolveAssetUrl,
|
|
5472
5910
|
serializeBackgroundConfig,
|
|
5911
|
+
serializeEmbedValue,
|
|
5473
5912
|
serializeImageValue,
|
|
5474
5913
|
serializeVideoValue,
|
|
5475
5914
|
setAssetResolver,
|