@haklex/rich-renderer-linkcard 0.0.65 → 0.0.67
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 +98 -48
- package/dist/ConvertToLinkCardAction.d.ts +2 -2
- package/dist/ConvertToLinkCardAction.d.ts.map +1 -1
- package/dist/LinkCardEditDecorator.d.ts +3 -3
- package/dist/LinkCardEditDecorator.d.ts.map +1 -1
- package/dist/LinkCardEditNode.d.ts +2 -1
- package/dist/LinkCardEditNode.d.ts.map +1 -1
- package/dist/{LinkCardRenderer-Dap643Is.js → LinkCardRenderer-CJB5CmHP.js} +58 -109
- package/dist/LinkCardRenderer.d.ts +4 -4
- package/dist/LinkCardRenderer.d.ts.map +1 -1
- package/dist/hooks/useCardFetcher.d.ts +7 -7
- package/dist/hooks/useCardFetcher.d.ts.map +1 -1
- package/dist/hooks/useUrlMatcher.d.ts +1 -1
- package/dist/hooks/useUrlMatcher.d.ts.map +1 -1
- package/dist/index.mjs +48 -99
- package/dist/plugins/code/leetcode.d.ts.map +1 -1
- package/dist/plugins/github/repo.d.ts.map +1 -1
- package/dist/rich-renderer-linkcard.css +1 -1
- package/dist/static.mjs +1 -1
- package/dist/styles.css.d.ts +0 -6
- package/dist/styles.css.d.ts.map +1 -1
- package/dist/types.d.ts +32 -32
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/package.json +18 -12
package/README.md
CHANGED
|
@@ -1,67 +1,117 @@
|
|
|
1
1
|
# @haklex/rich-renderer-linkcard
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Rich link preview card renderer with metadata display and an extensible plugin system for URL-specific cards.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Includes pre-built plugins for GitHub repos/PRs/issues, ArXiv papers, Bangumi entries, LeetCode problems, TMDB media, NetEase Music, and QQ Music.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
pnpm add @haklex/rich-renderer-linkcard @haklex/rich-editor
|
|
9
|
-
```
|
|
7
|
+
## Installation
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
```ts
|
|
14
|
-
// 渲染器
|
|
15
|
-
export { LinkCardRenderer } from './LinkCardRenderer'
|
|
16
|
-
export { LinkCardEditNode, linkCardEditNodes } from './LinkCardEditNode'
|
|
17
|
-
export { LinkCardSkeleton } from './LinkCardSkeleton'
|
|
18
|
-
|
|
19
|
-
// Hooks
|
|
20
|
-
export { useUrlMatcher } from './hooks/useUrlMatcher'
|
|
21
|
-
|
|
22
|
-
// 插件
|
|
23
|
-
export { plugins, pluginMap, getPluginByName } from './plugins'
|
|
24
|
-
export {
|
|
25
|
-
githubRepoPlugin, githubPrPlugin, githubIssuePlugin,
|
|
26
|
-
githubCommitPlugin, githubDiscussionPlugin,
|
|
27
|
-
arxivPlugin, tmdbPlugin, bangumiPlugin,
|
|
28
|
-
leetcodePlugin, mxSpacePlugin, createMxSpacePlugin,
|
|
29
|
-
neteaseMusicPlugin, qqMusicPlugin
|
|
30
|
-
} from './plugins'
|
|
31
|
-
|
|
32
|
-
// 工具
|
|
33
|
-
export {
|
|
34
|
-
fetchGitHubApi, fetchJsonWithContext,
|
|
35
|
-
camelcaseKeys, generateColor, LanguageToColorMap
|
|
36
|
-
} from './utils'
|
|
37
|
-
|
|
38
|
-
// 类型
|
|
39
|
-
export type {
|
|
40
|
-
LinkCardData, LinkCardPlugin, LinkCardTypeClass,
|
|
41
|
-
LinkCardApiAdapter, LinkCardFetchContext,
|
|
42
|
-
PluginRegistry, UrlMatchResult, UrlMatchInfo,
|
|
43
|
-
EnhancedLinkCardProps, MxSpacePluginConfig
|
|
44
|
-
} from './types'
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @haklex/rich-renderer-linkcard
|
|
45
11
|
```
|
|
46
12
|
|
|
47
|
-
##
|
|
13
|
+
## Peer Dependencies
|
|
48
14
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
15
|
+
| Package | Version |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| `lexical` | `^0.41.0` |
|
|
18
|
+
| `@lexical/react` | `^0.41.0` |
|
|
19
|
+
| `@lexical/link` | `^0.41.0` |
|
|
20
|
+
| `react` | `>=19` |
|
|
21
|
+
| `react-dom` | `>=19` |
|
|
53
22
|
|
|
54
|
-
##
|
|
23
|
+
## Usage
|
|
55
24
|
|
|
56
25
|
```tsx
|
|
57
|
-
import { LinkCardRenderer } from '@haklex/rich-renderer-linkcard'
|
|
58
|
-
import type { RendererConfig } from '@haklex/rich-editor'
|
|
26
|
+
import { LinkCardRenderer } from '@haklex/rich-renderer-linkcard/static'
|
|
59
27
|
|
|
60
|
-
|
|
28
|
+
// Register in a static RendererConfig
|
|
29
|
+
const rendererConfig = {
|
|
30
|
+
// ...other renderers
|
|
61
31
|
LinkCard: LinkCardRenderer,
|
|
62
32
|
}
|
|
63
33
|
```
|
|
64
34
|
|
|
35
|
+
For edit mode with link card conversion and paste support:
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import {
|
|
39
|
+
LinkCardEditNode,
|
|
40
|
+
linkCardEditNodes,
|
|
41
|
+
ConvertToLinkCardAction,
|
|
42
|
+
PasteLinkCardPlugin,
|
|
43
|
+
LinkCardFetchProvider,
|
|
44
|
+
} from '@haklex/rich-renderer-linkcard'
|
|
45
|
+
|
|
46
|
+
// Wrap editor with fetch provider for metadata resolution
|
|
47
|
+
<LinkCardFetchProvider>
|
|
48
|
+
<Editor
|
|
49
|
+
nodes={linkCardEditNodes}
|
|
50
|
+
plugins={[
|
|
51
|
+
<PasteLinkCardPlugin />,
|
|
52
|
+
]}
|
|
53
|
+
/>
|
|
54
|
+
</LinkCardFetchProvider>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Using URL-specific plugins
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { githubRepoPlugin, githubPrPlugin } from '@haklex/rich-renderer-linkcard'
|
|
61
|
+
|
|
62
|
+
// Plugins are auto-registered; use matchUrl to detect supported URLs
|
|
63
|
+
import { matchUrl } from '@haklex/rich-renderer-linkcard'
|
|
64
|
+
const matched = matchUrl('https://github.com/user/repo')
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Exports
|
|
68
|
+
|
|
69
|
+
### Components
|
|
70
|
+
|
|
71
|
+
- `LinkCardRenderer` — Static (read-only) renderer for link preview cards
|
|
72
|
+
- `LinkCardSkeleton` — Loading skeleton placeholder
|
|
73
|
+
|
|
74
|
+
### Nodes and Plugins
|
|
75
|
+
|
|
76
|
+
- `LinkCardEditNode` — Edit node for link cards
|
|
77
|
+
- `linkCardEditNodes` — Array of link card edit nodes for registration
|
|
78
|
+
- `ConvertToLinkCardAction` — Action to convert a link to a link card
|
|
79
|
+
- `PasteLinkCardPlugin` — Editor plugin for paste-to-card conversion
|
|
80
|
+
|
|
81
|
+
### Context
|
|
82
|
+
|
|
83
|
+
- `LinkCardFetchProvider` — Provider for link metadata fetching
|
|
84
|
+
- `useLinkCardFetchContext` — Hook to access fetch context
|
|
85
|
+
|
|
86
|
+
### Plugin Registry
|
|
87
|
+
|
|
88
|
+
- `getPluginByName` — Retrieve a plugin by name
|
|
89
|
+
- `pluginMap` — Map of all registered plugins
|
|
90
|
+
- `plugins` — Array of all registered plugins
|
|
91
|
+
|
|
92
|
+
### Pre-built Plugins
|
|
93
|
+
|
|
94
|
+
- `githubRepoPlugin` — GitHub repository cards
|
|
95
|
+
- `githubPrPlugin` — GitHub PR/issue cards
|
|
96
|
+
- ArXiv, Bangumi, LeetCode, TMDB, NetEase Music, QQ Music plugins
|
|
97
|
+
|
|
98
|
+
### URL Matching
|
|
99
|
+
|
|
100
|
+
- `useUrlMatcher` — Hook for matching URLs to plugins
|
|
101
|
+
- `matchUrl` — Utility to match a URL against registered plugins
|
|
102
|
+
|
|
103
|
+
### Sub-path Exports
|
|
104
|
+
|
|
105
|
+
| Path | Description |
|
|
106
|
+
| --- | --- |
|
|
107
|
+
| `@haklex/rich-renderer-linkcard` | Full exports (edit + static + plugins) |
|
|
108
|
+
| `@haklex/rich-renderer-linkcard/static` | Static-only renderer |
|
|
109
|
+
| `@haklex/rich-renderer-linkcard/style.css` | Stylesheet |
|
|
110
|
+
|
|
111
|
+
## Part of Haklex
|
|
112
|
+
|
|
113
|
+
This package is part of the [Haklex](../../README.md) rich editor ecosystem.
|
|
114
|
+
|
|
65
115
|
## License
|
|
66
116
|
|
|
67
117
|
MIT
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { PluginRegistry } from './types';
|
|
2
2
|
export interface ConvertToLinkCardActionProps {
|
|
3
|
-
|
|
3
|
+
className?: string;
|
|
4
4
|
linkKey: string;
|
|
5
5
|
pluginRegistry?: PluginRegistry;
|
|
6
|
-
|
|
6
|
+
url: string;
|
|
7
7
|
}
|
|
8
8
|
export declare function ConvertToLinkCardAction({ url, linkKey, pluginRegistry, className, }: ConvertToLinkCardActionProps): import("react/jsx-runtime").JSX.Element | null;
|
|
9
9
|
//# sourceMappingURL=ConvertToLinkCardAction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConvertToLinkCardAction.d.ts","sourceRoot":"","sources":["../src/ConvertToLinkCardAction.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"ConvertToLinkCardAction.d.ts","sourceRoot":"","sources":["../src/ConvertToLinkCardAction.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,WAAW,4BAA4B;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,uBAAuB,CAAC,EACtC,GAAG,EACH,OAAO,EACP,cAAc,EACd,SAAS,GACV,EAAE,4BAA4B,kDA4B9B"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { LinkCardNodePayload } from '@haklex/rich-editor';
|
|
1
|
+
import { LinkCardNodePayload } from '@haklex/rich-editor/nodes';
|
|
2
2
|
import { ReactElement } from 'react';
|
|
3
3
|
interface LinkCardEditDecoratorProps {
|
|
4
|
+
children: ReactElement;
|
|
4
5
|
nodeKey: string;
|
|
5
6
|
payload: LinkCardNodePayload;
|
|
6
|
-
children: ReactElement;
|
|
7
7
|
}
|
|
8
|
-
export declare function LinkCardEditDecorator({ nodeKey, payload, children
|
|
8
|
+
export declare function LinkCardEditDecorator({ nodeKey, payload, children }: LinkCardEditDecoratorProps): import("react/jsx-runtime").JSX.Element;
|
|
9
9
|
export {};
|
|
10
10
|
//# sourceMappingURL=LinkCardEditDecorator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkCardEditDecorator.d.ts","sourceRoot":"","sources":["../src/LinkCardEditDecorator.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"LinkCardEditDecorator.d.ts","sourceRoot":"","sources":["../src/LinkCardEditDecorator.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAYtF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAK1C,UAAU,0BAA0B;IAClC,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,wBAAgB,qBAAqB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,0BAA0B,2CA0I/F"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { CommandItemConfig
|
|
1
|
+
import { CommandItemConfig } from '@haklex/rich-editor/commands';
|
|
2
|
+
import { LinkCardNode, LinkCardNodePayload, SerializedLinkCardNode } from '@haklex/rich-editor/nodes';
|
|
2
3
|
import { EditorConfig, Klass, LexicalEditor, LexicalNode } from 'lexical';
|
|
3
4
|
import { ReactElement } from 'react';
|
|
4
5
|
export declare class LinkCardEditNode extends LinkCardNode {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkCardEditNode.d.ts","sourceRoot":"","sources":["../src/LinkCardEditNode.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"LinkCardEditNode.d.ts","sourceRoot":"","sources":["../src/LinkCardEditNode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EACL,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC5B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG/E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAK1C,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,MAAM,CAAC,YAAY,EAAE,iBAAiB,EAAE,CAatC;IAEF,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;CAetE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,mBAAmB,GAAG,gBAAgB,CAEtF;AAED,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAsB,CAAC"}
|
|
@@ -79,47 +79,43 @@ async function fetchJsonWithContext(url, context, provider, init) {
|
|
|
79
79
|
}
|
|
80
80
|
async function fetchGitHubApi(url, context) {
|
|
81
81
|
const path = url.replace("https://api.github.com", "");
|
|
82
|
-
return fetchJsonWithContext(
|
|
83
|
-
`https://api.github.com${path}`,
|
|
84
|
-
context,
|
|
85
|
-
"github"
|
|
86
|
-
);
|
|
82
|
+
return fetchJsonWithContext(`https://api.github.com${path}`, context, "github");
|
|
87
83
|
}
|
|
88
84
|
const LanguageToColorMap = {
|
|
89
|
-
typescript: "#2b7489",
|
|
90
|
-
javascript: "#f1e05a",
|
|
91
|
-
html: "#e34c26",
|
|
92
|
-
java: "#b07219",
|
|
93
|
-
go: "#00add8",
|
|
94
|
-
vue: "#2c3e50",
|
|
95
|
-
css: "#563d7c",
|
|
96
|
-
yaml: "#cb171e",
|
|
97
|
-
json: "#292929",
|
|
98
|
-
markdown: "#083fa1",
|
|
99
|
-
csharp: "#178600",
|
|
85
|
+
"typescript": "#2b7489",
|
|
86
|
+
"javascript": "#f1e05a",
|
|
87
|
+
"html": "#e34c26",
|
|
88
|
+
"java": "#b07219",
|
|
89
|
+
"go": "#00add8",
|
|
90
|
+
"vue": "#2c3e50",
|
|
91
|
+
"css": "#563d7c",
|
|
92
|
+
"yaml": "#cb171e",
|
|
93
|
+
"json": "#292929",
|
|
94
|
+
"markdown": "#083fa1",
|
|
95
|
+
"csharp": "#178600",
|
|
100
96
|
"c#": "#178600",
|
|
101
|
-
c: "#555555",
|
|
102
|
-
cpp: "#f34b7d",
|
|
97
|
+
"c": "#555555",
|
|
98
|
+
"cpp": "#f34b7d",
|
|
103
99
|
"c++": "#f34b7d",
|
|
104
|
-
python: "#3572a5",
|
|
105
|
-
lua: "#000080",
|
|
106
|
-
vimscript: "#199f4b",
|
|
107
|
-
shell: "#89e051",
|
|
108
|
-
dockerfile: "#384d54",
|
|
109
|
-
ruby: "#701516",
|
|
110
|
-
php: "#4f5d95",
|
|
111
|
-
lisp: "#3fb68b",
|
|
112
|
-
kotlin: "#F18E33",
|
|
113
|
-
rust: "#dea584",
|
|
114
|
-
dart: "#00B4AB",
|
|
115
|
-
swift: "#ffac45",
|
|
100
|
+
"python": "#3572a5",
|
|
101
|
+
"lua": "#000080",
|
|
102
|
+
"vimscript": "#199f4b",
|
|
103
|
+
"shell": "#89e051",
|
|
104
|
+
"dockerfile": "#384d54",
|
|
105
|
+
"ruby": "#701516",
|
|
106
|
+
"php": "#4f5d95",
|
|
107
|
+
"lisp": "#3fb68b",
|
|
108
|
+
"kotlin": "#F18E33",
|
|
109
|
+
"rust": "#dea584",
|
|
110
|
+
"dart": "#00B4AB",
|
|
111
|
+
"swift": "#ffac45",
|
|
116
112
|
"objective-c": "#438eff",
|
|
117
113
|
"objective-c++": "#6866fb",
|
|
118
|
-
r: "#198ce7",
|
|
119
|
-
matlab: "#e16737",
|
|
120
|
-
scala: "#c22d40",
|
|
121
|
-
sql: "#e38c00",
|
|
122
|
-
perl: "#0298c3"
|
|
114
|
+
"r": "#198ce7",
|
|
115
|
+
"matlab": "#e16737",
|
|
116
|
+
"scala": "#c22d40",
|
|
117
|
+
"sql": "#e38c00",
|
|
118
|
+
"perl": "#0298c3"
|
|
123
119
|
};
|
|
124
120
|
const bangumiTypeMap = {
|
|
125
121
|
subject: "subjects",
|
|
@@ -151,18 +147,22 @@ function generateColor(str, saturation = [30, 35], lightness = [60, 70]) {
|
|
|
151
147
|
return hslToHex(h, s, l);
|
|
152
148
|
}
|
|
153
149
|
function stripMarkdown(text) {
|
|
154
|
-
return text.replaceAll(/!\[
|
|
150
|
+
return text.replaceAll(/!\[[^\]]*\]\([^)]*\)/g, "").replaceAll(/\[([^\]]*)\]\([^)]*\)/g, "$1").replaceAll(/[#*>_`~]/g, "").replaceAll(/\n+/g, " ").trim();
|
|
155
151
|
}
|
|
156
152
|
function getDifficultyColor(difficulty) {
|
|
157
153
|
switch (difficulty) {
|
|
158
|
-
case "Easy":
|
|
154
|
+
case "Easy": {
|
|
159
155
|
return "#00BFA5";
|
|
160
|
-
|
|
156
|
+
}
|
|
157
|
+
case "Medium": {
|
|
161
158
|
return "#FFA726";
|
|
162
|
-
|
|
159
|
+
}
|
|
160
|
+
case "Hard": {
|
|
163
161
|
return "#F44336";
|
|
164
|
-
|
|
162
|
+
}
|
|
163
|
+
default: {
|
|
165
164
|
return "#757575";
|
|
165
|
+
}
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
const leetcodePlugin = {
|
|
@@ -172,8 +172,7 @@ const leetcodePlugin = {
|
|
|
172
172
|
typeClass: "wide",
|
|
173
173
|
provider: "leetcode",
|
|
174
174
|
matchUrl(url) {
|
|
175
|
-
if (url.hostname !== "leetcode.cn" && url.hostname !== "leetcode.com")
|
|
176
|
-
return null;
|
|
175
|
+
if (url.hostname !== "leetcode.cn" && url.hostname !== "leetcode.com") return null;
|
|
177
176
|
const parts = url.pathname.split("/").filter(Boolean);
|
|
178
177
|
if (parts[0] !== "problems" || !parts[1]) return null;
|
|
179
178
|
return { id: parts[1], fullUrl: url.toString() };
|
|
@@ -574,10 +573,7 @@ const githubRepoPlugin = {
|
|
|
574
573
|
},
|
|
575
574
|
async fetch(id, _meta, context) {
|
|
576
575
|
const [owner, repo] = id.split("/");
|
|
577
|
-
const response = await fetchGitHubApi(
|
|
578
|
-
`https://api.github.com/repos/${owner}/${repo}`,
|
|
579
|
-
context
|
|
580
|
-
);
|
|
576
|
+
const response = await fetchGitHubApi(`https://api.github.com/repos/${owner}/${repo}`, context);
|
|
581
577
|
const data = camelcaseKeys(response);
|
|
582
578
|
return {
|
|
583
579
|
title: /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
@@ -593,7 +589,7 @@ const githubRepoPlugin = {
|
|
|
593
589
|
color: "#fb923c"
|
|
594
590
|
},
|
|
595
591
|
children: [
|
|
596
|
-
/* @__PURE__ */ jsx(Star, { size: 14, strokeWidth: 2
|
|
592
|
+
/* @__PURE__ */ jsx(Star, { "aria-hidden": true, size: 14, strokeWidth: 2 }),
|
|
597
593
|
/* @__PURE__ */ jsx("span", { style: { fontFamily: "sans-serif", fontWeight: 500 }, children: formatStargazers(data.stargazersCount) })
|
|
598
594
|
]
|
|
599
595
|
}
|
|
@@ -1027,7 +1023,7 @@ function useUrlMatcher(url, pluginRegistry = plugins) {
|
|
|
1027
1023
|
return matchUrl(url, pluginRegistry);
|
|
1028
1024
|
}, [url, pluginRegistry]);
|
|
1029
1025
|
}
|
|
1030
|
-
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", 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"
|
|
1026
|
+
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", 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" };
|
|
1031
1027
|
var card = "_13weebv0";
|
|
1032
1028
|
var cardShortDesc = "_13weebv1";
|
|
1033
1029
|
var bg = "_13weebv2";
|
|
@@ -1045,9 +1041,6 @@ var editPanel = "_13weebvk";
|
|
|
1045
1041
|
var editUrlRow = "_13weebvl";
|
|
1046
1042
|
var editLinkIcon = "_13weebvm";
|
|
1047
1043
|
var editInput = "_13weebvn";
|
|
1048
|
-
var editActions = "_13weebvo";
|
|
1049
|
-
var editActionButton = "_13weebvp";
|
|
1050
|
-
var editActionButtonEnd = "_13weebvq";
|
|
1051
1044
|
var typeCardModifier = { media: "_13weebvd", github: "_13weebve", academic: "_13weebvf", wide: "_13weebvc" };
|
|
1052
1045
|
var semanticTypeClassNames = { media: "link-card--media", github: "link-card--github", academic: "link-card--academic", wide: "link-card--wide" };
|
|
1053
1046
|
var semanticClassToStyle = { "link-card--short-desc": "_13weebv1", "link-card--skeleton": "_13weebvg", "link-card--error": "_13weebvi", "link-card--poster": "_13weebvb", "link-card--wide": "_13weebvc", "link-card--media": "_13weebvd", "link-card--github": "_13weebve", "link-card--academic": "_13weebvf", "link-card__image--poster": "_13weebv4" };
|
|
@@ -1074,10 +1067,7 @@ function useCardFetcher(options) {
|
|
|
1074
1067
|
const data = await plugin.fetch(id, void 0, context);
|
|
1075
1068
|
setCardInfo(data);
|
|
1076
1069
|
} catch (err) {
|
|
1077
|
-
console.error(
|
|
1078
|
-
`[LinkCard] Error fetching ${source || plugin.name} data:`,
|
|
1079
|
-
err
|
|
1080
|
-
);
|
|
1070
|
+
console.error(`[LinkCard] Error fetching ${source || plugin.name} data:`, err);
|
|
1081
1071
|
setIsError(true);
|
|
1082
1072
|
} finally {
|
|
1083
1073
|
setLoading(false);
|
|
@@ -1150,7 +1140,7 @@ function LinkCardSkeleton({
|
|
|
1150
1140
|
}
|
|
1151
1141
|
function FallbackIcon({ favicon }) {
|
|
1152
1142
|
const [faviconFailed, setFaviconFailed] = useState(false);
|
|
1153
|
-
return /* @__PURE__ */ jsx("span", { className: `${icon} ${semanticClassNames.icon}`, children: favicon && !faviconFailed ? /* @__PURE__ */ jsx("img", {
|
|
1143
|
+
return /* @__PURE__ */ jsx("span", { className: `${icon} ${semanticClassNames.icon}`, children: favicon && !faviconFailed ? /* @__PURE__ */ jsx("img", { alt: "", src: favicon, onError: () => setFaviconFailed(true) }) : /* @__PURE__ */ jsx(Globe, { "aria-hidden": "true" }) });
|
|
1154
1144
|
}
|
|
1155
1145
|
function mapSemanticClasses(classNames) {
|
|
1156
1146
|
if (!classNames) return "";
|
|
@@ -1179,18 +1169,13 @@ const LinkCardRenderer = (props) => {
|
|
|
1179
1169
|
for (const plugin of extraPlugins) {
|
|
1180
1170
|
map.set(plugin.name, plugin);
|
|
1181
1171
|
}
|
|
1182
|
-
return [...map.values()].sort(
|
|
1183
|
-
(a, b) => (b.priority ?? 0) - (a.priority ?? 0)
|
|
1184
|
-
);
|
|
1172
|
+
return [...map.values()].sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
1185
1173
|
}, [extraPlugins]);
|
|
1186
1174
|
const pluginMap2 = useMemo(
|
|
1187
1175
|
() => new Map(mergedPlugins.map((plugin) => [plugin.name, plugin])),
|
|
1188
1176
|
[mergedPlugins]
|
|
1189
1177
|
);
|
|
1190
|
-
const urlMatch = useUrlMatcher(
|
|
1191
|
-
!explicitSource || !explicitId ? url : void 0,
|
|
1192
|
-
mergedPlugins
|
|
1193
|
-
);
|
|
1178
|
+
const urlMatch = useUrlMatcher(!explicitSource || !explicitId ? url : void 0, mergedPlugins);
|
|
1194
1179
|
const source = explicitSource || urlMatch?.plugin.name;
|
|
1195
1180
|
const id = explicitId || urlMatch?.match.id;
|
|
1196
1181
|
const matchedFullUrl = urlMatch?.match.fullUrl;
|
|
@@ -1232,17 +1217,7 @@ const LinkCardRenderer = (props) => {
|
|
|
1232
1217
|
return null;
|
|
1233
1218
|
}
|
|
1234
1219
|
if (useDynamicFetch && loading) {
|
|
1235
|
-
return /* @__PURE__ */ jsx(
|
|
1236
|
-
"a",
|
|
1237
|
-
{
|
|
1238
|
-
"data-hide-print": true,
|
|
1239
|
-
ref,
|
|
1240
|
-
href: fullUrl,
|
|
1241
|
-
target: "_blank",
|
|
1242
|
-
rel: "noopener noreferrer",
|
|
1243
|
-
children: /* @__PURE__ */ jsx(LinkCardSkeleton, { source })
|
|
1244
|
-
}
|
|
1245
|
-
);
|
|
1220
|
+
return /* @__PURE__ */ jsx("a", { "data-hide-print": true, href: fullUrl, ref, rel: "noopener noreferrer", target: "_blank", children: /* @__PURE__ */ jsx(LinkCardSkeleton, { source }) });
|
|
1246
1221
|
}
|
|
1247
1222
|
const hasImage = !!finalImage;
|
|
1248
1223
|
const showImagePlaceholder = isErrorState && !hasImage;
|
|
@@ -1251,7 +1226,11 @@ const LinkCardRenderer = (props) => {
|
|
|
1251
1226
|
"a",
|
|
1252
1227
|
{
|
|
1253
1228
|
"data-hide-print": true,
|
|
1229
|
+
"data-source": source || void 0,
|
|
1230
|
+
href: useDynamicFetch ? fullUrl : url,
|
|
1254
1231
|
ref: useDynamicFetch ? ref : void 0,
|
|
1232
|
+
rel: "noopener noreferrer",
|
|
1233
|
+
target: "_blank",
|
|
1255
1234
|
className: [
|
|
1256
1235
|
card,
|
|
1257
1236
|
semanticClassNames.card,
|
|
@@ -1267,10 +1246,6 @@ const LinkCardRenderer = (props) => {
|
|
|
1267
1246
|
className,
|
|
1268
1247
|
mappedCardRootClass
|
|
1269
1248
|
].filter(Boolean).join(" "),
|
|
1270
|
-
"data-source": source || void 0,
|
|
1271
|
-
href: useDynamicFetch ? fullUrl : url,
|
|
1272
|
-
target: "_blank",
|
|
1273
|
-
rel: "noopener noreferrer",
|
|
1274
1249
|
style: {
|
|
1275
1250
|
borderColor: finalColor ? `${finalColor}30` : void 0
|
|
1276
1251
|
},
|
|
@@ -1288,40 +1263,17 @@ const LinkCardRenderer = (props) => {
|
|
|
1288
1263
|
hasImage || showImagePlaceholder ? /* @__PURE__ */ jsx(
|
|
1289
1264
|
"span",
|
|
1290
1265
|
{
|
|
1291
|
-
className: [
|
|
1292
|
-
image,
|
|
1293
|
-
semanticClassNames.image,
|
|
1294
|
-
mappedImageClass
|
|
1295
|
-
].filter(Boolean).join(" "),
|
|
1296
1266
|
"data-image": finalImage || "",
|
|
1267
|
+
className: [image, semanticClassNames.image, mappedImageClass].filter(Boolean).join(" "),
|
|
1297
1268
|
style: {
|
|
1298
1269
|
backgroundImage: finalImage ? `url(${finalImage})` : void 0
|
|
1299
1270
|
}
|
|
1300
1271
|
}
|
|
1301
1272
|
) : /* @__PURE__ */ jsx(FallbackIcon, { favicon }),
|
|
1302
|
-
/* @__PURE__ */ jsxs(
|
|
1303
|
-
"span",
|
|
1304
|
-
{
|
|
1305
|
-
|
|
1306
|
-
children: [
|
|
1307
|
-
/* @__PURE__ */ jsx("span", { className: `${title} ${semanticClassNames.title}`, children: /* @__PURE__ */ jsx(
|
|
1308
|
-
"span",
|
|
1309
|
-
{
|
|
1310
|
-
className: `${titleText} ${semanticClassNames.titleText}`,
|
|
1311
|
-
children: finalTitle
|
|
1312
|
-
}
|
|
1313
|
-
) }),
|
|
1314
|
-
finalDesc && /* @__PURE__ */ jsx(
|
|
1315
|
-
"span",
|
|
1316
|
-
{
|
|
1317
|
-
ref: descRef,
|
|
1318
|
-
className: `${desc} ${semanticClassNames.desc}`,
|
|
1319
|
-
children: finalDesc
|
|
1320
|
-
}
|
|
1321
|
-
)
|
|
1322
|
-
]
|
|
1323
|
-
}
|
|
1324
|
-
)
|
|
1273
|
+
/* @__PURE__ */ jsxs("span", { className: `${content} ${semanticClassNames.content}`, children: [
|
|
1274
|
+
/* @__PURE__ */ jsx("span", { className: `${title} ${semanticClassNames.title}`, children: /* @__PURE__ */ jsx("span", { className: `${titleText} ${semanticClassNames.titleText}`, children: finalTitle }) }),
|
|
1275
|
+
finalDesc && /* @__PURE__ */ jsx("span", { className: `${desc} ${semanticClassNames.desc}`, ref: descRef, children: finalDesc })
|
|
1276
|
+
] })
|
|
1325
1277
|
]
|
|
1326
1278
|
}
|
|
1327
1279
|
);
|
|
@@ -1332,9 +1284,6 @@ export {
|
|
|
1332
1284
|
editUrlRow as C,
|
|
1333
1285
|
editLinkIcon as D,
|
|
1334
1286
|
editInput as E,
|
|
1335
|
-
editActions as F,
|
|
1336
|
-
editActionButton as G,
|
|
1337
|
-
editActionButtonEnd as H,
|
|
1338
1287
|
LanguageToColorMap as L,
|
|
1339
1288
|
LinkCardFetchProvider as a,
|
|
1340
1289
|
LinkCardRenderer as b,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { LinkCardRendererProps } from '@haklex/rich-editor';
|
|
1
|
+
import { LinkCardRendererProps } from '@haklex/rich-editor/renderers';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
3
|
import { LinkCardFetchContext, PluginRegistry } from './types';
|
|
4
4
|
export interface EnhancedLinkCardProps extends LinkCardRendererProps {
|
|
5
|
-
source?: string;
|
|
6
|
-
id?: string;
|
|
7
5
|
className?: string;
|
|
6
|
+
fetchContext?: LinkCardFetchContext;
|
|
7
|
+
id?: string;
|
|
8
8
|
/**
|
|
9
9
|
* 额外插件,与内置插件合并(同名覆盖内置,按 priority 排序)
|
|
10
10
|
*/
|
|
11
11
|
plugins?: PluginRegistry;
|
|
12
|
-
|
|
12
|
+
source?: string;
|
|
13
13
|
}
|
|
14
14
|
export declare const LinkCardRenderer: ComponentType<EnhancedLinkCardProps>;
|
|
15
15
|
//# sourceMappingURL=LinkCardRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkCardRenderer.d.ts","sourceRoot":"","sources":["../src/LinkCardRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"LinkCardRenderer.d.ts","sourceRoot":"","sources":["../src/LinkCardRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAE3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAS3C,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEpE,MAAM,WAAW,qBAAsB,SAAQ,qBAAqB;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA2BD,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAAC,qBAAqB,CA4JjE,CAAC"}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { LinkCardData, LinkCardFetchContext, LinkCardPlugin } from '../types';
|
|
2
2
|
export interface UseCardFetcherOptions {
|
|
3
|
-
source?: string;
|
|
4
|
-
plugin?: LinkCardPlugin;
|
|
5
|
-
id: string;
|
|
6
|
-
fallbackUrl?: string;
|
|
7
|
-
enabled?: boolean;
|
|
8
3
|
context?: LinkCardFetchContext;
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
fallbackUrl?: string;
|
|
6
|
+
id: string;
|
|
7
|
+
plugin?: LinkCardPlugin;
|
|
8
|
+
source?: string;
|
|
9
9
|
}
|
|
10
10
|
export interface UseCardFetcherResult {
|
|
11
|
-
loading: boolean;
|
|
12
|
-
isError: boolean;
|
|
13
11
|
cardInfo: LinkCardData | undefined;
|
|
14
12
|
fullUrl: string;
|
|
13
|
+
isError: boolean;
|
|
15
14
|
isValid: boolean;
|
|
15
|
+
loading: boolean;
|
|
16
16
|
ref: (node?: Element | null) => void;
|
|
17
17
|
}
|
|
18
18
|
export declare function useCardFetcher(options: UseCardFetcherOptions): UseCardFetcherResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCardFetcher.d.ts","sourceRoot":"","sources":["../../src/hooks/useCardFetcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"useCardFetcher.d.ts","sourceRoot":"","sources":["../../src/hooks/useCardFetcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEnF,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,YAAY,GAAG,SAAS,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;CACtC;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,oBAAoB,CA8CnF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { LinkCardPlugin, PluginRegistry, UrlMatchResult } from '../types';
|
|
2
2
|
export interface UrlMatchInfo {
|
|
3
|
-
plugin: LinkCardPlugin;
|
|
4
3
|
match: UrlMatchResult;
|
|
4
|
+
plugin: LinkCardPlugin;
|
|
5
5
|
}
|
|
6
6
|
export declare function matchUrl(url: string, pluginRegistry?: PluginRegistry): UrlMatchInfo | null;
|
|
7
7
|
export declare function useUrlMatcher(url: string | undefined, pluginRegistry?: PluginRegistry): UrlMatchInfo | null;
|
|
@@ -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,
|
|
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,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;CACxB;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.mjs
CHANGED
|
@@ -7,15 +7,12 @@ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext
|
|
|
7
7
|
import { $getNodeByKey, $createTextNode, $createParagraphNode, $insertNodes, $createNodeSelection, $setSelection, PASTE_COMMAND, $getSelection, $isRangeSelection, $isParagraphNode, COMMAND_PRIORITY_LOW } from "lexical";
|
|
8
8
|
import { Link, ExternalLink, RemoveFormatting, Unlink, CreditCard } from "lucide-react";
|
|
9
9
|
import { useState, useRef, useEffect, useCallback, createElement, useMemo } from "react";
|
|
10
|
-
import { z as editWrapper, A as semanticClassNames, B as editPanel, C as editUrlRow, D as editLinkIcon, E as editInput,
|
|
11
|
-
import { L, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, s, t, u, v, w, x, y } from "./LinkCardRenderer-
|
|
12
|
-
import { $isLinkCardNode, LinkCardNode
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
payload,
|
|
17
|
-
children
|
|
18
|
-
}) {
|
|
10
|
+
import { z as editWrapper, A as semanticClassNames, B as editPanel, C as editUrlRow, D as editLinkIcon, E as editInput, r as matchUrl } from "./LinkCardRenderer-CJB5CmHP.js";
|
|
11
|
+
import { L, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, s, t, u, v, w, x, y } from "./LinkCardRenderer-CJB5CmHP.js";
|
|
12
|
+
import { $isLinkCardNode, LinkCardNode } from "@haklex/rich-editor/nodes";
|
|
13
|
+
import { createRendererDecoration, LinkCardRenderer } from "@haklex/rich-editor/renderers";
|
|
14
|
+
import { Popover, PopoverTrigger, PopoverPanel, ActionBar, ActionButton } from "@haklex/rich-editor-ui";
|
|
15
|
+
function LinkCardEditDecorator({ nodeKey, payload, children }) {
|
|
19
16
|
const [editor] = useLexicalComposerContext();
|
|
20
17
|
const editable = editor.isEditable();
|
|
21
18
|
const [open, setOpen] = useState(() => !payload.url);
|
|
@@ -96,98 +93,57 @@ function LinkCardEditDecorator({
|
|
|
96
93
|
/* @__PURE__ */ jsx(
|
|
97
94
|
PopoverTrigger,
|
|
98
95
|
{
|
|
99
|
-
delay: 200,
|
|
100
|
-
closeDelay: 300,
|
|
101
96
|
openOnHover: true,
|
|
97
|
+
closeDelay: 300,
|
|
98
|
+
delay: 200,
|
|
102
99
|
nativeButton: false,
|
|
103
|
-
render: /* @__PURE__ */ jsx(
|
|
104
|
-
"span",
|
|
105
|
-
{
|
|
106
|
-
className: `${editWrapper} ${semanticClassNames.editWrapper}`
|
|
107
|
-
}
|
|
108
|
-
),
|
|
100
|
+
render: /* @__PURE__ */ jsx("span", { className: `${editWrapper} ${semanticClassNames.editWrapper}` }),
|
|
109
101
|
children
|
|
110
102
|
}
|
|
111
103
|
),
|
|
112
104
|
/* @__PURE__ */ jsxs(
|
|
113
105
|
PopoverPanel,
|
|
114
106
|
{
|
|
107
|
+
className: `${editPanel} ${semanticClassNames.editPanel}`,
|
|
115
108
|
side: "bottom",
|
|
116
109
|
sideOffset: 8,
|
|
117
|
-
className: `${editPanel} ${semanticClassNames.editPanel}`,
|
|
118
110
|
children: [
|
|
119
|
-
/* @__PURE__ */ jsxs(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
className: `${editActionButton} ${semanticClassNames.editActionButton}`,
|
|
156
|
-
type: "button",
|
|
157
|
-
onClick: handleOpen,
|
|
158
|
-
children: [
|
|
159
|
-
/* @__PURE__ */ jsx(ExternalLink, { size: 14 }),
|
|
160
|
-
"Open"
|
|
161
|
-
]
|
|
162
|
-
}
|
|
163
|
-
),
|
|
164
|
-
/* @__PURE__ */ jsxs(
|
|
165
|
-
"button",
|
|
166
|
-
{
|
|
167
|
-
className: `${editActionButton} ${semanticClassNames.editActionButton}`,
|
|
168
|
-
type: "button",
|
|
169
|
-
onClick: handleConvertToLink,
|
|
170
|
-
children: [
|
|
171
|
-
/* @__PURE__ */ jsx(RemoveFormatting, { size: 14 }),
|
|
172
|
-
"To Link"
|
|
173
|
-
]
|
|
174
|
-
}
|
|
175
|
-
),
|
|
176
|
-
/* @__PURE__ */ jsxs(
|
|
177
|
-
"button",
|
|
178
|
-
{
|
|
179
|
-
className: `${editActionButton} ${semanticClassNames.editActionButton} ${editActionButtonEnd} ${semanticClassNames.editActionButtonEnd}`,
|
|
180
|
-
type: "button",
|
|
181
|
-
onClick: handleDelete,
|
|
182
|
-
children: [
|
|
183
|
-
/* @__PURE__ */ jsx(Unlink, { size: 14 }),
|
|
184
|
-
"Remove"
|
|
185
|
-
]
|
|
186
|
-
}
|
|
187
|
-
)
|
|
188
|
-
]
|
|
189
|
-
}
|
|
190
|
-
)
|
|
111
|
+
/* @__PURE__ */ jsxs("div", { className: `${editUrlRow} ${semanticClassNames.editUrlRow}`, children: [
|
|
112
|
+
/* @__PURE__ */ jsx(
|
|
113
|
+
Link,
|
|
114
|
+
{
|
|
115
|
+
className: `${editLinkIcon} ${semanticClassNames.editLinkIcon}`,
|
|
116
|
+
size: 16
|
|
117
|
+
}
|
|
118
|
+
),
|
|
119
|
+
/* @__PURE__ */ jsx(
|
|
120
|
+
"input",
|
|
121
|
+
{
|
|
122
|
+
className: `${editInput} ${semanticClassNames.editInput}`,
|
|
123
|
+
placeholder: "https://...",
|
|
124
|
+
ref: inputRef,
|
|
125
|
+
type: "url",
|
|
126
|
+
value: url,
|
|
127
|
+
onBlur: commitUrl,
|
|
128
|
+
onChange: (e2) => setUrl(e2.target.value),
|
|
129
|
+
onKeyDown: handleKeyDown
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
] }),
|
|
133
|
+
/* @__PURE__ */ jsxs(ActionBar, { children: [
|
|
134
|
+
/* @__PURE__ */ jsxs(ActionButton, { onClick: handleOpen, children: [
|
|
135
|
+
/* @__PURE__ */ jsx(ExternalLink, { size: 14 }),
|
|
136
|
+
"Open"
|
|
137
|
+
] }),
|
|
138
|
+
/* @__PURE__ */ jsxs(ActionButton, { onClick: handleConvertToLink, children: [
|
|
139
|
+
/* @__PURE__ */ jsx(RemoveFormatting, { size: 14 }),
|
|
140
|
+
"To Link"
|
|
141
|
+
] }),
|
|
142
|
+
/* @__PURE__ */ jsxs(ActionButton, { danger: true, onClick: handleDelete, children: [
|
|
143
|
+
/* @__PURE__ */ jsx(Unlink, { size: 14 }),
|
|
144
|
+
"Remove"
|
|
145
|
+
] })
|
|
146
|
+
] })
|
|
191
147
|
]
|
|
192
148
|
}
|
|
193
149
|
)
|
|
@@ -225,11 +181,7 @@ const _LinkCardEditNode = class _LinkCardEditNode extends LinkCardNode {
|
|
|
225
181
|
favicon: this.__favicon,
|
|
226
182
|
image: this.__image
|
|
227
183
|
};
|
|
228
|
-
const rendererEl = createRendererDecoration(
|
|
229
|
-
"LinkCard",
|
|
230
|
-
LinkCardRenderer,
|
|
231
|
-
payload
|
|
232
|
-
);
|
|
184
|
+
const rendererEl = createRendererDecoration("LinkCard", LinkCardRenderer, payload);
|
|
233
185
|
return createElement(LinkCardEditDecorator, {
|
|
234
186
|
nodeKey: this.__key,
|
|
235
187
|
payload,
|
|
@@ -263,10 +215,7 @@ function ConvertToLinkCardAction({
|
|
|
263
215
|
className
|
|
264
216
|
}) {
|
|
265
217
|
const [editor] = useLexicalComposerContext();
|
|
266
|
-
const info = useMemo(
|
|
267
|
-
() => matchUrl(url, pluginRegistry),
|
|
268
|
-
[url, pluginRegistry]
|
|
269
|
-
);
|
|
218
|
+
const info = useMemo(() => matchUrl(url, pluginRegistry), [url, pluginRegistry]);
|
|
270
219
|
if (!info) return null;
|
|
271
220
|
const handleConvert = () => {
|
|
272
221
|
editor.update(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"leetcode.d.ts","sourceRoot":"","sources":["../../../src/plugins/code/leetcode.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,cAAc,EAEf,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"leetcode.d.ts","sourceRoot":"","sources":["../../../src/plugins/code/leetcode.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,cAAc,EAEf,MAAM,aAAa,CAAC;AAoBrB,eAAO,MAAM,cAAc,EAAE,cAuF5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../../src/plugins/github/repo.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,cAAc,EAAkB,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../../src/plugins/github/repo.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,cAAc,EAAkB,MAAM,aAAa,CAAC;AAOhF,eAAO,MAAM,gBAAgB,EAAE,cAuD9B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}:root.dark{--rc-text: #fafafa;--rc-text-secondary: #a1a1aa;--rc-text-tertiary: #71717a;--rc-text-quaternary: #52525b;--rc-bg: #09090b;--rc-bg-secondary: #18181b;--rc-bg-tertiary: #27272a;--rc-fill: #2a2a2f;--rc-fill-secondary: #222226;--rc-fill-tertiary: #1b1b1f;--rc-fill-quaternary: #131316;--rc-border: #27272a;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #e4e4e7;--rc-code-bg: #27272a;--rc-hr-border: #27272a;--rc-quote-border: #60a5fa;--rc-quote-bg: #1e3a5f;--rc-alert-info: #7db9e5;--rc-alert-warning: #da864a;--rc-alert-tip: #54da48;--rc-alert-caution: #e16973;--rc-alert-important: #9966e0;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.4), 0 4px 6px -4px rgba(0,0,0,.35);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.25), 0 4px 16px rgba(0,0,0,.4);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._1osyxsk0{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._1osyxsk1{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.8;--rc-line-height-tight: 1.4;--rc-font-family: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._1osyxsk2{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #a1a1aa;--rc-quote-bg: #fafafa;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: none;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 2px;--rc-space-sm: 4px;--rc-space-md: 10px;--rc-space-lg: 16px;--rc-space-xl: 20px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 14px;--rc-font-size-small: 12px;--rc-line-height: 1.5;--rc-line-height-tight: 1.3;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 3px;--rc-radius-md: 6px;--rc-radius-lg: 8px}.dark ._1osyxsk0,[data-theme=dark] ._1osyxsk0,.dark._1osyxsk0,[data-theme=dark]._1osyxsk0,.dark ._1osyxsk1,[data-theme=dark] ._1osyxsk1,.dark._1osyxsk1,[data-theme=dark]._1osyxsk1,.dark ._1osyxsk2,[data-theme=dark] ._1osyxsk2,.dark._1osyxsk2,[data-theme=dark]._1osyxsk2{--rc-text: #fafafa;--rc-text-secondary: #a1a1aa;--rc-text-tertiary: #71717a;--rc-text-quaternary: #52525b;--rc-bg: #09090b;--rc-bg-secondary: #18181b;--rc-bg-tertiary: #27272a;--rc-fill: #2a2a2f;--rc-fill-secondary: #222226;--rc-fill-tertiary: #1b1b1f;--rc-fill-quaternary: #131316;--rc-border: #27272a;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #e4e4e7;--rc-code-bg: #27272a;--rc-hr-border: #27272a;--rc-quote-border: #60a5fa;--rc-quote-bg: #1e3a5f;--rc-alert-info: #7db9e5;--rc-alert-warning: #da864a;--rc-alert-tip: #54da48;--rc-alert-caution: #e16973;--rc-alert-important: #9966e0;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.4), 0 4px 6px -4px rgba(0,0,0,.35);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.25), 0 4px 16px rgba(0,0,0,.4)}@keyframes _13weebvh{0%,to{opacity:1}50%{opacity:.5}}._13weebv0{position:relative;display:flex;box-sizing:border-box;align-items:flex-start;gap:.75rem;width:32rem;max-width:100%;margin:1.25rem auto;padding:1rem;border-radius:.5rem;overflow:hidden;cursor:pointer;text-decoration:none;color:inherit;text-indent:0;font-family:var(--rc-font-family-sans);border:1px solid color-mix(in srgb,var(--rc-border) 80%,transparent);background-color:color-mix(in srgb,var(--rc-bg-secondary) 80%,transparent);backdrop-filter:blur(12px) saturate(150%);transition:background-color .2s}._13weebv0:hover{border-color:var(--rc-border);background-color:var(--rc-fill-tertiary)}._13weebv1{align-items:center}._13weebv0 *{font-style:normal!important}._13weebv0 span{border-bottom:0!important}._13weebv2{position:absolute;inset:0;z-index:0;pointer-events:none}._13weebv3{position:relative;flex-shrink:0;width:2.5rem;height:2.5rem;border-radius:.5rem;background-size:cover;background-position:center;background-repeat:no-repeat;background-color:var(--rc-bg-secondary);z-index:1}._13weebv4{width:6.25rem!important;height:auto!important;min-height:8.75rem;aspect-ratio:2 / 3;align-self:stretch}._13weebv5{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;border-radius:.5rem;background-color:var(--rc-bg-secondary);z-index:1}._13weebv5 img{width:1.25rem;height:1.25rem;border-radius:.25rem}._13weebv5 svg{width:1.25rem;height:1.25rem;color:var(--rc-text-secondary)}._13weebv6{flex:1;min-width:0;position:relative;z-index:1}._13weebv7{display:flex;align-items:center;gap:.5rem;line-height:1.25rem}._13weebv8{flex:1;min-width:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;text-overflow:ellipsis;font-size:var(--rc-font-size-md);font-weight:600;line-height:1.25rem}._13weebv9{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;text-overflow:ellipsis;margin-top:.375rem;font-size:var(--rc-font-size-md);line-height:1.5;color:var(--rc-text-secondary);min-width:0}._13weebvb{width:100%!important;height:auto!important;max-width:40rem;padding:0}._13weebvb ._13weebv3{border-radius:0;align-self:stretch;height:auto!important;margin-left:0!important}._13weebvb ._13weebv3:after{content:"";position:absolute;inset:0;background:linear-gradient(to right,transparent 60%,var(--rc-bg-secondary));pointer-events:none}._13weebvb ._13weebv6{padding:1rem;display:flex;flex-direction:column;justify-content:center}._13weebvc{width:100%;max-width:40rem}._13weebvd{width:100%!important;max-width:unset!important}._13weebvd ._13weebv9{-webkit-line-clamp:4}._13weebve{width:36rem}._13weebvf{width:38rem}._13weebvf ._13weebv9{-webkit-line-clamp:3}._13weebv0[data-source=gh-repo]{height:6.25rem}._13weebv0[data-source=gh-commit],._13weebv0[data-source=gh-pr],._13weebv0[data-source=gh-issue],._13weebv0[data-source=gh-discussion]{height:5rem}._13weebv0[data-source=leetcode]{height:5.25rem}._13weebv0[data-source=arxiv]{height:6rem}._13weebv0[data-source=netease-music-song],._13weebv0[data-source=qq-music-song]{height:5.75rem}._13weebvg{animation-play-state:paused}._13weebvg ._13weebv8{width:8rem;height:1.25rem;border-radius:.375rem;background-color:var(--rc-border)}._13weebvg ._13weebv9{width:100%;margin-top:.5rem;height:.875rem;border-radius:.375rem;background-color:var(--rc-border)}._13weebvg ._13weebva{width:80%}._13weebvg ._13weebv3{background-color:var(--rc-border)}._13weebvg ._13weebv8,._13weebvg ._13weebv9,._13weebvg ._13weebv3{animation:_13weebvh 2s cubic-bezier(.4,0,.6,1) infinite}._13weebvg._13weebvi{background-color:color-mix(in srgb,var(--rc-alert-caution) 12%,transparent)!important;border:0}._13weebvg._13weebvi ._13weebv8,._13weebvg._13weebvi ._13weebv9,._13weebvg._13weebvi ._13weebv3{background-color:color-mix(in srgb,var(--rc-alert-caution) 47%,transparent);color:transparent;animation:none}._13weebvg._13weebvi ._13weebv6{overflow:hidden;min-width:0}._13weebvg._13weebvi ._13weebv9{width:80%}._13weebvg._13weebvi ._13weebv3{background-image:none!important}._13weebvj{display:block}._13weebvk{display:flex;flex-direction:column;gap:8px;width:340px;padding:12px;font-size:var(--rc-font-size-sm);background-color:var(--rc-bg);border-color:var(--rc-border);color:var(--rc-text)}._13weebvl{display:flex;align-items:center;gap:8px;padding:8px 12px;background-color:var(--rc-bg-secondary);border-radius:var(--rc-radius-md);min-width:0}._13weebvm{flex-shrink:0;color:var(--rc-text-secondary)}._13weebvn{flex:1;appearance:none;border:none;background-color:transparent;color:var(--rc-text);font-family:var(--rc-font-mono);font-size:var(--rc-font-size-sm);padding:0;outline:none;min-width:0}._13weebvo{display:flex;align-items:center;gap:4px}._13weebvp{display:inline-flex;align-items:center;gap:6px;appearance:none;border:none;background:none;color:var(--rc-text);font-size:var(--rc-font-size-sm);font-weight:500;cursor:pointer;padding:4px 8px;border-radius:var(--rc-radius-sm);transition:color .15s ease,background-color .15s ease;white-space:nowrap}._13weebvp:hover{background-color:var(--rc-fill-secondary)}._13weebvq{margin-left:auto}@media(max-width:640px){._13weebve{width:100%}}
|
|
1
|
+
:root{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}:root.dark{--rc-text: #fafafa;--rc-text-secondary: #a1a1aa;--rc-text-tertiary: #71717a;--rc-text-quaternary: #52525b;--rc-bg: #09090b;--rc-bg-secondary: #18181b;--rc-bg-tertiary: #27272a;--rc-fill: #2a2a2f;--rc-fill-secondary: #222226;--rc-fill-tertiary: #1b1b1f;--rc-fill-quaternary: #131316;--rc-border: #27272a;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #e4e4e7;--rc-code-bg: #27272a;--rc-hr-border: #27272a;--rc-quote-border: #60a5fa;--rc-quote-bg: #1e3a5f;--rc-alert-info: #7db9e5;--rc-alert-warning: #da864a;--rc-alert-tip: #54da48;--rc-alert-caution: #e16973;--rc-alert-important: #9966e0;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.4), 0 4px 6px -4px rgba(0,0,0,.35);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.25), 0 4px 16px rgba(0,0,0,.4);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._1osyxsk0{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.7;--rc-line-height-tight: 1.4;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._1osyxsk1{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #2563eb;--rc-quote-bg: #eff6ff;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: 700px;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 4px;--rc-space-sm: 8px;--rc-space-md: 16px;--rc-space-lg: 24px;--rc-space-xl: 32px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 16px;--rc-font-size-small: 14px;--rc-line-height: 1.8;--rc-line-height-tight: 1.4;--rc-font-family: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-radius-sm: 4px;--rc-radius-md: 8px;--rc-radius-lg: 12px}._1osyxsk2{--rc-text: #000;--rc-text-secondary: #27272a;--rc-text-tertiary: #71717a;--rc-text-quaternary: #a1a1aa;--rc-bg: #ffffff;--rc-bg-secondary: #fafafa;--rc-bg-tertiary: #f4f4f5;--rc-fill: #e8e8ec;--rc-fill-secondary: #eeeeef;--rc-fill-tertiary: #f4f4f6;--rc-fill-quaternary: #f9f9fa;--rc-border: #f4f4f5;--rc-accent: #2563eb;--rc-accent-light: #2563eb20;--rc-link: #2563eb;--rc-code-text: #3f3f46;--rc-code-bg: #f4f4f5;--rc-hr-border: #e4e4e7;--rc-quote-border: #a1a1aa;--rc-quote-bg: #fafafa;--rc-alert-info: #006bb7;--rc-alert-warning: #cc5500;--rc-alert-tip: #11cc00;--rc-alert-caution: #cc0011;--rc-alert-important: #5500cc;--rc-max-width: none;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.1), 0 4px 6px -4px rgba(0,0,0,.1);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.04), 0 4px 16px rgba(0,0,0,.08);--rc-space-xs: 2px;--rc-space-sm: 4px;--rc-space-md: 10px;--rc-space-lg: 16px;--rc-space-xl: 20px;--rc-font-family-sans: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-font-family-serif: "Noto Serif CJK SC", "Source Han Serif SC", "Source Han Serif", "source-han-serif-sc", "Songti SC", STSong, "华文宋体", serif;--rc-font-mono: "SF Mono", SFMono-Regular, ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace;--rc-font-size-2xs: .625em;--rc-font-size-xs: .75em;--rc-font-size-sm: .8125em;--rc-font-size-md: .875em;--rc-font-size-lg: 1.25em;--rc-font-size-base: 14px;--rc-font-size-small: 12px;--rc-line-height: 1.5;--rc-line-height-tight: 1.3;--rc-font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", Roboto, Helvetica, "noto sans sc", "hiragino sans gb", -apple-system, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Not Color Emoji;--rc-radius-sm: 3px;--rc-radius-md: 6px;--rc-radius-lg: 8px}.dark ._1osyxsk0,[data-theme=dark] ._1osyxsk0,.dark._1osyxsk0,[data-theme=dark]._1osyxsk0,.dark ._1osyxsk1,[data-theme=dark] ._1osyxsk1,.dark._1osyxsk1,[data-theme=dark]._1osyxsk1,.dark ._1osyxsk2,[data-theme=dark] ._1osyxsk2,.dark._1osyxsk2,[data-theme=dark]._1osyxsk2{--rc-text: #fafafa;--rc-text-secondary: #a1a1aa;--rc-text-tertiary: #71717a;--rc-text-quaternary: #52525b;--rc-bg: #09090b;--rc-bg-secondary: #18181b;--rc-bg-tertiary: #27272a;--rc-fill: #2a2a2f;--rc-fill-secondary: #222226;--rc-fill-tertiary: #1b1b1f;--rc-fill-quaternary: #131316;--rc-border: #27272a;--rc-accent: #60a5fa;--rc-accent-light: #60a5fa20;--rc-link: #60a5fa;--rc-code-text: #e4e4e7;--rc-code-bg: #27272a;--rc-hr-border: #27272a;--rc-quote-border: #60a5fa;--rc-quote-bg: #1e3a5f;--rc-alert-info: #7db9e5;--rc-alert-warning: #da864a;--rc-alert-tip: #54da48;--rc-alert-caution: #e16973;--rc-alert-important: #9966e0;--rc-shadow-top-bar: 0 8px 30px rgba(0, 0, 0, .45), 0 2px 8px rgba(0, 0, 0, .3);--rc-shadow-modal: 0 10px 15px -3px rgba(0,0,0,.4), 0 4px 6px -4px rgba(0,0,0,.35);--rc-shadow-menu: 0 1px 4px rgba(0,0,0,.25), 0 4px 16px rgba(0,0,0,.4)}@keyframes _13weebvh{0%,to{opacity:1}50%{opacity:.5}}._13weebv0{position:relative;display:flex;box-sizing:border-box;align-items:flex-start;gap:.75rem;width:32rem;max-width:100%;margin:1.25rem auto;padding:1rem;border-radius:.5rem;overflow:hidden;cursor:pointer;text-decoration:none;color:inherit;text-indent:0;font-family:var(--rc-font-family-sans);border:1px solid color-mix(in srgb,var(--rc-border) 80%,transparent);background-color:color-mix(in srgb,var(--rc-bg-secondary) 80%,transparent);backdrop-filter:blur(12px) saturate(150%);transition:background-color .2s}._13weebv0:hover{border-color:var(--rc-border);background-color:var(--rc-fill-tertiary)}._13weebv1{align-items:center}._13weebv0 *{font-style:normal!important}._13weebv0 span{border-bottom:0!important}._13weebv2{position:absolute;inset:0;z-index:0;pointer-events:none}._13weebv3{position:relative;flex-shrink:0;width:2.5rem;height:2.5rem;border-radius:.5rem;background-size:cover;background-position:center;background-repeat:no-repeat;background-color:var(--rc-bg-secondary);z-index:1}._13weebv4{width:6.25rem!important;height:auto!important;min-height:8.75rem;aspect-ratio:2 / 3;align-self:stretch}._13weebv5{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;border-radius:.5rem;background-color:var(--rc-bg-secondary);z-index:1}._13weebv5 img{width:1.25rem;height:1.25rem;border-radius:.25rem}._13weebv5 svg{width:1.25rem;height:1.25rem;color:var(--rc-text-secondary)}._13weebv6{flex:1;min-width:0;position:relative;z-index:1}._13weebv7{display:flex;align-items:center;gap:.5rem;line-height:1.25rem}._13weebv8{flex:1;min-width:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;text-overflow:ellipsis;font-size:var(--rc-font-size-md);font-weight:600;line-height:1.25rem}._13weebv9{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;text-overflow:ellipsis;margin-top:.375rem;font-size:var(--rc-font-size-md);line-height:1.5;color:var(--rc-text-secondary);min-width:0}._13weebvb{width:100%!important;height:auto!important;max-width:40rem;padding:0}._13weebvb ._13weebv3{border-radius:0;align-self:stretch;height:auto!important;margin-left:0!important}._13weebvb ._13weebv3:after{content:"";position:absolute;inset:0;background:linear-gradient(to right,transparent 60%,var(--rc-bg-secondary));pointer-events:none}._13weebvb ._13weebv6{padding:1rem;display:flex;flex-direction:column;justify-content:center}._13weebvc{width:100%;max-width:40rem}._13weebvd{width:100%!important;max-width:unset!important}._13weebvd ._13weebv9{-webkit-line-clamp:4}._13weebve{width:36rem}._13weebvf{width:38rem}._13weebvf ._13weebv9{-webkit-line-clamp:3}._13weebv0[data-source=gh-repo]{height:6.25rem}._13weebv0[data-source=gh-commit],._13weebv0[data-source=gh-pr],._13weebv0[data-source=gh-issue],._13weebv0[data-source=gh-discussion]{height:5rem}._13weebv0[data-source=leetcode]{height:5.25rem}._13weebv0[data-source=arxiv]{height:6rem}._13weebv0[data-source=netease-music-song],._13weebv0[data-source=qq-music-song]{height:5.75rem}._13weebvg{animation-play-state:paused}._13weebvg ._13weebv8{width:8rem;height:1.25rem;border-radius:.375rem;background-color:var(--rc-border)}._13weebvg ._13weebv9{width:100%;margin-top:.5rem;height:.875rem;border-radius:.375rem;background-color:var(--rc-border)}._13weebvg ._13weebva{width:80%}._13weebvg ._13weebv3{background-color:var(--rc-border)}._13weebvg ._13weebv8,._13weebvg ._13weebv9,._13weebvg ._13weebv3{animation:_13weebvh 2s cubic-bezier(.4,0,.6,1) infinite}._13weebvg._13weebvi{background-color:color-mix(in srgb,var(--rc-alert-caution) 12%,transparent)!important;border:0}._13weebvg._13weebvi ._13weebv8,._13weebvg._13weebvi ._13weebv9,._13weebvg._13weebvi ._13weebv3{background-color:color-mix(in srgb,var(--rc-alert-caution) 47%,transparent);color:transparent;animation:none}._13weebvg._13weebvi ._13weebv6{overflow:hidden;min-width:0}._13weebvg._13weebvi ._13weebv9{width:80%}._13weebvg._13weebvi ._13weebv3{background-image:none!important}._13weebvj{display:block}._13weebvk{display:flex;flex-direction:column;gap:8px;width:340px;padding:12px;font-size:var(--rc-font-size-sm);background-color:var(--rc-bg);border-color:var(--rc-border);color:var(--rc-text)}._13weebvl{display:flex;align-items:center;gap:8px;padding:8px 12px;background-color:var(--rc-bg-secondary);border-radius:var(--rc-radius-md);min-width:0}._13weebvm{flex-shrink:0;color:var(--rc-text-secondary)}._13weebvn{flex:1;appearance:none;border:none;background-color:transparent;color:var(--rc-text);font-family:var(--rc-font-mono);font-size:var(--rc-font-size-sm);padding:0;outline:none;min-width:0}@media(max-width:640px){._13weebve{width:100%}}
|
package/dist/static.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { L, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y } from "./LinkCardRenderer-
|
|
1
|
+
import { L, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y } from "./LinkCardRenderer-CJB5CmHP.js";
|
|
2
2
|
export {
|
|
3
3
|
L as LanguageToColorMap,
|
|
4
4
|
a as LinkCardFetchProvider,
|
package/dist/styles.css.d.ts
CHANGED
|
@@ -22,9 +22,6 @@ export declare const semanticClassNames: {
|
|
|
22
22
|
readonly editUrlRow: "rich-link-card-edit-url-row";
|
|
23
23
|
readonly editLinkIcon: "rich-link-card-edit-link-icon";
|
|
24
24
|
readonly editInput: "rich-link-card-edit-input";
|
|
25
|
-
readonly editActions: "rich-link-card-edit-actions";
|
|
26
|
-
readonly editActionButton: "rich-link-card-edit-action-btn";
|
|
27
|
-
readonly editActionButtonEnd: "rich-link-card-edit-action-btn--end";
|
|
28
25
|
};
|
|
29
26
|
export declare const card: string;
|
|
30
27
|
export declare const cardShortDesc: string;
|
|
@@ -49,9 +46,6 @@ export declare const editPanel: string;
|
|
|
49
46
|
export declare const editUrlRow: string;
|
|
50
47
|
export declare const editLinkIcon: string;
|
|
51
48
|
export declare const editInput: string;
|
|
52
|
-
export declare const editActions: string;
|
|
53
|
-
export declare const editActionButton: string;
|
|
54
|
-
export declare const editActionButtonEnd: string;
|
|
55
49
|
export declare const typeCardModifier: {
|
|
56
50
|
readonly media: string;
|
|
57
51
|
readonly github: string;
|
package/dist/styles.css.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.css.d.ts","sourceRoot":"","sources":["../src/styles.css.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"styles.css.d.ts","sourceRoot":"","sources":["../src/styles.css.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;CAyBrB,CAAA;AAEV,eAAO,MAAM,IAAI,QA2Bf,CAAA;AAEF,eAAO,MAAM,aAAa,QAExB,CAAA;AAKF,eAAO,MAAM,EAAE,QAKb,CAAA;AAEF,eAAO,MAAM,KAAK,QAWhB,CAAA;AAEF,eAAO,MAAM,WAAW,QAMtB,CAAA;AAEF,eAAO,MAAM,IAAI,QAUf,CAAA;AAcF,eAAO,MAAM,OAAO,QAKlB,CAAA;AAEF,eAAO,MAAM,KAAK,QAKhB,CAAA;AAEF,eAAO,MAAM,SAAS,QAWpB,CAAA;AAEF,eAAO,MAAM,IAAI,QAWf,CAAA;AAEF,eAAO,MAAM,KAAK,QAAY,CAAA;AAE9B,eAAO,MAAM,UAAU,QAKrB,CAAA;AAwBF,eAAO,MAAM,QAAQ,QAA8C,CAAA;AACnE,eAAO,MAAM,SAAS,QAGpB,CAAA;AAGF,eAAO,MAAM,UAAU,QAGrB,CAAA;AAEF,eAAO,MAAM,YAAY,QAA4B,CAAA;AAerD,eAAO,MAAM,YAAY,QAA0C,CAAA;AAmCnE,eAAO,MAAM,SAAS,QAAY,CAAA;AA8BlC,eAAO,MAAM,WAAW,QAEtB,CAAA;AAEF,eAAO,MAAM,SAAS,QAUpB,CAAA;AAEF,eAAO,MAAM,UAAU,QAQrB,CAAA;AAEF,eAAO,MAAM,YAAY,QAGvB,CAAA;AAEF,eAAO,MAAM,SAAS,QAWpB,CAAA;AAEF,eAAO,MAAM,gBAAgB;;;;;CAKnB,CAAA;AAEV,eAAO,MAAM,sBAAsB;;;;;CAKzB,CAAA;AAEV,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAUvD,CAAA"}
|
package/dist/types.d.ts
CHANGED
|
@@ -3,28 +3,28 @@ import { ReactNode } from 'react';
|
|
|
3
3
|
* 卡片数据 - 插件只提供数据,渲染统一
|
|
4
4
|
*/
|
|
5
5
|
export interface LinkCardData {
|
|
6
|
-
/** 卡片标题 */
|
|
7
|
-
title: ReactNode;
|
|
8
|
-
/** 卡片描述 */
|
|
9
|
-
desc?: ReactNode;
|
|
10
|
-
/** 图片 URL */
|
|
11
|
-
image?: string;
|
|
12
|
-
/** 高亮/主题色 (hex 格式) */
|
|
13
|
-
color?: string;
|
|
14
6
|
/** CSS 类名覆盖 */
|
|
15
7
|
classNames?: {
|
|
16
8
|
image?: string;
|
|
17
9
|
cardRoot?: string;
|
|
18
10
|
};
|
|
11
|
+
/** 高亮/主题色 (hex 格式) */
|
|
12
|
+
color?: string;
|
|
13
|
+
/** 卡片描述 */
|
|
14
|
+
desc?: ReactNode;
|
|
15
|
+
/** 图片 URL */
|
|
16
|
+
image?: string;
|
|
17
|
+
/** 卡片标题 */
|
|
18
|
+
title: ReactNode;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* URL 匹配结果
|
|
22
22
|
*/
|
|
23
23
|
export interface UrlMatchResult {
|
|
24
|
-
/** 解析后的 ID */
|
|
25
|
-
id: string;
|
|
26
24
|
/** 完整 URL(用于链接跳转) */
|
|
27
25
|
fullUrl?: string;
|
|
26
|
+
/** 解析后的 ID */
|
|
27
|
+
id: string;
|
|
28
28
|
/** 额外元数据 */
|
|
29
29
|
meta?: Record<string, unknown>;
|
|
30
30
|
}
|
|
@@ -32,21 +32,21 @@ export interface UrlMatchResult {
|
|
|
32
32
|
* 请求适配器:由业务方注入具体请求策略(鉴权、代理、限流兜底、重试等)
|
|
33
33
|
*/
|
|
34
34
|
export interface LinkCardApiAdapter {
|
|
35
|
-
request<T = unknown>(input: string, init?: RequestInit)
|
|
35
|
+
request: <T = unknown>(input: string, init?: RequestInit) => Promise<T>;
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* LinkCard fetch 运行时上下文
|
|
39
39
|
*/
|
|
40
40
|
export interface LinkCardFetchContext {
|
|
41
|
-
/**
|
|
42
|
-
* 全局默认 fetcher(当 provider 适配器不存在时使用)
|
|
43
|
-
*/
|
|
44
|
-
fetchJson?<T = unknown>(input: string, init?: RequestInit): Promise<T>;
|
|
45
41
|
/**
|
|
46
42
|
* 按 provider 注入请求适配器
|
|
47
43
|
* 例如: { github: { request: ... }, tmdb: { request: ... } }
|
|
48
44
|
*/
|
|
49
45
|
adapters?: Record<string, LinkCardApiAdapter>;
|
|
46
|
+
/**
|
|
47
|
+
* 全局默认 fetcher(当 provider 适配器不存在时使用)
|
|
48
|
+
*/
|
|
49
|
+
fetchJson?: <T = unknown>(input: string, init?: RequestInit) => Promise<T>;
|
|
50
50
|
}
|
|
51
51
|
/** 卡片类型样式 */
|
|
52
52
|
export type LinkCardTypeClass = 'media' | 'github' | 'academic' | 'wide';
|
|
@@ -54,32 +54,32 @@ export type LinkCardTypeClass = 'media' | 'github' | 'academic' | 'wide';
|
|
|
54
54
|
* 插件接口 - 每个插件自包含
|
|
55
55
|
*/
|
|
56
56
|
export interface LinkCardPlugin<TMeta = Record<string, unknown>> {
|
|
57
|
-
/** 唯一标识符 */
|
|
58
|
-
readonly name: string;
|
|
59
57
|
/** 可读名称(调试/文档用) */
|
|
60
58
|
readonly displayName: string;
|
|
61
|
-
/** URL 匹配优先级(越高越先匹配) */
|
|
62
|
-
readonly priority?: number;
|
|
63
|
-
/** 卡片样式类型 */
|
|
64
|
-
readonly typeClass?: LinkCardTypeClass;
|
|
65
|
-
/** 插件依赖的 provider 名称,用于路由到对应请求适配器 */
|
|
66
|
-
readonly provider?: string;
|
|
67
59
|
/**
|
|
68
|
-
*
|
|
69
|
-
* @
|
|
60
|
+
* 获取卡片数据
|
|
61
|
+
* @param id - 解析后的标识符
|
|
62
|
+
* @param meta - URL 匹配时的元数据
|
|
63
|
+
* @param context - 运行时上下文(请求适配器、全局 fetcher 等)
|
|
70
64
|
*/
|
|
71
|
-
|
|
65
|
+
fetch: (id: string, meta?: TMeta, context?: LinkCardFetchContext) => Promise<LinkCardData>;
|
|
72
66
|
/**
|
|
73
67
|
* 验证 ID 格式(支持显式 source 用法)
|
|
74
68
|
*/
|
|
75
|
-
isValidId(id: string)
|
|
69
|
+
isValidId: (id: string) => boolean;
|
|
76
70
|
/**
|
|
77
|
-
*
|
|
78
|
-
* @
|
|
79
|
-
* @param meta - URL 匹配时的元数据
|
|
80
|
-
* @param context - 运行时上下文(请求适配器、全局 fetcher 等)
|
|
71
|
+
* 匹配 URL
|
|
72
|
+
* @returns 匹配结果或 null
|
|
81
73
|
*/
|
|
82
|
-
|
|
74
|
+
matchUrl: (url: URL) => UrlMatchResult | null;
|
|
75
|
+
/** 唯一标识符 */
|
|
76
|
+
readonly name: string;
|
|
77
|
+
/** URL 匹配优先级(越高越先匹配) */
|
|
78
|
+
readonly priority?: number;
|
|
79
|
+
/** 插件依赖的 provider 名称,用于路由到对应请求适配器 */
|
|
80
|
+
readonly provider?: string;
|
|
81
|
+
/** 卡片样式类型 */
|
|
82
|
+
readonly typeClass?: LinkCardTypeClass;
|
|
83
83
|
}
|
|
84
84
|
/**
|
|
85
85
|
* 插件注册表类型
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,eAAe;IACf,UAAU,CAAC,EAAE;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,sBAAsB;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW;IACX,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,aAAa;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW;IACX,KAAK,EAAE,SAAS,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc;IACd,EAAE,EAAE,MAAM,CAAC;IACX,YAAY;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CACzE;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC9C;;OAEG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CAC5E;AAED,aAAa;AACb,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC7D,mBAAmB;IACnB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;;;OAKG;IACH,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,oBAAoB,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAE3F;;OAEG;IACH,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IAEnC;;;OAGG;IACH,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,cAAc,GAAG,IAAI,CAAC;IAC9C,YAAY;IACZ,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,wBAAwB;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,qCAAqC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAE3B,aAAa;IACb,QAAQ,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAC;CACxC;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,SAAS,cAAc,EAAE,CAAC"}
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAMpD,wBAAgB,aAAa,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,CAQlD;AAED,wBAAsB,oBAAoB,CAAC,CAAC,GAAG,GAAG,EAChD,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,oBAAoB,EAC9B,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,CAAC,CAAC,CAgBZ;AAED,wBAAsB,cAAc,CAAC,CAAC,GAAG,GAAG,EAC1C,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,CAAC,CAAC,CAGZ;AAED,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAmCrD,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAIjD,CAAC;AACF,eAAO,MAAM,mBAAmB,UAA8B,CAAC;AAgB/D,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,CAAC,MAAM,EAAE,MAAM,CAAY,EACvC,SAAS,GAAE,CAAC,MAAM,EAAE,MAAM,CAAY,GACrC,MAAM,CAWR;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOlD"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@haklex/rich-renderer-linkcard",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
3
|
+
"version": "0.0.67",
|
|
4
|
+
"description": "Rich link preview card renderer with extensible URL plugins",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/Innei/haklex.git",
|
|
8
|
+
"directory": "packages/rich-renderer-linkcard"
|
|
9
|
+
},
|
|
5
10
|
"license": "MIT",
|
|
11
|
+
"type": "module",
|
|
6
12
|
"exports": {
|
|
7
13
|
".": {
|
|
8
14
|
"import": "./dist/index.mjs",
|
|
@@ -18,19 +24,12 @@
|
|
|
18
24
|
"files": [
|
|
19
25
|
"dist"
|
|
20
26
|
],
|
|
21
|
-
"peerDependencies": {
|
|
22
|
-
"@lexical/link": "^0.41.0",
|
|
23
|
-
"@lexical/react": "^0.41.0",
|
|
24
|
-
"lexical": "^0.41.0",
|
|
25
|
-
"react": ">=19",
|
|
26
|
-
"react-dom": ">=19"
|
|
27
|
-
},
|
|
28
27
|
"dependencies": {
|
|
29
28
|
"lucide-react": "^0.577.0",
|
|
30
29
|
"react-intersection-observer": "^10.0.3",
|
|
31
|
-
"@haklex/rich-editor": "0.0.
|
|
32
|
-
"@haklex/rich-editor-ui": "0.0.
|
|
33
|
-
"@haklex/rich-style-token": "0.0.
|
|
30
|
+
"@haklex/rich-editor": "0.0.67",
|
|
31
|
+
"@haklex/rich-editor-ui": "0.0.67",
|
|
32
|
+
"@haklex/rich-style-token": "0.0.67"
|
|
34
33
|
},
|
|
35
34
|
"devDependencies": {
|
|
36
35
|
"@lexical/link": "^0.41.0",
|
|
@@ -46,6 +45,13 @@
|
|
|
46
45
|
"vite": "^7.3.1",
|
|
47
46
|
"vite-plugin-dts": "^4.5.4"
|
|
48
47
|
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"@lexical/link": "^0.41.0",
|
|
50
|
+
"@lexical/react": "^0.41.0",
|
|
51
|
+
"lexical": "^0.41.0",
|
|
52
|
+
"react": ">=19",
|
|
53
|
+
"react-dom": ">=19"
|
|
54
|
+
},
|
|
49
55
|
"publishConfig": {
|
|
50
56
|
"access": "public"
|
|
51
57
|
},
|