eddyter 1.3.36 → 1.3.38

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/README.md CHANGED
@@ -298,6 +298,8 @@ Provides authentication and configuration context for the editor.
298
298
  - `children`: React nodes to render
299
299
  - `defaultFontFamilies`: Array of font names (optional)
300
300
  - `currentUser`: Current logged-in user for comments (optional) - Object with `id`, `name`, `email`, and optional `avatar`
301
+ - `enableLinkPreview`: Enable automatic link preview on hover (optional, default: `true`)
302
+ - `apiKey`: API key for authentication (optional) - Required only if you need link preview to work immediately without opening the editor first
301
303
 
302
304
  ### ConfigurableEditorWithAuth
303
305
 
@@ -439,6 +441,43 @@ function App() {
439
441
  }
440
442
  ```
441
443
 
444
+ ## Link Preview Feature
445
+
446
+ Eddyter includes automatic link preview on hover. When users hover over links in content wrapped by `EditorProvider`, a preview popup shows the link's title, description, and image.
447
+
448
+ ### How It Works
449
+
450
+ - **Inside the editor**: Link preview works automatically after authentication
451
+ - **Outside the editor** (preview mode, saved content): Link preview works if the user has opened the editor at least once in the session (authentication stores the API key)
452
+
453
+ ### Preview-Only Scenarios
454
+
455
+ If your application displays saved content without ever opening the editor (e.g., a read-only view), you need to pass `apiKey` to `EditorProvider`:
456
+
457
+ ```jsx
458
+ import React from 'react';
459
+ import { EditorProvider } from 'eddyter';
460
+ import 'eddyter/style.css';
461
+
462
+ function ContentPreviewPage({ savedHtml }) {
463
+ return (
464
+ <EditorProvider apiKey="your-api-key">
465
+ <div dangerouslySetInnerHTML={{ __html: savedHtml }} />
466
+ </EditorProvider>
467
+ );
468
+ }
469
+ ```
470
+
471
+ ### Disabling Link Preview
472
+
473
+ To disable link preview entirely:
474
+
475
+ ```jsx
476
+ <EditorProvider enableLinkPreview={false}>
477
+ {/* Your content */}
478
+ </EditorProvider>
479
+ ```
480
+
442
481
  ## License
443
482
 
444
483
  This project is licensed under the MIT License - see the LICENSE file for details.
@@ -18,11 +18,16 @@ interface EditorContextType {
18
18
  verifyKey: (apiKey: string) => Promise<void>;
19
19
  }
20
20
  export declare const useEditor: () => EditorContextType;
21
+ export declare const useEditorOptional: () => EditorContextType | undefined;
21
22
  interface EditorProviderProps {
22
23
  children: React.ReactNode;
23
24
  defaultFontFamilies?: string[];
24
25
  mentionUserList?: string[];
25
26
  currentUser?: CurrentUser;
27
+ /** Enable automatic link preview on hover for all content within provider (default: true) */
28
+ enableLinkPreview?: boolean;
29
+ /** API key for authentication - if provided, will auto-authenticate on mount */
30
+ apiKey?: string;
26
31
  }
27
32
  export declare const EditorProvider: React.FC<EditorProviderProps>;
28
33
  export {};
@@ -3,8 +3,9 @@ type AiStreamType = {
3
3
  onMessage: (message: string) => void;
4
4
  };
5
5
  export declare const AiStream: ({ content, onMessage }: AiStreamType) => Promise<void>;
6
- export declare const AiJsonResponse: ({ content }: {
6
+ export declare const AiJsonResponse: ({ content, apiKey }: {
7
7
  content: string;
8
+ apiKey?: string | undefined;
8
9
  }) => Promise<any>;
9
10
  export declare const AiImageResponse: ({ content }: {
10
11
  content: string;
@@ -2157,21 +2157,11 @@ video {
2157
2157
  background-color: rgb(42 42 42 / var(--tw-bg-opacity, 1));
2158
2158
  }
2159
2159
 
2160
- .cteditor-bg-\[\#2a3a2a\]{
2161
- --tw-bg-opacity: 1;
2162
- background-color: rgb(42 58 42 / var(--tw-bg-opacity, 1));
2163
- }
2164
-
2165
2160
  .cteditor-bg-\[\#2e1a1a\]{
2166
2161
  --tw-bg-opacity: 1;
2167
2162
  background-color: rgb(46 26 26 / var(--tw-bg-opacity, 1));
2168
2163
  }
2169
2164
 
2170
- .cteditor-bg-\[\#3a2a2a\]{
2171
- --tw-bg-opacity: 1;
2172
- background-color: rgb(58 42 42 / var(--tw-bg-opacity, 1));
2173
- }
2174
-
2175
2165
  .cteditor-bg-\[hsl\(var\(--cteditorf47ac10b-popover\)\)\]{
2176
2166
  background-color: hsl(var(--cteditorf47ac10b-popover));
2177
2167
  }
@@ -7142,74 +7132,7 @@ body .EmojiPickerReact{
7142
7132
  min-width: 200px;
7143
7133
  min-height: 150px;
7144
7134
  }
7145
- }.floating-enhance-button {
7146
- position: absolute;
7147
- z-index: 10;
7148
- background: linear-gradient(135deg, #1f2937 0%, #111827 100%);
7149
- border: 1px solid rgba(255, 255, 255, 0.1);
7150
- border-radius: 8px;
7151
- padding: 8px;
7152
- cursor: pointer;
7153
- display: flex;
7154
- align-items: center;
7155
- justify-content: center;
7156
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
7157
- transition: all 0.2s ease;
7158
- opacity: 0;
7159
- pointer-events: auto;
7160
- width: 32px;
7161
- height: 32px;
7162
- }
7163
-
7164
- .floating-enhance-button:hover {
7165
- transform: scale(1.1);
7166
- background: linear-gradient(135deg, #374151 0%, #1f2937 100%);
7167
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
7168
- border-color: rgba(255, 255, 255, 0.2);
7169
- }
7170
-
7171
- .floating-enhance-button:active {
7172
- transform: scale(0.95);
7173
- }
7174
-
7175
- .floating-enhance-button svg {
7176
- width: 16px;
7177
- height: 16px;
7178
- color: #a78bfa;
7179
- }
7180
-
7181
- .floating-enhance-button-tooltip {
7182
- position: absolute;
7183
- bottom: calc(100% + 8px);
7184
- left: 50%;
7185
- transform: translateX(-50%);
7186
- background-color: #1f2937;
7187
- color: white;
7188
- padding: 6px 12px;
7189
- border-radius: 6px;
7190
- font-size: 12px;
7191
- font-weight: 500;
7192
- white-space: nowrap;
7193
- opacity: 0;
7194
- pointer-events: none;
7195
- transition: opacity 0.2s ease;
7196
- }
7197
-
7198
- .floating-enhance-button:hover .floating-enhance-button-tooltip {
7199
- opacity: 1;
7200
- }
7201
-
7202
- /* Arrow for tooltip */
7203
- .floating-enhance-button-tooltip::after {
7204
- content: "";
7205
- position: absolute;
7206
- top: 100%;
7207
- left: 50%;
7208
- transform: translateX(-50%);
7209
- border: 6px solid transparent;
7210
- border-top-color: #1f2937;
7211
- }
7212
- .link-editor {
7135
+ }.link-editor {
7213
7136
  display: flex;
7214
7137
  position: absolute;
7215
7138
  top: 0;
@@ -20,6 +20,18 @@ interface ConfigurableEditorWithAuthProps {
20
20
  onBlur?: () => void;
21
21
  /** Called when editor height changes (React Native bridge) */
22
22
  onHeightChange?: (height: number) => void;
23
+ /**
24
+ * Editor mode:
25
+ * - "edit" (default): Full editor with all editing capabilities
26
+ * - "preview": Read-only preview with interactive features (link preview, etc.)
27
+ */
28
+ mode?: "edit" | "preview";
29
+ /** Additional class name for the preview container (only used in preview mode) */
30
+ previewClassName?: string;
31
+ /** Additional styles for the preview container (only used in preview mode) */
32
+ previewStyle?: React.CSSProperties;
33
+ /** Click handler for preview mode (useful for switching to edit mode) */
34
+ onPreviewClick?: () => void;
23
35
  }
24
36
  declare const ConfigurableEditorWithAuth: React.FC<ConfigurableEditorWithAuthProps>;
25
37
  export default ConfigurableEditorWithAuth;
@@ -0,0 +1,38 @@
1
+ import { default as React } from 'react';
2
+
3
+ /**
4
+ * ContentPreview - A component for displaying saved editor content with all interactive features
5
+ * (like link previews) enabled automatically.
6
+ *
7
+ * This is the recommended way to display content that was created with ConfigurableEditor.
8
+ * When used within EditorProvider, it automatically enables:
9
+ * - Link preview on hover (handled by EditorProvider)
10
+ * - Proper styling
11
+ * - All interactive features
12
+ *
13
+ * Note: Link preview is now automatically handled by EditorProvider.
14
+ * Just wrap your app with EditorProvider and link preview works everywhere!
15
+ *
16
+ * Usage:
17
+ * ```tsx
18
+ * import { ContentPreview, EditorProvider } from "@craxinno/cteditor";
19
+ *
20
+ * <EditorProvider>
21
+ * <ConfigurableEditorWithAuth apiKey={apiKey} ... />
22
+ * {/* Content preview also gets link preview automatically! *\/}
23
+ * <ContentPreview content={savedHtmlContent} />
24
+ * </EditorProvider>
25
+ * ```
26
+ */
27
+ interface ContentPreviewProps {
28
+ /** The HTML content to display (from editor's onChange) */
29
+ content: string;
30
+ /** Additional CSS class names */
31
+ className?: string;
32
+ /** Additional inline styles */
33
+ style?: React.CSSProperties;
34
+ /** Click handler for the content area */
35
+ onClick?: () => void;
36
+ }
37
+ export default function ContentPreview({ content, className, style, onClick, }: ContentPreviewProps): JSX.Element;
38
+ export type { ContentPreviewProps };
@@ -0,0 +1,40 @@
1
+ /// <reference types="react" />
2
+ /**
3
+ * LinkPreviewHover - A standalone component that provides link preview on hover
4
+ * Can be used with any HTML container (not dependent on Lexical editor)
5
+ *
6
+ * Usage:
7
+ * <LinkPreviewHover containerRef={myContainerRef} apiKey={apiKey} />
8
+ *
9
+ * Or wrap content:
10
+ * <LinkPreviewHover apiKey={apiKey}>
11
+ * <div dangerouslySetInnerHTML={{ __html: htmlContent }} />
12
+ * </LinkPreviewHover>
13
+ */
14
+ interface LinkPreviewHoverProps {
15
+ /** Reference to the container element to attach hover listeners */
16
+ containerRef?: React.RefObject<HTMLElement>;
17
+ /** Children to wrap (alternative to containerRef) */
18
+ children?: React.ReactNode;
19
+ /** API key for authentication */
20
+ apiKey?: string;
21
+ /** Delay before showing preview (ms) */
22
+ showDelay?: number;
23
+ /** Delay before hiding preview (ms) */
24
+ hideDelay?: number;
25
+ /** Enable/disable the preview */
26
+ enabled?: boolean;
27
+ }
28
+ export default function LinkPreviewHover({ containerRef, children, apiKey, showDelay, hideDelay, enabled, }: LinkPreviewHoverProps): JSX.Element;
29
+ interface LinkPreviewCardProps {
30
+ url: string;
31
+ rect: DOMRect;
32
+ apiKey?: string;
33
+ onClose: () => void;
34
+ }
35
+ declare function LinkPreviewCard({ url, rect, apiKey, onClose }: LinkPreviewCardProps): import("react/jsx-runtime").JSX.Element;
36
+ declare function TypeIcon({ type }: {
37
+ type: string;
38
+ }): import("react/jsx-runtime").JSX.Element;
39
+ export { LinkPreviewCard, TypeIcon };
40
+ export type { LinkPreviewHoverProps, LinkPreviewCardProps };
@@ -7,7 +7,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
7
7
  declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
8
8
  declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
9
9
  declare const sheetVariants: (props?: ({
10
- side?: "left" | "right" | "bottom" | "top" | null | undefined;
10
+ side?: "top" | "left" | "right" | "bottom" | null | undefined;
11
11
  } & import('class-variance-authority/dist/types').ClassProp) | undefined) => string;
12
12
  interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
13
13
  }
@@ -4,7 +4,7 @@ var __publicField = (obj, key, value) => {
4
4
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
5
  return value;
6
6
  };
7
- import { g as getDefaultExportFromCjs, c as commonjsGlobal } from "./index-455942f2.js";
7
+ import { g as getDefaultExportFromCjs, c as commonjsGlobal } from "./index-0bc350db.js";
8
8
  function _mergeNamespaces(n, m) {
9
9
  for (var i = 0; i < m.length; i++) {
10
10
  const e = m[i];
@@ -46125,4 +46125,4 @@ const html2pdf_bundle$1 = /* @__PURE__ */ _mergeNamespaces({
46125
46125
  export {
46126
46126
  html2pdf_bundle$1 as h
46127
46127
  };
46128
- //# sourceMappingURL=html2pdf.bundle-2195a04c.js.map
46128
+ //# sourceMappingURL=html2pdf.bundle-d21122e4.js.map