mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-17 03:10:38 +09:00
Fix markdown mention chips
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
cd7c6ee751
commit
8232456ce8
14 changed files with 527 additions and 264 deletions
|
|
@ -1,9 +1,9 @@
|
|||
import { isValidElement, useEffect, useId, useState, type CSSProperties, type ReactNode } from "react";
|
||||
import { isValidElement, useEffect, useId, useState, type ReactNode } from "react";
|
||||
import Markdown, { type Components } from "react-markdown";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import { parseProjectMentionHref } from "@paperclipai/shared";
|
||||
import { cn } from "../lib/utils";
|
||||
import { useTheme } from "../context/ThemeContext";
|
||||
import { mentionChipInlineStyle, parseMentionChipHref } from "../lib/mention-chips";
|
||||
|
||||
interface MarkdownBodyProps {
|
||||
children: string;
|
||||
|
|
@ -36,29 +36,6 @@ function extractMermaidSource(children: ReactNode): string | null {
|
|||
return flattenText(childProps.children).replace(/\n$/, "");
|
||||
}
|
||||
|
||||
function hexToRgb(hex: string): { r: number; g: number; b: number } | null {
|
||||
const match = /^#([0-9a-f]{6})$/i.exec(hex.trim());
|
||||
if (!match) return null;
|
||||
const value = match[1];
|
||||
return {
|
||||
r: parseInt(value.slice(0, 2), 16),
|
||||
g: parseInt(value.slice(2, 4), 16),
|
||||
b: parseInt(value.slice(4, 6), 16),
|
||||
};
|
||||
}
|
||||
|
||||
function mentionChipStyle(color: string | null): CSSProperties | undefined {
|
||||
if (!color) return undefined;
|
||||
const rgb = hexToRgb(color);
|
||||
if (!rgb) return undefined;
|
||||
const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;
|
||||
return {
|
||||
borderColor: color,
|
||||
backgroundColor: `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.22)`,
|
||||
color: luminance > 0.55 ? "#111827" : "#f8fafc",
|
||||
};
|
||||
}
|
||||
|
||||
function MermaidDiagramBlock({ source, darkMode }: { source: string; darkMode: boolean }) {
|
||||
const renderId = useId().replace(/[^a-zA-Z0-9_-]/g, "");
|
||||
const [svg, setSvg] = useState<string | null>(null);
|
||||
|
|
@ -125,16 +102,23 @@ export function MarkdownBody({ children, className, resolveImageSrc }: MarkdownB
|
|||
return <pre {...preProps}>{preChildren}</pre>;
|
||||
},
|
||||
a: ({ href, children: linkChildren }) => {
|
||||
const parsed = href ? parseProjectMentionHref(href) : null;
|
||||
const parsed = href ? parseMentionChipHref(href) : null;
|
||||
if (parsed) {
|
||||
const label = linkChildren;
|
||||
const targetHref = parsed.kind === "project"
|
||||
? `/projects/${parsed.projectId}`
|
||||
: `/agents/${parsed.agentId}`;
|
||||
return (
|
||||
<a
|
||||
href={`/projects/${parsed.projectId}`}
|
||||
className="paperclip-project-mention-chip"
|
||||
style={mentionChipStyle(parsed.color)}
|
||||
href={targetHref}
|
||||
className={cn(
|
||||
"paperclip-mention-chip",
|
||||
`paperclip-mention-chip--${parsed.kind}`,
|
||||
parsed.kind === "project" && "paperclip-project-mention-chip",
|
||||
)}
|
||||
data-mention-kind={parsed.kind}
|
||||
style={mentionChipInlineStyle(parsed)}
|
||||
>
|
||||
{label}
|
||||
{linkChildren}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
|
@ -160,7 +144,7 @@ export function MarkdownBody({ children, className, resolveImageSrc }: MarkdownB
|
|||
className,
|
||||
)}
|
||||
>
|
||||
<Markdown remarkPlugins={[remarkGfm]} components={components}>
|
||||
<Markdown remarkPlugins={[remarkGfm]} components={components} urlTransform={(url) => url}>
|
||||
{children}
|
||||
</Markdown>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue