@yoamigo.com/core 0.2.0 → 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 +98 -6
- package/dist/index.js +317 -156
- package/dist/plugin.js +31 -0
- package/dist/prod.d.ts +4 -4
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import
|
|
2
|
+
import React__default, { ReactNode } from 'react';
|
|
3
3
|
|
|
4
4
|
type EditMode = 'read-only' | 'inline-edit';
|
|
5
5
|
interface ContentStore {
|
|
@@ -28,9 +28,9 @@ interface YaLinkProps {
|
|
|
28
28
|
href?: string;
|
|
29
29
|
className?: string;
|
|
30
30
|
/** Inline styles to apply to the link element */
|
|
31
|
-
style?:
|
|
31
|
+
style?: React__default.CSSProperties;
|
|
32
32
|
as?: 'a' | 'span';
|
|
33
|
-
children?:
|
|
33
|
+
children?: React__default.ReactNode;
|
|
34
34
|
/** Available pages for href dropdown (injected by template) */
|
|
35
35
|
availablePages?: PageInfo[];
|
|
36
36
|
/** Optional click handler called after navigation */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import * as React$1 from 'react';
|
|
3
|
+
import React__default, { ReactNode, CSSProperties } from 'react';
|
|
4
|
+
export { C as ContentStoreProviderProd, d as MarkdownText, e as MarkdownTextProps, P as PageInfo, b as StaticImage, c as StaticImageProps, M as StaticText, S as StaticTextProps, Y as YaLink, f as YaLinkProps, u as useContentStoreProd } from './MarkdownText-kV5IiAma.js';
|
|
4
5
|
export { Link, LinkProps, NavigateFunction, Router, RouterProps, useNavigate } from './router.js';
|
|
5
6
|
export { Route, Switch, useParams } from 'wouter';
|
|
6
7
|
export { A as AssetResolverFn, C as ContentRegistry, c as contentRegistry, a as getAllContent, g as getContent, h as hasContent, r as registerContent, b as resolveAssetUrl, s as setAssetResolver } from './asset-resolver-BnIvDkVv.js';
|
|
@@ -44,7 +45,7 @@ interface YaTextProps {
|
|
|
44
45
|
className?: string;
|
|
45
46
|
as?: YaTextElement;
|
|
46
47
|
/** Optional fallback content (used if fieldId not in store) */
|
|
47
|
-
children?:
|
|
48
|
+
children?: React__default.ReactNode;
|
|
48
49
|
}
|
|
49
50
|
declare module '@tiptap/core' {
|
|
50
51
|
interface Commands<ReturnType> {
|
|
@@ -125,7 +126,9 @@ interface YaVideoProps {
|
|
|
125
126
|
objectFit?: 'cover' | 'contain' | 'fill';
|
|
126
127
|
/** Loading strategy */
|
|
127
128
|
loading?: 'lazy' | 'eager';
|
|
128
|
-
/**
|
|
129
|
+
/** Default video value (used when nothing in content store) */
|
|
130
|
+
defaultValue?: VideoFieldValue;
|
|
131
|
+
/** Fallback for backward compatibility (deprecated: use defaultValue) */
|
|
129
132
|
fallbackSrc?: string;
|
|
130
133
|
/** Fallback poster image */
|
|
131
134
|
fallbackPoster?: string;
|
|
@@ -134,7 +137,7 @@ interface YaVideoProps {
|
|
|
134
137
|
* Serialize video field value for storage
|
|
135
138
|
*/
|
|
136
139
|
declare function serializeVideoValue(value: VideoFieldValue): string;
|
|
137
|
-
declare function YaVideo({ fieldId, className, aspectRatio: propAspectRatio, objectFit: propObjectFit, loading, fallbackSrc, fallbackPoster, }: YaVideoProps): react_jsx_runtime.JSX.Element;
|
|
140
|
+
declare function YaVideo({ fieldId, className, aspectRatio: propAspectRatio, objectFit: propObjectFit, loading, defaultValue, fallbackSrc, fallbackPoster, }: YaVideoProps): react_jsx_runtime.JSX.Element;
|
|
138
141
|
|
|
139
142
|
interface BackgroundImageConfig {
|
|
140
143
|
src: string;
|
|
@@ -191,6 +194,39 @@ interface SafeHtmlProps {
|
|
|
191
194
|
*/
|
|
192
195
|
declare function SafeHtml({ content, className, mode }: SafeHtmlProps): react_jsx_runtime.JSX.Element;
|
|
193
196
|
|
|
197
|
+
interface SafeTriangleBelowProps {
|
|
198
|
+
/** Ref to the trigger element */
|
|
199
|
+
triggerRef: React.RefObject<HTMLElement | null>;
|
|
200
|
+
/** Ref to the popover element */
|
|
201
|
+
popoverRef: React.RefObject<HTMLElement | null>;
|
|
202
|
+
/** Whether the popover is currently visible */
|
|
203
|
+
isVisible: boolean;
|
|
204
|
+
/** Called when mouse leaves the safe zone */
|
|
205
|
+
onLeave?: () => void;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* SafeTriangleBelow creates a dynamic SVG triangle between the cursor and a popover
|
|
209
|
+
* that appears below the trigger, preventing the popover from closing when users
|
|
210
|
+
* move diagonally toward it.
|
|
211
|
+
*
|
|
212
|
+
* Based on the "Safe Triangle" pattern:
|
|
213
|
+
* @see https://www.smashingmagazine.com/2023/08/better-context-menus-safe-triangles/
|
|
214
|
+
*
|
|
215
|
+
* This variant is for popovers that appear BELOW the trigger (vs SafeTriangle which
|
|
216
|
+
* is for tooltips appearing to the RIGHT).
|
|
217
|
+
*
|
|
218
|
+
* Usage:
|
|
219
|
+
* ```tsx
|
|
220
|
+
* <SafeTriangleBelow
|
|
221
|
+
* triggerRef={triggerRef}
|
|
222
|
+
* popoverRef={popoverRef}
|
|
223
|
+
* isVisible={isOpen}
|
|
224
|
+
* onLeave={() => setIsOpen(false)}
|
|
225
|
+
* />
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
declare function SafeTriangleBelow({ triggerRef, popoverRef, isVisible, onLeave, }: SafeTriangleBelowProps): React$1.ReactPortal | null;
|
|
229
|
+
|
|
194
230
|
/**
|
|
195
231
|
* Animation state for a single field
|
|
196
232
|
*/
|
|
@@ -580,4 +616,60 @@ interface AnimatedTextOptions {
|
|
|
580
616
|
*/
|
|
581
617
|
declare function useAnimatedText(fieldId: string, content: string, options?: AnimatedTextOptions): AnimatedTextResult;
|
|
582
618
|
|
|
583
|
-
|
|
619
|
+
interface UseSafeTriangleOptions {
|
|
620
|
+
/** Delay before showing popover (ms) */
|
|
621
|
+
showDelay?: number;
|
|
622
|
+
/** Delay before hiding popover after mouse leaves (ms) */
|
|
623
|
+
hideDelay?: number;
|
|
624
|
+
/** Whether the hook is enabled (for edit mode check) */
|
|
625
|
+
enabled?: boolean;
|
|
626
|
+
}
|
|
627
|
+
interface UseSafeTriangleReturn<T extends HTMLElement, U extends HTMLElement> {
|
|
628
|
+
/** Ref to attach to the trigger element */
|
|
629
|
+
triggerRef: React.RefObject<T | null>;
|
|
630
|
+
/** Ref to attach to the popover element */
|
|
631
|
+
popoverRef: React.RefObject<U | null>;
|
|
632
|
+
/** Whether the popover should be visible */
|
|
633
|
+
isVisible: boolean;
|
|
634
|
+
/** Event handlers to spread on the trigger container */
|
|
635
|
+
handlers: {
|
|
636
|
+
onMouseEnter: () => void;
|
|
637
|
+
onMouseLeave: () => void;
|
|
638
|
+
onFocus: () => void;
|
|
639
|
+
};
|
|
640
|
+
/** Props to spread on the SafeTriangleBelow component */
|
|
641
|
+
triangleProps: {
|
|
642
|
+
triggerRef: React.RefObject<T | null>;
|
|
643
|
+
popoverRef: React.RefObject<U | null>;
|
|
644
|
+
isVisible: boolean;
|
|
645
|
+
onLeave: () => void;
|
|
646
|
+
};
|
|
647
|
+
/** Manually show the popover */
|
|
648
|
+
show: () => void;
|
|
649
|
+
/** Manually hide the popover */
|
|
650
|
+
hide: () => void;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Hook for managing safe triangle popover state.
|
|
654
|
+
* Handles show/hide delays and provides all necessary refs and handlers.
|
|
655
|
+
*
|
|
656
|
+
* @example
|
|
657
|
+
* ```tsx
|
|
658
|
+
* const { triggerRef, popoverRef, isVisible, handlers, triangleProps } = useSafeTriangle()
|
|
659
|
+
*
|
|
660
|
+
* return (
|
|
661
|
+
* <div>
|
|
662
|
+
* <a ref={triggerRef} {...handlers}>
|
|
663
|
+
* Hover me
|
|
664
|
+
* </a>
|
|
665
|
+
* {isVisible && (
|
|
666
|
+
* <div ref={popoverRef}>Popover content</div>
|
|
667
|
+
* )}
|
|
668
|
+
* <SafeTriangleBelow {...triangleProps} />
|
|
669
|
+
* </div>
|
|
670
|
+
* )
|
|
671
|
+
* ```
|
|
672
|
+
*/
|
|
673
|
+
declare function useSafeTriangle<T extends HTMLElement = HTMLElement, U extends HTMLElement = HTMLDivElement>(options?: UseSafeTriangleOptions): UseSafeTriangleReturn<T, U>;
|
|
674
|
+
|
|
675
|
+
export { type AIEditContextValue, AIEditProvider, type AnimatedTextOptions, type AnimatedTextResult, type AnimationConfig, type AnimationMetadata, type AnimationOptions, type AnimationPhase, type AnimationResult, type AnimationState, type AnimationStrategy, type BackgroundConfig, type BackgroundImageConfig, type ContentStoreContextType, type ContentStoreMode, ContentStoreProvider, type ImageFieldValue, type ImageValue, type LinkValue, type OverlayConfig, SafeHtml, type SafeHtmlProps, SafeTriangleBelow, type TextAnimationMetadata, type TextDiff, type VideoFieldValue, YaContainer, type YaContainerProps, YaImage, type YaImageProps, YaText, type YaTextProps, YaVideo, type YaVideoProps, buildIntermediateText, calculateAnimationTiming, computeTextDiff, containsHtml, getTextCursorPosition, imageCrossfadeStrategy, linkTransitionStrategy, parseBackgroundConfig, serializeBackgroundConfig, serializeImageValue, serializeVideoValue, stripHtml, textTypingStrategy, useAIEditAnimation, useAIEditContext, useAIEditContextOptional, useAnimatedText, useContentStore, useSafeTriangle };
|
package/dist/index.js
CHANGED
|
@@ -2917,6 +2917,7 @@ function YaVideo({
|
|
|
2917
2917
|
aspectRatio: propAspectRatio,
|
|
2918
2918
|
objectFit: propObjectFit,
|
|
2919
2919
|
loading = "lazy",
|
|
2920
|
+
defaultValue,
|
|
2920
2921
|
fallbackSrc,
|
|
2921
2922
|
fallbackPoster
|
|
2922
2923
|
}) {
|
|
@@ -2928,7 +2929,8 @@ function YaVideo({
|
|
|
2928
2929
|
const [isSmallVideo, setIsSmallVideo] = useState7(false);
|
|
2929
2930
|
const [isInView, setIsInView] = useState7(loading === "eager");
|
|
2930
2931
|
const rawValue = getValue(fieldId);
|
|
2931
|
-
const
|
|
2932
|
+
const parsedValue = parseVideoValue(rawValue);
|
|
2933
|
+
const videoData = parsedValue.src ? parsedValue : defaultValue || parsedValue;
|
|
2932
2934
|
const src = videoData.src || fallbackSrc || "";
|
|
2933
2935
|
const poster = videoData.poster || fallbackPoster || "";
|
|
2934
2936
|
const objectFit = videoData.objectFit || propObjectFit || "cover";
|
|
@@ -3228,8 +3230,8 @@ function YaVideo({
|
|
|
3228
3230
|
}
|
|
3229
3231
|
|
|
3230
3232
|
// src/components/YaLink.tsx
|
|
3231
|
-
import { useEffect as
|
|
3232
|
-
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";
|
|
3233
3235
|
import { useEditor as useEditor2, EditorContent as EditorContent2 } from "@tiptap/react";
|
|
3234
3236
|
import { BubbleMenu as BubbleMenu2 } from "@tiptap/react/menus";
|
|
3235
3237
|
import StarterKit2 from "@tiptap/starter-kit";
|
|
@@ -3237,11 +3239,169 @@ import { TextStyle as TextStyle2 } from "@tiptap/extension-text-style";
|
|
|
3237
3239
|
import { Extension as Extension2 } from "@tiptap/core";
|
|
3238
3240
|
import { Link as WouterLink, useLocation } from "wouter";
|
|
3239
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
|
+
|
|
3240
3400
|
// src/components/ya-link.css
|
|
3241
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');
|
|
3242
3402
|
|
|
3243
3403
|
// src/components/YaLink.tsx
|
|
3244
|
-
import { Fragment as Fragment3, jsx as
|
|
3404
|
+
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
3245
3405
|
function isInternalPath(path) {
|
|
3246
3406
|
if (!path) return false;
|
|
3247
3407
|
if (path.startsWith("#")) return false;
|
|
@@ -3342,8 +3502,8 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3342
3502
|
const { getValue, setValue, mode, saveToWorker, getPages } = useContentStore();
|
|
3343
3503
|
const [, navigate] = useLocation();
|
|
3344
3504
|
const pages = availablePages ?? getPages();
|
|
3345
|
-
const [sections, setSections] =
|
|
3346
|
-
const [sectionsExpanded, setSectionsExpanded] =
|
|
3505
|
+
const [sections, setSections] = useState10([]);
|
|
3506
|
+
const [sectionsExpanded, setSectionsExpanded] = useState10(false);
|
|
3347
3507
|
const textFieldId = `${fieldId}.text`;
|
|
3348
3508
|
const hrefFieldId = `${fieldId}.href`;
|
|
3349
3509
|
const storeText = getValue(textFieldId);
|
|
@@ -3354,16 +3514,25 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3354
3514
|
const isExternal = isExternalHref(href);
|
|
3355
3515
|
const effectiveTarget = target ?? (isExternal ? "_blank" : void 0);
|
|
3356
3516
|
const effectiveRel = rel ?? (isExternal ? "noopener noreferrer" : void 0);
|
|
3357
|
-
const [editingMode, setEditingMode] =
|
|
3358
|
-
const [
|
|
3359
|
-
const [
|
|
3360
|
-
const [
|
|
3361
|
-
const [
|
|
3362
|
-
const [
|
|
3363
|
-
const
|
|
3364
|
-
const
|
|
3365
|
-
const
|
|
3366
|
-
|
|
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;
|
|
3367
3536
|
const editor = useEditor2({
|
|
3368
3537
|
extensions: [
|
|
3369
3538
|
StarterKit2.configure({
|
|
@@ -3386,26 +3555,19 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3386
3555
|
}
|
|
3387
3556
|
}
|
|
3388
3557
|
});
|
|
3389
|
-
|
|
3558
|
+
useEffect10(() => {
|
|
3390
3559
|
if (editor && editingMode !== "text") {
|
|
3391
3560
|
if (editor.getHTML() !== text) {
|
|
3392
3561
|
editor.commands.setContent(text);
|
|
3393
3562
|
}
|
|
3394
3563
|
}
|
|
3395
3564
|
}, [text, editor, editingMode]);
|
|
3396
|
-
|
|
3565
|
+
useEffect10(() => {
|
|
3397
3566
|
if (editingMode !== "link") {
|
|
3398
3567
|
setCurrentHref(href);
|
|
3399
3568
|
}
|
|
3400
3569
|
}, [href, editingMode]);
|
|
3401
|
-
|
|
3402
|
-
return () => {
|
|
3403
|
-
if (hidePopoverTimeoutRef.current) {
|
|
3404
|
-
clearTimeout(hidePopoverTimeoutRef.current);
|
|
3405
|
-
}
|
|
3406
|
-
};
|
|
3407
|
-
}, []);
|
|
3408
|
-
useEffect8(() => {
|
|
3570
|
+
useEffect10(() => {
|
|
3409
3571
|
if (editingMode !== "link") return;
|
|
3410
3572
|
const handleClickOutside = (event) => {
|
|
3411
3573
|
const target2 = event.target;
|
|
@@ -3419,7 +3581,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3419
3581
|
document.addEventListener("mousedown", handleClickOutside);
|
|
3420
3582
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
3421
3583
|
}, [editingMode, originalHref]);
|
|
3422
|
-
const handleSaveText =
|
|
3584
|
+
const handleSaveText = useCallback10(() => {
|
|
3423
3585
|
if (!editor) return;
|
|
3424
3586
|
let html = editor.getHTML();
|
|
3425
3587
|
html = html.replace(/<\/p><p>/g, "<br><br>").replace(/^<p>/, "").replace(/<\/p>$/, "");
|
|
@@ -3427,26 +3589,26 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3427
3589
|
saveToWorker?.(textFieldId, html);
|
|
3428
3590
|
setEditingMode(null);
|
|
3429
3591
|
}, [editor, textFieldId, setValue, saveToWorker]);
|
|
3430
|
-
const handleSaveLink =
|
|
3592
|
+
const handleSaveLink = useCallback10(() => {
|
|
3431
3593
|
setValue(hrefFieldId, currentHref);
|
|
3432
3594
|
saveToWorker?.(hrefFieldId, currentHref);
|
|
3433
3595
|
setEditingMode(null);
|
|
3434
3596
|
setIsExternalUrl(false);
|
|
3435
3597
|
setExternalUrl("");
|
|
3436
3598
|
}, [hrefFieldId, currentHref, setValue, saveToWorker]);
|
|
3437
|
-
const handleCancelText =
|
|
3599
|
+
const handleCancelText = useCallback10(() => {
|
|
3438
3600
|
if (editor) {
|
|
3439
3601
|
editor.commands.setContent(originalText);
|
|
3440
3602
|
}
|
|
3441
3603
|
setEditingMode(null);
|
|
3442
3604
|
}, [editor, originalText]);
|
|
3443
|
-
const handleCancelLink =
|
|
3605
|
+
const handleCancelLink = useCallback10(() => {
|
|
3444
3606
|
setCurrentHref(originalHref);
|
|
3445
3607
|
setEditingMode(null);
|
|
3446
3608
|
setIsExternalUrl(false);
|
|
3447
3609
|
setExternalUrl("");
|
|
3448
3610
|
}, [originalHref]);
|
|
3449
|
-
const handleClick =
|
|
3611
|
+
const handleClick = useCallback10(
|
|
3450
3612
|
(e) => {
|
|
3451
3613
|
const selectModeEnabled = window.__builderSelectModeEnabled;
|
|
3452
3614
|
if (selectModeEnabled) {
|
|
@@ -3478,43 +3640,22 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3478
3640
|
},
|
|
3479
3641
|
[href, navigate, onClick]
|
|
3480
3642
|
);
|
|
3481
|
-
const
|
|
3482
|
-
|
|
3483
|
-
clearTimeout(hidePopoverTimeoutRef.current);
|
|
3484
|
-
hidePopoverTimeoutRef.current = null;
|
|
3485
|
-
}
|
|
3486
|
-
if (mode === "inline-edit" && !editingMode) {
|
|
3487
|
-
setShowEditPopover(true);
|
|
3488
|
-
}
|
|
3489
|
-
}, [mode, editingMode]);
|
|
3490
|
-
const handleMouseLeave = useCallback9(() => {
|
|
3491
|
-
hidePopoverTimeoutRef.current = window.setTimeout(() => {
|
|
3492
|
-
if (!editingMode) {
|
|
3493
|
-
setShowEditPopover(false);
|
|
3494
|
-
}
|
|
3495
|
-
}, 150);
|
|
3496
|
-
}, [editingMode]);
|
|
3497
|
-
const handleFocus = useCallback9(() => {
|
|
3498
|
-
if (mode === "inline-edit" && !editingMode) {
|
|
3499
|
-
setShowEditPopover(true);
|
|
3500
|
-
}
|
|
3501
|
-
}, [mode, editingMode]);
|
|
3502
|
-
const startEditText = useCallback9(() => {
|
|
3503
|
-
setShowEditPopover(false);
|
|
3643
|
+
const startEditText = useCallback10(() => {
|
|
3644
|
+
hideEditPopover();
|
|
3504
3645
|
setEditingMode("text");
|
|
3505
3646
|
setOriginalText(text);
|
|
3506
3647
|
setTimeout(() => {
|
|
3507
3648
|
editor?.chain().focus().selectAll().run();
|
|
3508
3649
|
}, 20);
|
|
3509
|
-
}, [text, editor]);
|
|
3510
|
-
const startEditLink =
|
|
3511
|
-
|
|
3650
|
+
}, [text, editor, hideEditPopover]);
|
|
3651
|
+
const startEditLink = useCallback10(() => {
|
|
3652
|
+
hideEditPopover();
|
|
3512
3653
|
setEditingMode("link");
|
|
3513
3654
|
setOriginalHref(href);
|
|
3514
3655
|
setCurrentHref(href);
|
|
3515
3656
|
setSections(discoverSectionsFromDOM());
|
|
3516
|
-
}, [href]);
|
|
3517
|
-
const handleKeyDown =
|
|
3657
|
+
}, [href, hideEditPopover]);
|
|
3658
|
+
const handleKeyDown = useCallback10(
|
|
3518
3659
|
(event) => {
|
|
3519
3660
|
if (editingMode !== "text") return;
|
|
3520
3661
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
@@ -3535,7 +3676,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3535
3676
|
},
|
|
3536
3677
|
[editingMode, handleSaveText, handleCancelText]
|
|
3537
3678
|
);
|
|
3538
|
-
const handleFontSizeChange =
|
|
3679
|
+
const handleFontSizeChange = useCallback10(
|
|
3539
3680
|
(e) => {
|
|
3540
3681
|
if (!editor) return;
|
|
3541
3682
|
const size = e.target.value;
|
|
@@ -3547,7 +3688,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3547
3688
|
},
|
|
3548
3689
|
[editor]
|
|
3549
3690
|
);
|
|
3550
|
-
const handleFontWeightChange =
|
|
3691
|
+
const handleFontWeightChange = useCallback10(
|
|
3551
3692
|
(e) => {
|
|
3552
3693
|
if (!editor) return;
|
|
3553
3694
|
const weight = e.target.value;
|
|
@@ -3559,11 +3700,11 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3559
3700
|
},
|
|
3560
3701
|
[editor]
|
|
3561
3702
|
);
|
|
3562
|
-
const handlePageSelect =
|
|
3703
|
+
const handlePageSelect = useCallback10((path) => {
|
|
3563
3704
|
setCurrentHref(path);
|
|
3564
3705
|
setIsExternalUrl(false);
|
|
3565
3706
|
}, []);
|
|
3566
|
-
const handleExternalUrlApply =
|
|
3707
|
+
const handleExternalUrlApply = useCallback10(() => {
|
|
3567
3708
|
if (externalUrl) {
|
|
3568
3709
|
setCurrentHref(externalUrl);
|
|
3569
3710
|
}
|
|
@@ -3579,9 +3720,9 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3579
3720
|
return attrs.fontWeight || "";
|
|
3580
3721
|
};
|
|
3581
3722
|
if (mode === "read-only") {
|
|
3582
|
-
const content = isIconMode ? children : /* @__PURE__ */
|
|
3723
|
+
const content = isIconMode ? children : /* @__PURE__ */ jsx10(SafeHtml, { content: text, mode });
|
|
3583
3724
|
if (isInternalPath(href)) {
|
|
3584
|
-
return /* @__PURE__ */
|
|
3725
|
+
return /* @__PURE__ */ jsx10(
|
|
3585
3726
|
WouterLink,
|
|
3586
3727
|
{
|
|
3587
3728
|
href,
|
|
@@ -3593,7 +3734,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3593
3734
|
}
|
|
3594
3735
|
);
|
|
3595
3736
|
}
|
|
3596
|
-
return /* @__PURE__ */
|
|
3737
|
+
return /* @__PURE__ */ jsx10(
|
|
3597
3738
|
Component,
|
|
3598
3739
|
{
|
|
3599
3740
|
ref: containerRef,
|
|
@@ -3609,7 +3750,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3609
3750
|
);
|
|
3610
3751
|
}
|
|
3611
3752
|
return /* @__PURE__ */ jsxs5("span", { className: "ya-link-wrapper", children: [
|
|
3612
|
-
/* @__PURE__ */
|
|
3753
|
+
/* @__PURE__ */ jsx10(
|
|
3613
3754
|
Component,
|
|
3614
3755
|
{
|
|
3615
3756
|
ref: containerRef,
|
|
@@ -3621,15 +3762,15 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3621
3762
|
"data-ya-restricted": "true",
|
|
3622
3763
|
"data-field-id": fieldId,
|
|
3623
3764
|
onClick: handleClick,
|
|
3624
|
-
onMouseEnter:
|
|
3625
|
-
onMouseLeave:
|
|
3626
|
-
onFocus:
|
|
3765
|
+
onMouseEnter: safeTriangleHandlers.onMouseEnter,
|
|
3766
|
+
onMouseLeave: safeTriangleHandlers.onMouseLeave,
|
|
3767
|
+
onFocus: safeTriangleHandlers.onFocus,
|
|
3627
3768
|
onKeyDown: handleKeyDown,
|
|
3628
3769
|
children: isIconMode ? (
|
|
3629
3770
|
// Icon mode: render children directly, no text editing
|
|
3630
3771
|
children
|
|
3631
3772
|
) : editor ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3632
|
-
|
|
3773
|
+
createPortal5(
|
|
3633
3774
|
/* @__PURE__ */ jsxs5(
|
|
3634
3775
|
BubbleMenu2,
|
|
3635
3776
|
{
|
|
@@ -3638,27 +3779,27 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3638
3779
|
options: { offset: 6, placement: "top" },
|
|
3639
3780
|
className: "ya-bubble-menu",
|
|
3640
3781
|
children: [
|
|
3641
|
-
/* @__PURE__ */
|
|
3782
|
+
/* @__PURE__ */ jsx10(
|
|
3642
3783
|
"button",
|
|
3643
3784
|
{
|
|
3644
3785
|
type: "button",
|
|
3645
3786
|
onClick: () => editor.chain().focus().toggleBold().run(),
|
|
3646
3787
|
className: `ya-bubble-btn ${editor.isActive("bold") ? "is-active" : ""}`,
|
|
3647
3788
|
title: "Bold",
|
|
3648
|
-
children: /* @__PURE__ */
|
|
3789
|
+
children: /* @__PURE__ */ jsx10("strong", { children: "B" })
|
|
3649
3790
|
}
|
|
3650
3791
|
),
|
|
3651
|
-
/* @__PURE__ */
|
|
3792
|
+
/* @__PURE__ */ jsx10(
|
|
3652
3793
|
"button",
|
|
3653
3794
|
{
|
|
3654
3795
|
type: "button",
|
|
3655
3796
|
onClick: () => editor.chain().focus().toggleItalic().run(),
|
|
3656
3797
|
className: `ya-bubble-btn ${editor.isActive("italic") ? "is-active" : ""}`,
|
|
3657
3798
|
title: "Italic",
|
|
3658
|
-
children: /* @__PURE__ */
|
|
3799
|
+
children: /* @__PURE__ */ jsx10("em", { children: "I" })
|
|
3659
3800
|
}
|
|
3660
3801
|
),
|
|
3661
|
-
/* @__PURE__ */
|
|
3802
|
+
/* @__PURE__ */ jsx10("span", { className: "ya-bubble-divider" }),
|
|
3662
3803
|
/* @__PURE__ */ jsxs5(
|
|
3663
3804
|
"select",
|
|
3664
3805
|
{
|
|
@@ -3667,8 +3808,8 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3667
3808
|
className: "ya-bubble-select",
|
|
3668
3809
|
title: "Font Size",
|
|
3669
3810
|
children: [
|
|
3670
|
-
/* @__PURE__ */
|
|
3671
|
-
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))
|
|
3672
3813
|
]
|
|
3673
3814
|
}
|
|
3674
3815
|
),
|
|
@@ -3680,8 +3821,8 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3680
3821
|
className: "ya-bubble-select",
|
|
3681
3822
|
title: "Font Weight",
|
|
3682
3823
|
children: [
|
|
3683
|
-
/* @__PURE__ */
|
|
3684
|
-
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))
|
|
3685
3826
|
]
|
|
3686
3827
|
}
|
|
3687
3828
|
)
|
|
@@ -3691,21 +3832,39 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3691
3832
|
document.body
|
|
3692
3833
|
),
|
|
3693
3834
|
editingMode === "text" ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3694
|
-
/* @__PURE__ */
|
|
3835
|
+
/* @__PURE__ */ jsx10(EditorContent2, { editor }),
|
|
3695
3836
|
/* @__PURE__ */ jsxs5("div", { className: "ya-link-actions", children: [
|
|
3696
|
-
/* @__PURE__ */
|
|
3697
|
-
/* @__PURE__ */
|
|
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" })
|
|
3698
3839
|
] })
|
|
3699
|
-
] }) : /* @__PURE__ */
|
|
3700
|
-
] }) : /* @__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
|
|
3701
3864
|
}
|
|
3702
3865
|
),
|
|
3703
|
-
showEditPopover && !editingMode && mode === "inline-edit" && /* @__PURE__ */ jsxs5("div", { className: "ya-link-edit-popover", onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [
|
|
3704
|
-
!isIconMode && /* @__PURE__ */ jsx9("button", { type: "button", onClick: startEditText, children: "Edit text" }),
|
|
3705
|
-
/* @__PURE__ */ jsx9("button", { type: "button", onClick: startEditLink, children: "Edit link" })
|
|
3706
|
-
] }),
|
|
3707
3866
|
editingMode === "link" && /* @__PURE__ */ jsxs5("div", { ref: hrefPopoverRef, className: "ya-href-popover", children: [
|
|
3708
|
-
/* @__PURE__ */
|
|
3867
|
+
/* @__PURE__ */ jsx10("div", { className: "ya-href-popover-header", children: "Link destination" }),
|
|
3709
3868
|
!isExternalUrl ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3710
3869
|
sections.length > 0 && /* @__PURE__ */ jsxs5("div", { className: "ya-href-popover-section", children: [
|
|
3711
3870
|
/* @__PURE__ */ jsxs5(
|
|
@@ -3715,14 +3874,14 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3715
3874
|
className: "ya-href-popover-label ya-href-collapsible-header",
|
|
3716
3875
|
onClick: () => setSectionsExpanded(!sectionsExpanded),
|
|
3717
3876
|
children: [
|
|
3718
|
-
/* @__PURE__ */
|
|
3877
|
+
/* @__PURE__ */ jsx10("span", { className: "ya-href-chevron", children: sectionsExpanded ? "\u25BC" : "\u25B6" }),
|
|
3719
3878
|
"Scroll to section (",
|
|
3720
3879
|
sections.length,
|
|
3721
3880
|
")"
|
|
3722
3881
|
]
|
|
3723
3882
|
}
|
|
3724
3883
|
),
|
|
3725
|
-
sectionsExpanded && /* @__PURE__ */
|
|
3884
|
+
sectionsExpanded && /* @__PURE__ */ jsx10("div", { className: "ya-href-popover-pages", children: sections.map((section) => /* @__PURE__ */ jsxs5(
|
|
3726
3885
|
"button",
|
|
3727
3886
|
{
|
|
3728
3887
|
type: "button",
|
|
@@ -3730,15 +3889,15 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3730
3889
|
onClick: () => handlePageSelect(section.path),
|
|
3731
3890
|
children: [
|
|
3732
3891
|
section.label,
|
|
3733
|
-
/* @__PURE__ */
|
|
3892
|
+
/* @__PURE__ */ jsx10("span", { className: "ya-href-page-path", children: section.path })
|
|
3734
3893
|
]
|
|
3735
3894
|
},
|
|
3736
3895
|
section.path
|
|
3737
3896
|
)) })
|
|
3738
3897
|
] }),
|
|
3739
3898
|
pages.length > 0 && /* @__PURE__ */ jsxs5("div", { className: "ya-href-popover-section", children: [
|
|
3740
|
-
/* @__PURE__ */
|
|
3741
|
-
/* @__PURE__ */
|
|
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(
|
|
3742
3901
|
"button",
|
|
3743
3902
|
{
|
|
3744
3903
|
type: "button",
|
|
@@ -3746,13 +3905,13 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3746
3905
|
onClick: () => handlePageSelect(page.path),
|
|
3747
3906
|
children: [
|
|
3748
3907
|
page.label,
|
|
3749
|
-
/* @__PURE__ */
|
|
3908
|
+
/* @__PURE__ */ jsx10("span", { className: "ya-href-page-path", children: page.path })
|
|
3750
3909
|
]
|
|
3751
3910
|
},
|
|
3752
3911
|
page.path
|
|
3753
3912
|
)) })
|
|
3754
3913
|
] }),
|
|
3755
|
-
/* @__PURE__ */
|
|
3914
|
+
/* @__PURE__ */ jsx10(
|
|
3756
3915
|
"button",
|
|
3757
3916
|
{
|
|
3758
3917
|
type: "button",
|
|
@@ -3766,8 +3925,8 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3766
3925
|
)
|
|
3767
3926
|
] }) : /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
3768
3927
|
/* @__PURE__ */ jsxs5("div", { className: "ya-href-popover-section", children: [
|
|
3769
|
-
/* @__PURE__ */
|
|
3770
|
-
/* @__PURE__ */
|
|
3928
|
+
/* @__PURE__ */ jsx10("label", { className: "ya-href-popover-label", children: "External URL" }),
|
|
3929
|
+
/* @__PURE__ */ jsx10(
|
|
3771
3930
|
"input",
|
|
3772
3931
|
{
|
|
3773
3932
|
type: "url",
|
|
@@ -3779,25 +3938,25 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
|
|
|
3779
3938
|
}
|
|
3780
3939
|
)
|
|
3781
3940
|
] }),
|
|
3782
|
-
/* @__PURE__ */
|
|
3941
|
+
/* @__PURE__ */ jsx10("button", { type: "button", className: "ya-href-external-toggle", onClick: () => setIsExternalUrl(false), children: "\u2190 Back to pages" })
|
|
3783
3942
|
] }),
|
|
3784
3943
|
/* @__PURE__ */ jsxs5("div", { className: "ya-href-popover-actions", children: [
|
|
3785
|
-
/* @__PURE__ */
|
|
3786
|
-
isExternalUrl ? /* @__PURE__ */
|
|
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" })
|
|
3787
3946
|
] })
|
|
3788
3947
|
] })
|
|
3789
3948
|
] });
|
|
3790
3949
|
}
|
|
3791
3950
|
|
|
3792
3951
|
// src/components/YaContainer.tsx
|
|
3793
|
-
import { useCallback as
|
|
3794
|
-
import { createPortal as
|
|
3952
|
+
import { useCallback as useCallback11, useEffect as useEffect11, useRef as useRef11, useState as useState11 } from "react";
|
|
3953
|
+
import { createPortal as createPortal6 } from "react-dom";
|
|
3795
3954
|
|
|
3796
3955
|
// src/components/ya-container.css
|
|
3797
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');
|
|
3798
3957
|
|
|
3799
3958
|
// src/components/YaContainer.tsx
|
|
3800
|
-
import { jsx as
|
|
3959
|
+
import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3801
3960
|
function parseBackgroundConfig(value) {
|
|
3802
3961
|
if (!value) {
|
|
3803
3962
|
return { type: "none" };
|
|
@@ -3839,8 +3998,8 @@ function deriveContainerLabel(element) {
|
|
|
3839
3998
|
return tagLabels[tagName] || "Section";
|
|
3840
3999
|
}
|
|
3841
4000
|
function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearClick, hasBackground }) {
|
|
3842
|
-
const [position, setPosition] =
|
|
3843
|
-
|
|
4001
|
+
const [position, setPosition] = useState11(null);
|
|
4002
|
+
useEffect11(() => {
|
|
3844
4003
|
const updatePosition = () => {
|
|
3845
4004
|
if (containerRef.current) {
|
|
3846
4005
|
const rect = containerRef.current.getBoundingClientRect();
|
|
@@ -3859,7 +4018,7 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
3859
4018
|
};
|
|
3860
4019
|
}, [containerRef]);
|
|
3861
4020
|
if (!position) return null;
|
|
3862
|
-
return
|
|
4021
|
+
return createPortal6(
|
|
3863
4022
|
/* @__PURE__ */ jsxs6(
|
|
3864
4023
|
"div",
|
|
3865
4024
|
{
|
|
@@ -3871,7 +4030,7 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
3871
4030
|
},
|
|
3872
4031
|
onClick: (e) => e.stopPropagation(),
|
|
3873
4032
|
children: [
|
|
3874
|
-
/* @__PURE__ */
|
|
4033
|
+
/* @__PURE__ */ jsx11(
|
|
3875
4034
|
"button",
|
|
3876
4035
|
{
|
|
3877
4036
|
type: "button",
|
|
@@ -3879,13 +4038,13 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
3879
4038
|
"aria-label": "Edit background image",
|
|
3880
4039
|
title: "Background Image",
|
|
3881
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: [
|
|
3882
|
-
/* @__PURE__ */
|
|
3883
|
-
/* @__PURE__ */
|
|
3884
|
-
/* @__PURE__ */
|
|
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" })
|
|
3885
4044
|
] })
|
|
3886
4045
|
}
|
|
3887
4046
|
),
|
|
3888
|
-
/* @__PURE__ */
|
|
4047
|
+
/* @__PURE__ */ jsx11(
|
|
3889
4048
|
"button",
|
|
3890
4049
|
{
|
|
3891
4050
|
type: "button",
|
|
@@ -3893,12 +4052,12 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
3893
4052
|
"aria-label": "Edit background color",
|
|
3894
4053
|
title: "Background Color",
|
|
3895
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: [
|
|
3896
|
-
/* @__PURE__ */
|
|
3897
|
-
/* @__PURE__ */
|
|
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" })
|
|
3898
4057
|
] })
|
|
3899
4058
|
}
|
|
3900
4059
|
),
|
|
3901
|
-
/* @__PURE__ */
|
|
4060
|
+
/* @__PURE__ */ jsx11(
|
|
3902
4061
|
"button",
|
|
3903
4062
|
{
|
|
3904
4063
|
type: "button",
|
|
@@ -3906,13 +4065,13 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
3906
4065
|
"aria-label": "Ask AI for help",
|
|
3907
4066
|
title: "AI Assist",
|
|
3908
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: [
|
|
3909
|
-
/* @__PURE__ */
|
|
3910
|
-
/* @__PURE__ */
|
|
3911
|
-
/* @__PURE__ */
|
|
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" })
|
|
3912
4071
|
] })
|
|
3913
4072
|
}
|
|
3914
4073
|
),
|
|
3915
|
-
hasBackground && /* @__PURE__ */
|
|
4074
|
+
hasBackground && /* @__PURE__ */ jsx11(
|
|
3916
4075
|
"button",
|
|
3917
4076
|
{
|
|
3918
4077
|
type: "button",
|
|
@@ -3920,8 +4079,8 @@ function Toolbar({ containerRef, onImageClick, onColorClick, onAIClick, onClearC
|
|
|
3920
4079
|
"aria-label": "Clear background",
|
|
3921
4080
|
title: "Clear Background",
|
|
3922
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: [
|
|
3923
|
-
/* @__PURE__ */
|
|
3924
|
-
/* @__PURE__ */
|
|
4082
|
+
/* @__PURE__ */ jsx11("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
4083
|
+
/* @__PURE__ */ jsx11("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
3925
4084
|
] })
|
|
3926
4085
|
}
|
|
3927
4086
|
)
|
|
@@ -3940,11 +4099,11 @@ function YaContainer({
|
|
|
3940
4099
|
defaultBackground
|
|
3941
4100
|
}) {
|
|
3942
4101
|
const { getValue, setValue, saveToWorker, mode } = useContentStore();
|
|
3943
|
-
const containerRef =
|
|
3944
|
-
const [isHovered, setIsHovered] =
|
|
3945
|
-
const [isSelected, setIsSelected] =
|
|
3946
|
-
const [isDropMode, setIsDropMode] =
|
|
3947
|
-
const [isDropHover, setIsDropHover] =
|
|
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);
|
|
3948
4107
|
const rawValue = getValue(fieldId);
|
|
3949
4108
|
const backgroundConfig = rawValue ? parseBackgroundConfig(rawValue) : defaultBackground || { type: "none" };
|
|
3950
4109
|
const hasBackground = backgroundConfig.type !== "none";
|
|
@@ -3965,7 +4124,7 @@ function YaContainer({
|
|
|
3965
4124
|
overlayCustomProps["--ya-overlay-color"] = backgroundConfig.overlay.color;
|
|
3966
4125
|
overlayCustomProps["--ya-overlay-opacity"] = backgroundConfig.overlay.opacity;
|
|
3967
4126
|
}
|
|
3968
|
-
const handleImageClick =
|
|
4127
|
+
const handleImageClick = useCallback11(() => {
|
|
3969
4128
|
if (mode !== "inline-edit") return;
|
|
3970
4129
|
setIsSelected(true);
|
|
3971
4130
|
const rect = containerRef.current?.getBoundingClientRect();
|
|
@@ -3985,7 +4144,7 @@ function YaContainer({
|
|
|
3985
4144
|
"*"
|
|
3986
4145
|
);
|
|
3987
4146
|
}, [mode, fieldId, backgroundConfig]);
|
|
3988
|
-
const handleColorClick =
|
|
4147
|
+
const handleColorClick = useCallback11(() => {
|
|
3989
4148
|
if (mode !== "inline-edit") return;
|
|
3990
4149
|
setIsSelected(true);
|
|
3991
4150
|
const rect = containerRef.current?.getBoundingClientRect();
|
|
@@ -4005,7 +4164,7 @@ function YaContainer({
|
|
|
4005
4164
|
"*"
|
|
4006
4165
|
);
|
|
4007
4166
|
}, [mode, fieldId, backgroundConfig]);
|
|
4008
|
-
const handleAIClick =
|
|
4167
|
+
const handleAIClick = useCallback11(() => {
|
|
4009
4168
|
if (mode !== "inline-edit") return;
|
|
4010
4169
|
const label = deriveContainerLabel(containerRef.current);
|
|
4011
4170
|
window.parent.postMessage(
|
|
@@ -4018,14 +4177,14 @@ function YaContainer({
|
|
|
4018
4177
|
"*"
|
|
4019
4178
|
);
|
|
4020
4179
|
}, [mode, fieldId, backgroundConfig]);
|
|
4021
|
-
const handleClearClick =
|
|
4180
|
+
const handleClearClick = useCallback11(() => {
|
|
4022
4181
|
if (mode !== "inline-edit") return;
|
|
4023
4182
|
const clearedConfig = { type: "none" };
|
|
4024
4183
|
const serialized = serializeBackgroundConfig(clearedConfig);
|
|
4025
4184
|
setValue(fieldId, serialized);
|
|
4026
4185
|
saveToWorker?.(fieldId, serialized);
|
|
4027
4186
|
}, [mode, fieldId, setValue, saveToWorker]);
|
|
4028
|
-
|
|
4187
|
+
useEffect11(() => {
|
|
4029
4188
|
if (mode !== "inline-edit") return;
|
|
4030
4189
|
const handleMessage2 = (event) => {
|
|
4031
4190
|
if (event.data?.type === "YA_CONTAINER_EDIT_COMPLETE" && event.data.fieldId === fieldId) {
|
|
@@ -4038,7 +4197,7 @@ function YaContainer({
|
|
|
4038
4197
|
window.addEventListener("message", handleMessage2);
|
|
4039
4198
|
return () => window.removeEventListener("message", handleMessage2);
|
|
4040
4199
|
}, [mode, fieldId]);
|
|
4041
|
-
|
|
4200
|
+
useEffect11(() => {
|
|
4042
4201
|
if (mode !== "inline-edit") return;
|
|
4043
4202
|
const handleDropModeMessage = (event) => {
|
|
4044
4203
|
if (event.data?.type === "DROP_MODE_START") {
|
|
@@ -4052,7 +4211,7 @@ function YaContainer({
|
|
|
4052
4211
|
window.addEventListener("message", handleDropModeMessage);
|
|
4053
4212
|
return () => window.removeEventListener("message", handleDropModeMessage);
|
|
4054
4213
|
}, [mode]);
|
|
4055
|
-
const handleDragEnter =
|
|
4214
|
+
const handleDragEnter = useCallback11(
|
|
4056
4215
|
(e) => {
|
|
4057
4216
|
if (!isDropMode) return;
|
|
4058
4217
|
e.preventDefault();
|
|
@@ -4076,7 +4235,7 @@ function YaContainer({
|
|
|
4076
4235
|
},
|
|
4077
4236
|
[isDropMode, fieldId]
|
|
4078
4237
|
);
|
|
4079
|
-
const handleDragOver =
|
|
4238
|
+
const handleDragOver = useCallback11(
|
|
4080
4239
|
(e) => {
|
|
4081
4240
|
if (!isDropMode) return;
|
|
4082
4241
|
e.preventDefault();
|
|
@@ -4084,7 +4243,7 @@ function YaContainer({
|
|
|
4084
4243
|
},
|
|
4085
4244
|
[isDropMode]
|
|
4086
4245
|
);
|
|
4087
|
-
const handleDragLeave =
|
|
4246
|
+
const handleDragLeave = useCallback11(
|
|
4088
4247
|
(e) => {
|
|
4089
4248
|
if (!isDropMode) return;
|
|
4090
4249
|
e.preventDefault();
|
|
@@ -4098,7 +4257,7 @@ function YaContainer({
|
|
|
4098
4257
|
},
|
|
4099
4258
|
[isDropMode]
|
|
4100
4259
|
);
|
|
4101
|
-
const handleDrop =
|
|
4260
|
+
const handleDrop = useCallback11(
|
|
4102
4261
|
(e) => {
|
|
4103
4262
|
if (!isDropMode) return;
|
|
4104
4263
|
e.preventDefault();
|
|
@@ -4116,7 +4275,7 @@ function YaContainer({
|
|
|
4116
4275
|
},
|
|
4117
4276
|
[isDropMode, fieldId]
|
|
4118
4277
|
);
|
|
4119
|
-
|
|
4278
|
+
useEffect11(() => {
|
|
4120
4279
|
if (!isSelected || mode !== "inline-edit") return;
|
|
4121
4280
|
let lastRectKey = "";
|
|
4122
4281
|
let lastTime = 0;
|
|
@@ -4151,7 +4310,7 @@ function YaContainer({
|
|
|
4151
4310
|
return () => cancelAnimationFrame(rafId);
|
|
4152
4311
|
}, [isSelected, fieldId, mode]);
|
|
4153
4312
|
if (mode === "read-only") {
|
|
4154
|
-
return /* @__PURE__ */
|
|
4313
|
+
return /* @__PURE__ */ jsx11(
|
|
4155
4314
|
Tag,
|
|
4156
4315
|
{
|
|
4157
4316
|
className: `ya-container ${className || ""}`,
|
|
@@ -4196,7 +4355,7 @@ function YaContainer({
|
|
|
4196
4355
|
onDrop: handleDrop,
|
|
4197
4356
|
children: [
|
|
4198
4357
|
children,
|
|
4199
|
-
mode === "inline-edit" && (isHovered || isSelected) && !document.body.classList.contains("builder-selector-active") && /* @__PURE__ */
|
|
4358
|
+
mode === "inline-edit" && (isHovered || isSelected) && !document.body.classList.contains("builder-selector-active") && /* @__PURE__ */ jsx11(
|
|
4200
4359
|
Toolbar,
|
|
4201
4360
|
{
|
|
4202
4361
|
containerRef,
|
|
@@ -4213,10 +4372,10 @@ function YaContainer({
|
|
|
4213
4372
|
}
|
|
4214
4373
|
|
|
4215
4374
|
// src/components/StaticText.tsx
|
|
4216
|
-
import { jsx as
|
|
4375
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
4217
4376
|
function MpText({ fieldId, className, as: Component = "span", children }) {
|
|
4218
4377
|
const content = getContent(fieldId) || (typeof children === "string" ? children : "");
|
|
4219
|
-
return /* @__PURE__ */
|
|
4378
|
+
return /* @__PURE__ */ jsx12(
|
|
4220
4379
|
Component,
|
|
4221
4380
|
{
|
|
4222
4381
|
className,
|
|
@@ -4227,7 +4386,7 @@ function MpText({ fieldId, className, as: Component = "span", children }) {
|
|
|
4227
4386
|
}
|
|
4228
4387
|
|
|
4229
4388
|
// src/components/StaticImage.tsx
|
|
4230
|
-
import { jsx as
|
|
4389
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
4231
4390
|
function parseImageValue2(value) {
|
|
4232
4391
|
if (!value) {
|
|
4233
4392
|
return { src: "" };
|
|
@@ -4263,7 +4422,7 @@ function MpImage({
|
|
|
4263
4422
|
const altText = imageData.alt || alt || fallbackAlt || "";
|
|
4264
4423
|
const objectFit = imageData.objectFit || propObjectFit || "cover";
|
|
4265
4424
|
const objectPosition = getObjectPosition3(imageData) || propObjectPosition || "50% 50%";
|
|
4266
|
-
return /* @__PURE__ */
|
|
4425
|
+
return /* @__PURE__ */ jsx13(
|
|
4267
4426
|
"img",
|
|
4268
4427
|
{
|
|
4269
4428
|
src: resolveAssetUrl(src),
|
|
@@ -4281,7 +4440,7 @@ function MpImage({
|
|
|
4281
4440
|
|
|
4282
4441
|
// src/components/MarkdownText.tsx
|
|
4283
4442
|
import { Fragment as Fragment4 } from "react";
|
|
4284
|
-
import { jsx as
|
|
4443
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
4285
4444
|
function tokenize(text) {
|
|
4286
4445
|
const tokens = [];
|
|
4287
4446
|
let remaining = text;
|
|
@@ -4343,13 +4502,13 @@ function tokensToElements(tokens) {
|
|
|
4343
4502
|
return tokens.map((token, index) => {
|
|
4344
4503
|
switch (token.type) {
|
|
4345
4504
|
case "text":
|
|
4346
|
-
return /* @__PURE__ */
|
|
4505
|
+
return /* @__PURE__ */ jsx14(Fragment4, { children: token.content }, index);
|
|
4347
4506
|
case "bold":
|
|
4348
|
-
return /* @__PURE__ */
|
|
4507
|
+
return /* @__PURE__ */ jsx14("strong", { children: token.content }, index);
|
|
4349
4508
|
case "italic":
|
|
4350
|
-
return /* @__PURE__ */
|
|
4509
|
+
return /* @__PURE__ */ jsx14("em", { children: token.content }, index);
|
|
4351
4510
|
case "link":
|
|
4352
|
-
return /* @__PURE__ */
|
|
4511
|
+
return /* @__PURE__ */ jsx14(
|
|
4353
4512
|
"a",
|
|
4354
4513
|
{
|
|
4355
4514
|
href: token.url,
|
|
@@ -4361,7 +4520,7 @@ function tokensToElements(tokens) {
|
|
|
4361
4520
|
index
|
|
4362
4521
|
);
|
|
4363
4522
|
case "newline":
|
|
4364
|
-
return /* @__PURE__ */
|
|
4523
|
+
return /* @__PURE__ */ jsx14("br", {}, index);
|
|
4365
4524
|
default:
|
|
4366
4525
|
return null;
|
|
4367
4526
|
}
|
|
@@ -4373,15 +4532,15 @@ function parseMarkdownToElements(content) {
|
|
|
4373
4532
|
}
|
|
4374
4533
|
function MarkdownText({ content, className }) {
|
|
4375
4534
|
const elements = parseMarkdownToElements(content);
|
|
4376
|
-
return /* @__PURE__ */
|
|
4535
|
+
return /* @__PURE__ */ jsx14("span", { className, children: elements });
|
|
4377
4536
|
}
|
|
4378
4537
|
|
|
4379
4538
|
// src/router/Link.tsx
|
|
4380
4539
|
import { Link as WouterLink2 } from "wouter";
|
|
4381
|
-
import { jsx as
|
|
4540
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
4382
4541
|
function Link2({ to, href, children, className, onClick, replace, ...props }) {
|
|
4383
4542
|
const target = href ?? to ?? "/";
|
|
4384
|
-
return /* @__PURE__ */
|
|
4543
|
+
return /* @__PURE__ */ jsx15(WouterLink2, { href: target, className, onClick, replace, ...props, children });
|
|
4385
4544
|
}
|
|
4386
4545
|
|
|
4387
4546
|
// src/router/useNavigate.ts
|
|
@@ -4400,7 +4559,7 @@ function useNavigate() {
|
|
|
4400
4559
|
|
|
4401
4560
|
// src/router/Router.tsx
|
|
4402
4561
|
import { Router as WouterRouter } from "wouter";
|
|
4403
|
-
import { jsx as
|
|
4562
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
4404
4563
|
function detectBasename() {
|
|
4405
4564
|
if (typeof window === "undefined") return "";
|
|
4406
4565
|
const sessionMatch = window.location.pathname.match(/^\/session\/[^/]+/);
|
|
@@ -4415,7 +4574,7 @@ function detectBasename() {
|
|
|
4415
4574
|
}
|
|
4416
4575
|
function Router({ children, base }) {
|
|
4417
4576
|
const basename = base ?? detectBasename();
|
|
4418
|
-
return /* @__PURE__ */
|
|
4577
|
+
return /* @__PURE__ */ jsx16(WouterRouter, { base: basename, children });
|
|
4419
4578
|
}
|
|
4420
4579
|
|
|
4421
4580
|
// src/router/index.ts
|
|
@@ -4429,6 +4588,7 @@ export {
|
|
|
4429
4588
|
Route,
|
|
4430
4589
|
Router,
|
|
4431
4590
|
SafeHtml,
|
|
4591
|
+
SafeTriangleBelow,
|
|
4432
4592
|
MpImage as StaticImage,
|
|
4433
4593
|
MpText as StaticText,
|
|
4434
4594
|
Switch,
|
|
@@ -4465,5 +4625,6 @@ export {
|
|
|
4465
4625
|
useContentStore,
|
|
4466
4626
|
useContentStore2 as useContentStoreProd,
|
|
4467
4627
|
useNavigate,
|
|
4468
|
-
useParams
|
|
4628
|
+
useParams,
|
|
4629
|
+
useSafeTriangle
|
|
4469
4630
|
};
|
package/dist/plugin.js
CHANGED
|
@@ -6,6 +6,37 @@ function yoamigoPlugin(options = {}) {
|
|
|
6
6
|
const templateDir = process.cwd();
|
|
7
7
|
const resolveFromTemplate = (relativePath) => path.resolve(templateDir, relativePath);
|
|
8
8
|
return [
|
|
9
|
+
// Content HMR plugin - enables hot reloading of content.ts without full page refresh
|
|
10
|
+
{
|
|
11
|
+
name: "yoamigo:content-hmr",
|
|
12
|
+
handleHotUpdate({ file, server }) {
|
|
13
|
+
if (!file.endsWith("/content.ts") && !file.endsWith("\\content.ts")) return;
|
|
14
|
+
server.ws.send({
|
|
15
|
+
type: "custom",
|
|
16
|
+
event: "yoamigo:content-update"
|
|
17
|
+
});
|
|
18
|
+
return [];
|
|
19
|
+
},
|
|
20
|
+
transform(code, id) {
|
|
21
|
+
if (!id.match(/\/main\.tsx?$/) && !id.match(/\\main\.tsx?$/)) return;
|
|
22
|
+
const hmrCode = `
|
|
23
|
+
// YoAmigo Content HMR - injected by yoamigo:content-hmr plugin
|
|
24
|
+
if (import.meta.hot) {
|
|
25
|
+
import.meta.hot.on('yoamigo:content-update', async () => {
|
|
26
|
+
try {
|
|
27
|
+
const { default: newContent } = await import('./content?t=' + Date.now())
|
|
28
|
+
const { registerContent } = await import('@yoamigo.com/core')
|
|
29
|
+
registerContent(newContent)
|
|
30
|
+
window.dispatchEvent(new CustomEvent('content-updated'))
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.error('[yoamigo:content-hmr] Failed to hot reload content:', err)
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
return { code: code + "\n" + hmrCode, map: null };
|
|
38
|
+
}
|
|
39
|
+
},
|
|
9
40
|
{
|
|
10
41
|
name: "yoamigo:config",
|
|
11
42
|
config(config, { mode }) {
|
package/dist/prod.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { a as ContentStore, E as ContentStoreMode, C as ContentStoreProvider, d as MarkdownText, e as MarkdownTextProps, P as PageInfo, b as StaticImage, c as StaticImageProps, M as StaticText, S as StaticTextProps, b as YaImage, c as YaImageProps, M as YaText, S as YaTextProps, u as useContentStore } from './MarkdownText-
|
|
1
|
+
export { a as ContentStore, E as ContentStoreMode, C as ContentStoreProvider, d as MarkdownText, e as MarkdownTextProps, P as PageInfo, b as StaticImage, c as StaticImageProps, M as StaticText, S as StaticTextProps, b as YaImage, c as YaImageProps, M as YaText, S as YaTextProps, u as useContentStore } from './MarkdownText-kV5IiAma.js';
|
|
2
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
|
-
import
|
|
3
|
+
import React__default from 'react';
|
|
4
4
|
export { Link, LinkProps, NavigateFunction, Router, RouterProps, useNavigate } from './router.js';
|
|
5
5
|
export { Route, Switch, useParams } from 'wouter';
|
|
6
6
|
export { A as AssetResolverFn, C as ContentRegistry, c as contentRegistry, a as getAllContent, g as getContent, h as hasContent, r as registerContent, b as resolveAssetUrl, s as setAssetResolver } from './asset-resolver-BnIvDkVv.js';
|
|
@@ -10,9 +10,9 @@ interface StaticLinkProps {
|
|
|
10
10
|
href?: string;
|
|
11
11
|
className?: string;
|
|
12
12
|
/** Inline styles to apply to the link element */
|
|
13
|
-
style?:
|
|
13
|
+
style?: React__default.CSSProperties;
|
|
14
14
|
as?: 'a' | 'span';
|
|
15
|
-
children?:
|
|
15
|
+
children?: React__default.ReactNode;
|
|
16
16
|
/** Optional click handler called after navigation */
|
|
17
17
|
onClick?: () => void;
|
|
18
18
|
}
|