@haklex/rich-renderer-linkcard 0.0.8 → 0.0.10
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/ConvertToLinkCardAction.d.ts +9 -0
- package/dist/ConvertToLinkCardAction.d.ts.map +1 -0
- package/dist/LinkCardEditDecorator.d.ts.map +1 -1
- package/dist/LinkCardEditNode.d.ts +3 -1
- package/dist/LinkCardEditNode.d.ts.map +1 -1
- package/dist/PasteLinkCardPlugin.d.ts +6 -0
- package/dist/PasteLinkCardPlugin.d.ts.map +1 -0
- package/dist/hooks/useUrlMatcher.d.ts +1 -0
- package/dist/hooks/useUrlMatcher.d.ts.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +133 -16
- package/package.json +6 -4
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PluginRegistry } from './types';
|
|
2
|
+
export interface ConvertToLinkCardActionProps {
|
|
3
|
+
url: string;
|
|
4
|
+
linkKey: string;
|
|
5
|
+
pluginRegistry?: PluginRegistry;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function ConvertToLinkCardAction({ url, linkKey, pluginRegistry, className, }: ConvertToLinkCardActionProps): import("react/jsx-runtime").JSX.Element | null;
|
|
9
|
+
//# sourceMappingURL=ConvertToLinkCardAction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConvertToLinkCardAction.d.ts","sourceRoot":"","sources":["../src/ConvertToLinkCardAction.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C,MAAM,WAAW,4BAA4B;IAC3C,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,uBAAuB,CAAC,EACtC,GAAG,EACH,OAAO,EACP,cAAc,EACd,SAAS,GACV,EAAE,4BAA4B,kDA+B9B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkCardEditDecorator.d.ts","sourceRoot":"","sources":["../src/LinkCardEditDecorator.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"LinkCardEditDecorator.d.ts","sourceRoot":"","sources":["../src/LinkCardEditDecorator.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAM/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAKzC,UAAU,0BAA0B;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,mBAAmB,CAAA;IAC5B,QAAQ,EAAE,YAAY,CAAA;CACvB;AAED,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,OAAO,EACP,QAAQ,GACT,EAAE,0BAA0B,2CAuJ5B"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { LinkCardNode, SerializedLinkCardNode } from '@haklex/rich-editor';
|
|
1
|
+
import { LinkCardNode, LinkCardNodePayload, SerializedLinkCardNode, SlashMenuItemConfig } from '@haklex/rich-editor';
|
|
2
2
|
import { EditorConfig, Klass, LexicalEditor, LexicalNode } from 'lexical';
|
|
3
3
|
import { ReactElement } from 'react';
|
|
4
4
|
export declare class LinkCardEditNode extends LinkCardNode {
|
|
5
|
+
static slashMenuItems: SlashMenuItemConfig[];
|
|
5
6
|
static clone(node: LinkCardEditNode): LinkCardEditNode;
|
|
6
7
|
static importJSON(serializedNode: SerializedLinkCardNode): LinkCardEditNode;
|
|
7
8
|
decorate(_editor: LexicalEditor, _config: EditorConfig): ReactElement;
|
|
8
9
|
}
|
|
10
|
+
export declare function $createLinkCardEditNode(payload: LinkCardNodePayload): LinkCardEditNode;
|
|
9
11
|
export declare const linkCardEditNodes: Array<Klass<LexicalNode>>;
|
|
10
12
|
//# sourceMappingURL=LinkCardEditNode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkCardEditNode.d.ts","sourceRoot":"","sources":["../src/LinkCardEditNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,YAAY,
|
|
1
|
+
{"version":3,"file":"LinkCardEditNode.d.ts","sourceRoot":"","sources":["../src/LinkCardEditNode.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,YAAY,EACZ,KAAK,mBAAmB,EAExB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACzB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAG9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAKzC,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,MAAM,CAAC,cAAc,EAAE,mBAAmB,EAAE,CAa3C;IAED,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,gBAAgB,GAAG,gBAAgB;IAatD,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,sBAAsB,GAAG,gBAAgB;IAU3E,QAAQ,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,YAAY;CAmBtE;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,mBAAmB,GAC3B,gBAAgB,CAElB;AAED,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAsB,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { PluginRegistry } from './types';
|
|
2
|
+
export interface PasteLinkCardPluginProps {
|
|
3
|
+
pluginRegistry?: PluginRegistry;
|
|
4
|
+
}
|
|
5
|
+
export declare function PasteLinkCardPlugin({ pluginRegistry, }: PasteLinkCardPluginProps): null;
|
|
6
|
+
//# sourceMappingURL=PasteLinkCardPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PasteLinkCardPlugin.d.ts","sourceRoot":"","sources":["../src/PasteLinkCardPlugin.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C,MAAM,WAAW,wBAAwB;IACvC,cAAc,CAAC,EAAE,cAAc,CAAA;CAChC;AAED,wBAAgB,mBAAmB,CAAC,EAClC,cAAc,GACf,EAAE,wBAAwB,QAmC1B"}
|
|
@@ -3,5 +3,6 @@ export interface UrlMatchInfo {
|
|
|
3
3
|
plugin: LinkCardPlugin;
|
|
4
4
|
match: UrlMatchResult;
|
|
5
5
|
}
|
|
6
|
+
export declare function matchUrl(url: string, pluginRegistry?: PluginRegistry): UrlMatchInfo | null;
|
|
6
7
|
export declare function useUrlMatcher(url: string | undefined, pluginRegistry?: PluginRegistry): UrlMatchInfo | null;
|
|
7
8
|
//# sourceMappingURL=useUrlMatcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUrlMatcher.d.ts","sourceRoot":"","sources":["../../src/hooks/useUrlMatcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE9E,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAA;IACtB,KAAK,EAAE,cAAc,CAAA;CACtB;AAED,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,cAAc,GAAE,cAA+B,GAC9C,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"useUrlMatcher.d.ts","sourceRoot":"","sources":["../../src/hooks/useUrlMatcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE9E,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,CAAA;IACtB,KAAK,EAAE,cAAc,CAAA;CACtB;AAED,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,EACX,cAAc,GAAE,cAA+B,GAC9C,YAAY,GAAG,IAAI,CAWrB;AAED,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,cAAc,GAAE,cAA+B,GAC9C,YAAY,GAAG,IAAI,CAKrB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
export type { ConvertToLinkCardActionProps } from './ConvertToLinkCardAction';
|
|
2
|
+
export { ConvertToLinkCardAction } from './ConvertToLinkCardAction';
|
|
1
3
|
export type { UrlMatchInfo } from './hooks/useUrlMatcher';
|
|
2
|
-
export { useUrlMatcher } from './hooks/useUrlMatcher';
|
|
4
|
+
export { matchUrl, useUrlMatcher } from './hooks/useUrlMatcher';
|
|
3
5
|
export { LinkCardEditDecorator } from './LinkCardEditDecorator';
|
|
4
|
-
export { LinkCardEditNode, linkCardEditNodes } from './LinkCardEditNode';
|
|
6
|
+
export { $createLinkCardEditNode, LinkCardEditNode, linkCardEditNodes, } from './LinkCardEditNode';
|
|
5
7
|
export type { EnhancedLinkCardProps } from './LinkCardRenderer';
|
|
6
8
|
export { LinkCardRenderer } from './LinkCardRenderer';
|
|
7
9
|
export { LinkCardSkeleton } from './LinkCardSkeleton';
|
|
10
|
+
export type { PasteLinkCardPluginProps } from './PasteLinkCardPlugin';
|
|
11
|
+
export { PasteLinkCardPlugin } from './PasteLinkCardPlugin';
|
|
8
12
|
export { getPluginByName, pluginMap, plugins } from './plugins';
|
|
9
13
|
export { arxivPlugin, bangumiPlugin, githubCommitPlugin, githubDiscussionPlugin, githubIssuePlugin, githubPrPlugin, githubRepoPlugin, leetcodePlugin, mxSpacePlugin, neteaseMusicPlugin, qqMusicPlugin, tmdbPlugin, } from './plugins';
|
|
10
14
|
export { createMxSpacePlugin } from './plugins';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAA;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAA;AACnE,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,YAAY,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAC/D,OAAO,EACL,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,UAAU,GACX,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAC/C,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AACzD,YAAY,EACV,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,cAAc,GACf,MAAM,SAAS,CAAA;AAChB,OAAO,EACL,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,aAAa,EACb,kBAAkB,GACnB,MAAM,SAAS,CAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
2
4
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
5
|
+
import { $createLinkNode, $isLinkNode } from "@lexical/link";
|
|
6
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
7
|
+
import { $getNodeByKey, $createTextNode, $createParagraphNode, $insertNodes, $createNodeSelection, $setSelection, PASTE_COMMAND, $getSelection, $isRangeSelection, $isParagraphNode, COMMAND_PRIORITY_LOW } from "lexical";
|
|
8
|
+
import { Star, Link, ExternalLink, RemoveFormatting, Unlink, CreditCard, Globe } from "lucide-react";
|
|
9
|
+
import { useMemo, useState, useRef, useEffect, useCallback, createElement, useLayoutEffect } from "react";
|
|
4
10
|
import { $isLinkCardNode, LinkCardNode, createRendererDecoration, LinkCardRenderer as LinkCardRenderer$1 } from "@haklex/rich-editor";
|
|
5
11
|
import { Popover, PopoverTrigger, PopoverPanel } from "@haklex/rich-editor-ui";
|
|
6
|
-
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
7
|
-
import { $getNodeByKey } from "lexical";
|
|
8
12
|
import { useInView } from "react-intersection-observer";
|
|
9
13
|
const arxivPlugin = {
|
|
10
14
|
name: "arxiv",
|
|
@@ -1013,18 +1017,21 @@ function getPluginByName(name) {
|
|
|
1013
1017
|
const pluginMap = new Map(
|
|
1014
1018
|
plugins.map((p) => [p.name, p])
|
|
1015
1019
|
);
|
|
1020
|
+
function matchUrl(url, pluginRegistry = plugins) {
|
|
1021
|
+
try {
|
|
1022
|
+
const parsed = new URL(url);
|
|
1023
|
+
for (const plugin of pluginRegistry) {
|
|
1024
|
+
const match = plugin.matchUrl(parsed);
|
|
1025
|
+
if (match) return { plugin, match };
|
|
1026
|
+
}
|
|
1027
|
+
} catch {
|
|
1028
|
+
}
|
|
1029
|
+
return null;
|
|
1030
|
+
}
|
|
1016
1031
|
function useUrlMatcher(url, pluginRegistry = plugins) {
|
|
1017
1032
|
return useMemo(() => {
|
|
1018
1033
|
if (!url) return null;
|
|
1019
|
-
|
|
1020
|
-
const parsed = new URL(url);
|
|
1021
|
-
for (const plugin of pluginRegistry) {
|
|
1022
|
-
const match = plugin.matchUrl(parsed);
|
|
1023
|
-
if (match) return { plugin, match };
|
|
1024
|
-
}
|
|
1025
|
-
} catch {
|
|
1026
|
-
}
|
|
1027
|
-
return null;
|
|
1034
|
+
return matchUrl(url, pluginRegistry);
|
|
1028
1035
|
}, [url, pluginRegistry]);
|
|
1029
1036
|
}
|
|
1030
1037
|
var semanticClassNames = { card: "link-card", cardShortDesc: "link-card--short-desc", cardSkeleton: "link-card--skeleton", cardError: "link-card--error", bg: "link-card__bg", image: "link-card__image", icon: "link-card__icon", content: "link-card__content", title: "link-card__title", titleText: "link-card__title-text", external: "link-card__external", desc: "link-card__desc", desc2: "link-card__desc-2", editWrapper: "rich-link-card-edit-wrapper", editPanel: "rich-link-card-edit-panel", editUrlRow: "rich-link-card-edit-url-row", editLinkIcon: "rich-link-card-edit-link-icon", editInput: "rich-link-card-edit-input", editActions: "rich-link-card-edit-actions", editActionButton: "rich-link-card-edit-action-btn", editActionButtonEnd: "rich-link-card-edit-action-btn--end" };
|
|
@@ -1086,6 +1093,21 @@ function LinkCardEditDecorator({
|
|
|
1086
1093
|
});
|
|
1087
1094
|
setOpen(false);
|
|
1088
1095
|
}, [editor, nodeKey]);
|
|
1096
|
+
const handleConvertToLink = useCallback(() => {
|
|
1097
|
+
editor.update(() => {
|
|
1098
|
+
const node = $getNodeByKey(nodeKey);
|
|
1099
|
+
if (!$isLinkCardNode(node)) return;
|
|
1100
|
+
const nodeUrl = node.getUrl();
|
|
1101
|
+
const { title: title2 } = payload;
|
|
1102
|
+
const linkNode = $createLinkNode(nodeUrl);
|
|
1103
|
+
linkNode.append($createTextNode(title2 || nodeUrl));
|
|
1104
|
+
const paragraph = $createParagraphNode();
|
|
1105
|
+
paragraph.append(linkNode);
|
|
1106
|
+
node.replace(paragraph);
|
|
1107
|
+
paragraph.selectEnd();
|
|
1108
|
+
});
|
|
1109
|
+
setOpen(false);
|
|
1110
|
+
}, [editor, nodeKey, payload]);
|
|
1089
1111
|
const handleKeyDown = useCallback(
|
|
1090
1112
|
(e) => {
|
|
1091
1113
|
if (e.key === "Enter") {
|
|
@@ -1182,6 +1204,18 @@ function LinkCardEditDecorator({
|
|
|
1182
1204
|
]
|
|
1183
1205
|
}
|
|
1184
1206
|
),
|
|
1207
|
+
/* @__PURE__ */ jsxs(
|
|
1208
|
+
"button",
|
|
1209
|
+
{
|
|
1210
|
+
className: `${editActionButton} ${semanticClassNames.editActionButton}`,
|
|
1211
|
+
type: "button",
|
|
1212
|
+
onClick: handleConvertToLink,
|
|
1213
|
+
children: [
|
|
1214
|
+
/* @__PURE__ */ jsx(RemoveFormatting, { size: 14 }),
|
|
1215
|
+
"To Link"
|
|
1216
|
+
]
|
|
1217
|
+
}
|
|
1218
|
+
),
|
|
1185
1219
|
/* @__PURE__ */ jsxs(
|
|
1186
1220
|
"button",
|
|
1187
1221
|
{
|
|
@@ -1204,9 +1238,9 @@ function LinkCardEditDecorator({
|
|
|
1204
1238
|
}
|
|
1205
1239
|
);
|
|
1206
1240
|
}
|
|
1207
|
-
class
|
|
1241
|
+
const _LinkCardEditNode = class _LinkCardEditNode extends LinkCardNode {
|
|
1208
1242
|
static clone(node) {
|
|
1209
|
-
return new
|
|
1243
|
+
return new _LinkCardEditNode(
|
|
1210
1244
|
{
|
|
1211
1245
|
url: node.__url,
|
|
1212
1246
|
title: node.__title,
|
|
@@ -1218,7 +1252,7 @@ class LinkCardEditNode extends LinkCardNode {
|
|
|
1218
1252
|
);
|
|
1219
1253
|
}
|
|
1220
1254
|
static importJSON(serializedNode) {
|
|
1221
|
-
return new
|
|
1255
|
+
return new _LinkCardEditNode({
|
|
1222
1256
|
url: serializedNode.url,
|
|
1223
1257
|
title: serializedNode.title,
|
|
1224
1258
|
description: serializedNode.description,
|
|
@@ -1245,8 +1279,56 @@ class LinkCardEditNode extends LinkCardNode {
|
|
|
1245
1279
|
children: rendererEl
|
|
1246
1280
|
});
|
|
1247
1281
|
}
|
|
1282
|
+
};
|
|
1283
|
+
__publicField(_LinkCardEditNode, "slashMenuItems", [
|
|
1284
|
+
{
|
|
1285
|
+
title: "Link Card",
|
|
1286
|
+
icon: createElement(Link, { size: 20 }),
|
|
1287
|
+
description: "Link preview card",
|
|
1288
|
+
keywords: ["link", "card", "bookmark", "embed"],
|
|
1289
|
+
section: "MEDIA",
|
|
1290
|
+
onSelect: (editor) => {
|
|
1291
|
+
editor.update(() => {
|
|
1292
|
+
$insertNodes([$createLinkCardEditNode({ url: "" })]);
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
]);
|
|
1297
|
+
let LinkCardEditNode = _LinkCardEditNode;
|
|
1298
|
+
function $createLinkCardEditNode(payload) {
|
|
1299
|
+
return new LinkCardEditNode(payload);
|
|
1248
1300
|
}
|
|
1249
1301
|
const linkCardEditNodes = [LinkCardEditNode];
|
|
1302
|
+
function ConvertToLinkCardAction({
|
|
1303
|
+
url,
|
|
1304
|
+
linkKey,
|
|
1305
|
+
pluginRegistry,
|
|
1306
|
+
className
|
|
1307
|
+
}) {
|
|
1308
|
+
const [editor] = useLexicalComposerContext();
|
|
1309
|
+
const info = useMemo(
|
|
1310
|
+
() => matchUrl(url, pluginRegistry),
|
|
1311
|
+
[url, pluginRegistry]
|
|
1312
|
+
);
|
|
1313
|
+
if (!info) return null;
|
|
1314
|
+
const handleConvert = () => {
|
|
1315
|
+
editor.update(() => {
|
|
1316
|
+
const linkNode = $getNodeByKey(linkKey);
|
|
1317
|
+
if (!linkNode || !$isLinkNode(linkNode)) return;
|
|
1318
|
+
const topElement = linkNode.getTopLevelElement();
|
|
1319
|
+
if (!topElement) return;
|
|
1320
|
+
const linkCardNode = $createLinkCardEditNode({ url });
|
|
1321
|
+
topElement.replace(linkCardNode);
|
|
1322
|
+
const nodeSelection = $createNodeSelection();
|
|
1323
|
+
nodeSelection.add(linkCardNode.getKey());
|
|
1324
|
+
$setSelection(nodeSelection);
|
|
1325
|
+
});
|
|
1326
|
+
};
|
|
1327
|
+
return /* @__PURE__ */ jsxs("button", { className, type: "button", onClick: handleConvert, children: [
|
|
1328
|
+
/* @__PURE__ */ jsx(CreditCard, { size: 14 }),
|
|
1329
|
+
"To Card"
|
|
1330
|
+
] });
|
|
1331
|
+
}
|
|
1250
1332
|
function useCardFetcher(options) {
|
|
1251
1333
|
const { source, plugin, id, fallbackUrl, enabled = true, context } = options;
|
|
1252
1334
|
const [loading, setLoading] = useState(true);
|
|
@@ -1513,12 +1595,46 @@ const LinkCardRenderer = (props) => {
|
|
|
1513
1595
|
}
|
|
1514
1596
|
);
|
|
1515
1597
|
};
|
|
1598
|
+
function PasteLinkCardPlugin({
|
|
1599
|
+
pluginRegistry
|
|
1600
|
+
}) {
|
|
1601
|
+
const [editor] = useLexicalComposerContext();
|
|
1602
|
+
useEffect(() => {
|
|
1603
|
+
return editor.registerCommand(
|
|
1604
|
+
PASTE_COMMAND,
|
|
1605
|
+
(event) => {
|
|
1606
|
+
const text = event.clipboardData?.getData("text/plain")?.trim();
|
|
1607
|
+
if (!text) return false;
|
|
1608
|
+
const info = matchUrl(text, pluginRegistry);
|
|
1609
|
+
if (!info) return false;
|
|
1610
|
+
const selection = $getSelection();
|
|
1611
|
+
if (!$isRangeSelection(selection)) return false;
|
|
1612
|
+
const anchorNode = selection.anchor.getNode();
|
|
1613
|
+
const topElement = anchorNode.getTopLevelElement();
|
|
1614
|
+
if (!topElement || !$isParagraphNode(topElement)) return false;
|
|
1615
|
+
const textContent = topElement.getTextContent();
|
|
1616
|
+
if (textContent.trim().length > 0) return false;
|
|
1617
|
+
event.preventDefault();
|
|
1618
|
+
const linkCardNode = $createLinkCardEditNode({
|
|
1619
|
+
url: text
|
|
1620
|
+
});
|
|
1621
|
+
topElement.replace(linkCardNode);
|
|
1622
|
+
return true;
|
|
1623
|
+
},
|
|
1624
|
+
COMMAND_PRIORITY_LOW
|
|
1625
|
+
);
|
|
1626
|
+
}, [editor, pluginRegistry]);
|
|
1627
|
+
return null;
|
|
1628
|
+
}
|
|
1516
1629
|
export {
|
|
1630
|
+
$createLinkCardEditNode,
|
|
1631
|
+
ConvertToLinkCardAction,
|
|
1517
1632
|
LanguageToColorMap,
|
|
1518
1633
|
LinkCardEditDecorator,
|
|
1519
1634
|
LinkCardEditNode,
|
|
1520
1635
|
LinkCardRenderer,
|
|
1521
1636
|
LinkCardSkeleton,
|
|
1637
|
+
PasteLinkCardPlugin,
|
|
1522
1638
|
arxivPlugin,
|
|
1523
1639
|
bangumiPlugin,
|
|
1524
1640
|
camelcaseKeys,
|
|
@@ -1534,6 +1650,7 @@ export {
|
|
|
1534
1650
|
githubRepoPlugin,
|
|
1535
1651
|
leetcodePlugin,
|
|
1536
1652
|
linkCardEditNodes,
|
|
1653
|
+
matchUrl,
|
|
1537
1654
|
mxSpacePlugin,
|
|
1538
1655
|
neteaseMusicPlugin,
|
|
1539
1656
|
pluginMap,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haklex/rich-renderer-linkcard",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"lucide-react": "^0.574.0",
|
|
19
19
|
"react-intersection-observer": "^9.15.1",
|
|
20
|
-
"@haklex/rich-editor": "0.0.
|
|
21
|
-
"@haklex/rich-
|
|
22
|
-
"@haklex/rich-
|
|
20
|
+
"@haklex/rich-editor": "0.0.10",
|
|
21
|
+
"@haklex/rich-editor-ui": "0.0.10",
|
|
22
|
+
"@haklex/rich-style-token": "0.0.10"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
+
"@lexical/link": "^0.40.0",
|
|
25
26
|
"@lexical/react": "^0.40.0",
|
|
26
27
|
"@types/react": "^19.0.0",
|
|
27
28
|
"@types/react-dom": "^19.0.0",
|
|
@@ -35,6 +36,7 @@
|
|
|
35
36
|
"vite-plugin-dts": "^4.5.0"
|
|
36
37
|
},
|
|
37
38
|
"peerDependencies": {
|
|
39
|
+
"@lexical/link": "^0.40.0",
|
|
38
40
|
"@lexical/react": "^0.40.0",
|
|
39
41
|
"lexical": "^0.40.0",
|
|
40
42
|
"react": ">=19",
|