@yoamigo.com/core 0.4.3 → 0.4.4

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.
@@ -150,6 +150,8 @@ interface YaLinkProps {
150
150
  /** Default href if not set in content store */
151
151
  href?: string;
152
152
  className?: string;
153
+ /** Classes to apply to the wrapper span (for display/width control) */
154
+ wrapperClassName?: string;
153
155
  /** Inline styles to apply to the link element */
154
156
  style?: React$1.CSSProperties;
155
157
  as?: 'a' | 'span';
@@ -175,7 +177,7 @@ declare module '@tiptap/core' {
175
177
  };
176
178
  }
177
179
  }
178
- declare function YaLink({ fieldId, href: defaultHref, className, style, as: Component, children, availablePages, onClick, target, rel }: YaLinkProps): react_jsx_runtime.JSX.Element;
180
+ declare function YaLink({ fieldId, href: defaultHref, className, wrapperClassName, style, as: Component, children, availablePages, onClick, target, rel }: YaLinkProps): react_jsx_runtime.JSX.Element;
179
181
 
180
182
  interface BackgroundImageConfig {
181
183
  src: string;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React$1, { ReactNode } from 'react';
3
- export { D as BackgroundConfig, F as BackgroundImageConfig, C as ContentStoreProviderProd, q as EmbedFieldValue, r as EmbedType, I as ImageFieldValue, f as MarkdownText, g as MarkdownTextProps, O as OverlayConfig, P as PageInfo, c as StaticImage, d as StaticImageProps, M as StaticText, S as StaticTextProps, V as VideoFieldValue, y as YaContainer, B as YaContainerProps, m as YaEmbed, o as YaEmbedProps, Y as YaImage, h as YaImageProps, w as YaLink, x as YaLinkProps, j as YaVideo, l as YaVideoProps, b as background, e as embed, i as image, z as parseBackgroundConfig, p as parseEmbedUrl, A as serializeBackgroundConfig, n as serializeEmbedValue, s as serializeImageValue, k as serializeVideoValue, t as text, u as useContentStoreProd, v as video } from './content-helpers-kWphH5Tn.js';
3
+ export { D as BackgroundConfig, F as BackgroundImageConfig, C as ContentStoreProviderProd, q as EmbedFieldValue, r as EmbedType, I as ImageFieldValue, f as MarkdownText, g as MarkdownTextProps, O as OverlayConfig, P as PageInfo, c as StaticImage, d as StaticImageProps, M as StaticText, S as StaticTextProps, V as VideoFieldValue, y as YaContainer, B as YaContainerProps, m as YaEmbed, o as YaEmbedProps, Y as YaImage, h as YaImageProps, w as YaLink, x as YaLinkProps, j as YaVideo, l as YaVideoProps, b as background, e as embed, i as image, z as parseBackgroundConfig, p as parseEmbedUrl, A as serializeBackgroundConfig, n as serializeEmbedValue, s as serializeImageValue, k as serializeVideoValue, t as text, u as useContentStoreProd, v as video } from './content-helpers-DOUKazMz.js';
4
4
  export { Link, LinkProps, NavigateFunction, Router, RouterProps, ScrollRestoration, 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';
package/dist/index.js CHANGED
@@ -5213,7 +5213,7 @@ function TwitterWidgetLoader() {
5213
5213
  }
5214
5214
 
5215
5215
  // src/components/YaLink.tsx
5216
- import { useEffect as useEffect15, useRef as useRef16, useState as useState15, useCallback as useCallback17, useId } from "react";
5216
+ import { useEffect as useEffect15, useLayoutEffect as useLayoutEffect3, useRef as useRef16, useState as useState15, useCallback as useCallback17, useId } from "react";
5217
5217
  import { createPortal as createPortal6 } from "react-dom";
5218
5218
  import { useEditor as useEditor2, EditorContent as EditorContent2 } from "@tiptap/react";
5219
5219
  import { BubbleMenu } from "@tiptap/react/menus";
@@ -5366,7 +5366,7 @@ function useSafeTriangle(options = {}) {
5366
5366
  }
5367
5367
 
5368
5368
  // src/components/ya-link.css
5369
- 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}\n.ProseMirror-gapcursor {\n display: none !important;\n}\n.ProseMirror .ProseMirror-dropcursor {\n display: none !important;\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');
5369
+ 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}\n.ProseMirror-gapcursor {\n display: none !important;\n}\n.ProseMirror .ProseMirror-dropcursor {\n display: none !important;\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: fixed;\n z-index: 10000;\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 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 }\n to {\n opacity: 1;\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 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 }\n to {\n opacity: 1;\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: fixed;\n z-index: 10000;\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 transition: opacity 100ms ease;\n font-family:\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n white-space: nowrap;\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');
5370
5370
 
5371
5371
  // src/components/YaLink.tsx
5372
5372
  import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
@@ -5466,7 +5466,7 @@ function discoverSectionsFromDOM() {
5466
5466
  });
5467
5467
  return sections;
5468
5468
  }
5469
- function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Component = "a", children, availablePages, onClick, target, rel }) {
5469
+ function YaLink({ fieldId, href: defaultHref = "#", className, wrapperClassName, style, as: Component = "a", children, availablePages, onClick, target, rel }) {
5470
5470
  const { getValue, setValue, mode, saveToWorker, getPages } = useContentStore();
5471
5471
  const [, navigate] = useLocation();
5472
5472
  const pages = availablePages ?? getPages();
@@ -5488,10 +5488,13 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
5488
5488
  const [currentHref, setCurrentHref] = useState15(href);
5489
5489
  const [isExternalUrl, setIsExternalUrl] = useState15(false);
5490
5490
  const [externalUrl, setExternalUrl] = useState15("");
5491
- const [popoverPosition, setPopoverPosition] = useState15("below");
5492
5491
  const containerRef = useRef16(null);
5493
5492
  const hrefPopoverRef = useRef16(null);
5494
5493
  const [actionButtonsPos, setActionButtonsPos] = useState15(null);
5494
+ const [editPopoverPos, setEditPopoverPos] = useState15(null);
5495
+ const [editPopoverVisible, setEditPopoverVisible] = useState15(false);
5496
+ const [editPopoverMounted, setEditPopoverMounted] = useState15(false);
5497
+ const [hrefPopoverPos, setHrefPopoverPos] = useState15(null);
5495
5498
  const handleSaveTextRef = useRef16(() => {
5496
5499
  });
5497
5500
  const handleCancelTextRef = useRef16(() => {
@@ -5600,6 +5603,68 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
5600
5603
  window.removeEventListener("resize", updatePosition);
5601
5604
  };
5602
5605
  }, [editingMode]);
5606
+ useEffect15(() => {
5607
+ const shouldShow = showEditPopover && !editingMode && mode === "inline-edit";
5608
+ if (shouldShow) {
5609
+ setEditPopoverMounted(true);
5610
+ requestAnimationFrame(() => {
5611
+ setEditPopoverVisible(true);
5612
+ });
5613
+ } else {
5614
+ setEditPopoverVisible(false);
5615
+ const timer = setTimeout(() => {
5616
+ setEditPopoverMounted(false);
5617
+ }, 100);
5618
+ return () => clearTimeout(timer);
5619
+ }
5620
+ }, [showEditPopover, editingMode, mode]);
5621
+ useLayoutEffect3(() => {
5622
+ if (!editPopoverMounted || !containerRef.current) {
5623
+ setEditPopoverPos(null);
5624
+ return;
5625
+ }
5626
+ const updatePosition = () => {
5627
+ if (!containerRef.current) return;
5628
+ const rect = containerRef.current.getBoundingClientRect();
5629
+ setEditPopoverPos({
5630
+ top: rect.bottom + 8,
5631
+ left: rect.left + rect.width / 2
5632
+ });
5633
+ };
5634
+ updatePosition();
5635
+ window.addEventListener("scroll", updatePosition, true);
5636
+ window.addEventListener("resize", updatePosition);
5637
+ return () => {
5638
+ window.removeEventListener("scroll", updatePosition, true);
5639
+ window.removeEventListener("resize", updatePosition);
5640
+ };
5641
+ }, [editPopoverMounted]);
5642
+ useLayoutEffect3(() => {
5643
+ if (editingMode !== "link" || !containerRef.current) {
5644
+ setHrefPopoverPos(null);
5645
+ return;
5646
+ }
5647
+ const updatePosition = () => {
5648
+ if (!containerRef.current) return;
5649
+ const rect = containerRef.current.getBoundingClientRect();
5650
+ const popoverHeight = 350;
5651
+ const spaceBelow = window.innerHeight - rect.bottom;
5652
+ const spaceAbove = rect.top;
5653
+ const isAbove = spaceBelow < popoverHeight && spaceAbove > spaceBelow;
5654
+ setHrefPopoverPos({
5655
+ top: isAbove ? rect.top - 8 : rect.bottom + 8,
5656
+ left: rect.left + rect.width / 2,
5657
+ isAbove
5658
+ });
5659
+ };
5660
+ updatePosition();
5661
+ window.addEventListener("scroll", updatePosition, true);
5662
+ window.addEventListener("resize", updatePosition);
5663
+ return () => {
5664
+ window.removeEventListener("scroll", updatePosition, true);
5665
+ window.removeEventListener("resize", updatePosition);
5666
+ };
5667
+ }, [editingMode]);
5603
5668
  useEffect15(() => {
5604
5669
  if (editingMode !== "link") return;
5605
5670
  const handleClickOutside = (event) => {
@@ -5614,19 +5679,6 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
5614
5679
  document.addEventListener("mousedown", handleClickOutside);
5615
5680
  return () => document.removeEventListener("mousedown", handleClickOutside);
5616
5681
  }, [editingMode, originalHref]);
5617
- useEffect15(() => {
5618
- if (editingMode !== "link" || !containerRef.current) return;
5619
- const updatePosition = () => {
5620
- if (!containerRef.current) return;
5621
- const rect = containerRef.current.getBoundingClientRect();
5622
- const popoverHeight = 350;
5623
- const spaceBelow = window.innerHeight - rect.bottom;
5624
- const spaceAbove = rect.top;
5625
- setPopoverPosition(spaceBelow < popoverHeight && spaceAbove > spaceBelow ? "above" : "below");
5626
- };
5627
- window.addEventListener("resize", updatePosition);
5628
- return () => window.removeEventListener("resize", updatePosition);
5629
- }, [editingMode]);
5630
5682
  const handleSaveText = useCallback17(() => {
5631
5683
  if (!editor) return;
5632
5684
  let html = editor.getHTML();
@@ -5710,13 +5762,6 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
5710
5762
  setOriginalHref(href);
5711
5763
  setCurrentHref(href);
5712
5764
  setSections(discoverSectionsFromDOM());
5713
- if (containerRef.current) {
5714
- const rect = containerRef.current.getBoundingClientRect();
5715
- const popoverHeight = 350;
5716
- const spaceBelow = window.innerHeight - rect.bottom;
5717
- const spaceAbove = rect.top;
5718
- setPopoverPosition(spaceBelow < popoverHeight && spaceAbove > spaceBelow ? "above" : "below");
5719
- }
5720
5765
  }, [href, hideEditPopover]);
5721
5766
  const handleKeyDown = useCallback17(
5722
5767
  (event) => {
@@ -5812,7 +5857,7 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
5812
5857
  }
5813
5858
  );
5814
5859
  }
5815
- return /* @__PURE__ */ jsxs9("span", { className: "ya-link-wrapper", children: [
5860
+ return /* @__PURE__ */ jsxs9("span", { className: `ya-link-wrapper ${wrapperClassName || ""}`, children: [
5816
5861
  /* @__PURE__ */ jsx15(
5817
5862
  Component,
5818
5863
  {
@@ -5918,18 +5963,27 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
5918
5963
  ] }) : /* @__PURE__ */ jsx15(SafeHtml, { content: text2, mode })
5919
5964
  }
5920
5965
  ),
5921
- showEditPopover && !editingMode && mode === "inline-edit" && /* @__PURE__ */ jsxs9(
5922
- "div",
5923
- {
5924
- ref: editPopoverRef,
5925
- className: "ya-link-edit-popover",
5926
- onMouseEnter: safeTriangleHandlers.onMouseEnter,
5927
- onMouseLeave: safeTriangleHandlers.onMouseLeave,
5928
- children: [
5929
- /* @__PURE__ */ jsx15("button", { type: "button", onClick: startEditText, children: "Edit text" }),
5930
- /* @__PURE__ */ jsx15("button", { type: "button", onClick: startEditLink, children: "Edit link" })
5931
- ]
5932
- }
5966
+ editPopoverMounted && editPopoverPos && createPortal6(
5967
+ /* @__PURE__ */ jsxs9(
5968
+ "div",
5969
+ {
5970
+ ref: editPopoverRef,
5971
+ className: "ya-link-edit-popover",
5972
+ style: {
5973
+ top: editPopoverPos.top,
5974
+ left: editPopoverPos.left,
5975
+ transform: "translateX(-50%)",
5976
+ opacity: editPopoverVisible ? 1 : 0
5977
+ },
5978
+ onMouseEnter: safeTriangleHandlers.onMouseEnter,
5979
+ onMouseLeave: safeTriangleHandlers.onMouseLeave,
5980
+ children: [
5981
+ /* @__PURE__ */ jsx15("button", { type: "button", onClick: startEditText, children: "Edit text" }),
5982
+ /* @__PURE__ */ jsx15("button", { type: "button", onClick: startEditLink, children: "Edit link" })
5983
+ ]
5984
+ }
5985
+ ),
5986
+ document.body
5933
5987
  ),
5934
5988
  /* @__PURE__ */ jsx15(
5935
5989
  SafeTriangleBelow,
@@ -5941,88 +5995,104 @@ function YaLink({ fieldId, href: defaultHref = "#", className, style, as: Compon
5941
5995
  onStayInside: triangleProps.onStayInside
5942
5996
  }
5943
5997
  ),
5944
- editingMode === "link" && /* @__PURE__ */ jsxs9("div", { ref: hrefPopoverRef, className: `ya-href-popover ${popoverPosition === "above" ? "ya-href-popover--above" : ""}`, children: [
5945
- /* @__PURE__ */ jsx15("div", { className: "ya-href-popover-header", children: "Link destination" }),
5946
- !isExternalUrl ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
5947
- sections.length > 0 && /* @__PURE__ */ jsxs9("div", { className: "ya-href-popover-section", children: [
5948
- /* @__PURE__ */ jsxs9(
5949
- "button",
5950
- {
5951
- type: "button",
5952
- className: "ya-href-popover-label ya-href-collapsible-header",
5953
- onClick: () => setSectionsExpanded(!sectionsExpanded),
5954
- children: [
5955
- /* @__PURE__ */ jsx15("span", { className: "ya-href-chevron", children: sectionsExpanded ? "\u25BC" : "\u25B6" }),
5956
- "Scroll to section (",
5957
- sections.length,
5958
- ")"
5959
- ]
5960
- }
5961
- ),
5962
- sectionsExpanded && /* @__PURE__ */ jsx15("div", { className: "ya-href-popover-pages", children: sections.map((section) => /* @__PURE__ */ jsxs9(
5963
- "button",
5964
- {
5965
- type: "button",
5966
- className: `ya-href-page-btn ${currentHref === section.path ? "is-selected" : ""}`,
5967
- onClick: () => handlePageSelect(section.path),
5968
- children: [
5969
- section.label,
5970
- /* @__PURE__ */ jsx15("span", { className: "ya-href-page-path", children: section.path })
5971
- ]
5972
- },
5973
- section.path
5974
- )) })
5975
- ] }),
5976
- pages.length > 0 && /* @__PURE__ */ jsxs9("div", { className: "ya-href-popover-section", children: [
5977
- /* @__PURE__ */ jsx15("label", { className: "ya-href-popover-label", children: "Navigate to page" }),
5978
- /* @__PURE__ */ jsx15("div", { className: "ya-href-popover-pages", children: pages.map((page) => /* @__PURE__ */ jsxs9(
5979
- "button",
5980
- {
5981
- type: "button",
5982
- className: `ya-href-page-btn ${currentHref === page.path ? "is-selected" : ""}`,
5983
- onClick: () => handlePageSelect(page.path),
5984
- children: [
5985
- page.label,
5986
- /* @__PURE__ */ jsx15("span", { className: "ya-href-page-path", children: page.path })
5987
- ]
5988
- },
5989
- page.path
5990
- )) })
5991
- ] }),
5992
- /* @__PURE__ */ jsx15(
5993
- "button",
5994
- {
5995
- type: "button",
5996
- className: "ya-href-external-toggle",
5997
- onClick: () => {
5998
- setIsExternalUrl(true);
5999
- setExternalUrl(currentHref.startsWith("http") ? currentHref : "");
6000
- },
6001
- children: "Use external URL instead"
6002
- }
6003
- )
6004
- ] }) : /* @__PURE__ */ jsxs9(Fragment4, { children: [
6005
- /* @__PURE__ */ jsxs9("div", { className: "ya-href-popover-section", children: [
6006
- /* @__PURE__ */ jsx15("label", { className: "ya-href-popover-label", children: "External URL" }),
6007
- /* @__PURE__ */ jsx15(
6008
- "input",
6009
- {
6010
- type: "url",
6011
- className: "ya-href-url-input",
6012
- placeholder: "https://example.com",
6013
- value: externalUrl,
6014
- onChange: (e) => setExternalUrl(e.target.value),
6015
- autoFocus: true
6016
- }
6017
- )
6018
- ] }),
6019
- /* @__PURE__ */ jsx15("button", { type: "button", className: "ya-href-external-toggle", onClick: () => setIsExternalUrl(false), children: "\u2190 Back to pages" })
6020
- ] }),
6021
- /* @__PURE__ */ jsxs9("div", { className: "ya-href-popover-actions", children: [
6022
- /* @__PURE__ */ jsx15("button", { type: "button", className: "ya-link-btn ya-link-btn-cancel", onClick: handleCancelLink, children: "Cancel" }),
6023
- 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" })
6024
- ] })
6025
- ] })
5998
+ editingMode === "link" && hrefPopoverPos && createPortal6(
5999
+ /* @__PURE__ */ jsxs9(
6000
+ "div",
6001
+ {
6002
+ ref: hrefPopoverRef,
6003
+ className: `ya-href-popover ${hrefPopoverPos.isAbove ? "ya-href-popover--above" : ""}`,
6004
+ style: {
6005
+ top: hrefPopoverPos.isAbove ? "auto" : hrefPopoverPos.top,
6006
+ bottom: hrefPopoverPos.isAbove ? window.innerHeight - hrefPopoverPos.top : "auto",
6007
+ left: hrefPopoverPos.left,
6008
+ transform: "translateX(-50%)"
6009
+ },
6010
+ children: [
6011
+ /* @__PURE__ */ jsx15("div", { className: "ya-href-popover-header", children: "Link destination" }),
6012
+ !isExternalUrl ? /* @__PURE__ */ jsxs9(Fragment4, { children: [
6013
+ sections.length > 0 && /* @__PURE__ */ jsxs9("div", { className: "ya-href-popover-section", children: [
6014
+ /* @__PURE__ */ jsxs9(
6015
+ "button",
6016
+ {
6017
+ type: "button",
6018
+ className: "ya-href-popover-label ya-href-collapsible-header",
6019
+ onClick: () => setSectionsExpanded(!sectionsExpanded),
6020
+ children: [
6021
+ /* @__PURE__ */ jsx15("span", { className: "ya-href-chevron", children: sectionsExpanded ? "\u25BC" : "\u25B6" }),
6022
+ "Scroll to section (",
6023
+ sections.length,
6024
+ ")"
6025
+ ]
6026
+ }
6027
+ ),
6028
+ sectionsExpanded && /* @__PURE__ */ jsx15("div", { className: "ya-href-popover-pages", children: sections.map((section) => /* @__PURE__ */ jsxs9(
6029
+ "button",
6030
+ {
6031
+ type: "button",
6032
+ className: `ya-href-page-btn ${currentHref === section.path ? "is-selected" : ""}`,
6033
+ onClick: () => handlePageSelect(section.path),
6034
+ children: [
6035
+ section.label,
6036
+ /* @__PURE__ */ jsx15("span", { className: "ya-href-page-path", children: section.path })
6037
+ ]
6038
+ },
6039
+ section.path
6040
+ )) })
6041
+ ] }),
6042
+ pages.length > 0 && /* @__PURE__ */ jsxs9("div", { className: "ya-href-popover-section", children: [
6043
+ /* @__PURE__ */ jsx15("label", { className: "ya-href-popover-label", children: "Navigate to page" }),
6044
+ /* @__PURE__ */ jsx15("div", { className: "ya-href-popover-pages", children: pages.map((page) => /* @__PURE__ */ jsxs9(
6045
+ "button",
6046
+ {
6047
+ type: "button",
6048
+ className: `ya-href-page-btn ${currentHref === page.path ? "is-selected" : ""}`,
6049
+ onClick: () => handlePageSelect(page.path),
6050
+ children: [
6051
+ page.label,
6052
+ /* @__PURE__ */ jsx15("span", { className: "ya-href-page-path", children: page.path })
6053
+ ]
6054
+ },
6055
+ page.path
6056
+ )) })
6057
+ ] }),
6058
+ /* @__PURE__ */ jsx15(
6059
+ "button",
6060
+ {
6061
+ type: "button",
6062
+ className: "ya-href-external-toggle",
6063
+ onClick: () => {
6064
+ setIsExternalUrl(true);
6065
+ setExternalUrl(currentHref.startsWith("http") ? currentHref : "");
6066
+ },
6067
+ children: "Use external URL instead"
6068
+ }
6069
+ )
6070
+ ] }) : /* @__PURE__ */ jsxs9(Fragment4, { children: [
6071
+ /* @__PURE__ */ jsxs9("div", { className: "ya-href-popover-section", children: [
6072
+ /* @__PURE__ */ jsx15("label", { className: "ya-href-popover-label", children: "External URL" }),
6073
+ /* @__PURE__ */ jsx15(
6074
+ "input",
6075
+ {
6076
+ type: "url",
6077
+ className: "ya-href-url-input",
6078
+ placeholder: "https://example.com",
6079
+ value: externalUrl,
6080
+ onChange: (e) => setExternalUrl(e.target.value),
6081
+ autoFocus: true
6082
+ }
6083
+ )
6084
+ ] }),
6085
+ /* @__PURE__ */ jsx15("button", { type: "button", className: "ya-href-external-toggle", onClick: () => setIsExternalUrl(false), children: "\u2190 Back to pages" })
6086
+ ] }),
6087
+ /* @__PURE__ */ jsxs9("div", { className: "ya-href-popover-actions", children: [
6088
+ /* @__PURE__ */ jsx15("button", { type: "button", className: "ya-link-btn ya-link-btn-cancel", onClick: handleCancelLink, children: "Cancel" }),
6089
+ 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" })
6090
+ ] })
6091
+ ]
6092
+ }
6093
+ ),
6094
+ document.body
6095
+ )
6026
6096
  ] });
6027
6097
  }
6028
6098
 
@@ -6031,7 +6101,7 @@ import { useCallback as useCallback19, useEffect as useEffect17, useRef as useRe
6031
6101
  import { createPortal as createPortal8 } from "react-dom";
6032
6102
 
6033
6103
  // src/components/Tooltip.tsx
6034
- import { useState as useState16, useRef as useRef17, useEffect as useEffect16, useLayoutEffect as useLayoutEffect3, useCallback as useCallback18 } from "react";
6104
+ import { useState as useState16, useRef as useRef17, useEffect as useEffect16, useLayoutEffect as useLayoutEffect4, useCallback as useCallback18 } from "react";
6035
6105
  import { createPortal as createPortal7 } from "react-dom";
6036
6106
 
6037
6107
  // src/components/tooltip.css
@@ -6147,7 +6217,7 @@ function Tooltip({
6147
6217
  };
6148
6218
  }, []);
6149
6219
  const edgePadding = 12;
6150
- useLayoutEffect3(() => {
6220
+ useLayoutEffect4(() => {
6151
6221
  if (!isVisible || !tooltipRef.current || !tooltipPosition || tooltipPosition.adjusted) {
6152
6222
  return;
6153
6223
  }
package/dist/prod.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { a as ContentStore, E as ContentStoreMode, C as ContentStoreProvider, f as MarkdownText, g as MarkdownTextProps, P as PageInfo, c as StaticImage, d as StaticImageProps, M as StaticText, S as StaticTextProps, c as YaImage, d as YaImageProps, M as YaText, S as YaTextProps, b as background, e as embed, i as image, p as parseEmbedUrl, t as text, u as useContentStore, v as video } from './content-helpers-kWphH5Tn.js';
1
+ export { a as ContentStore, E as ContentStoreMode, C as ContentStoreProvider, f as MarkdownText, g as MarkdownTextProps, P as PageInfo, c as StaticImage, d as StaticImageProps, M as StaticText, S as StaticTextProps, c as YaImage, d as YaImageProps, M as YaText, S as YaTextProps, b as background, e as embed, i as image, p as parseEmbedUrl, t as text, u as useContentStore, v as video } from './content-helpers-DOUKazMz.js';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import React, { CSSProperties, ReactNode } from 'react';
4
4
  export { Link, LinkProps, NavigateFunction, Router, RouterProps, ScrollRestoration, useNavigate } from './router.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yoamigo.com/core",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "Core components, router, and utilities for YoAmigo templates",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",