mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-03-10 16:37:40 +00:00
feat(plugins): add SVG icon support with authenticated inline rendering
This commit is contained in:
39
src/components/plugins/PluginIcon.tsx
Normal file
39
src/components/plugins/PluginIcon.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { authenticatedFetch } from '../../utils/api';
|
||||
|
||||
type Props = {
|
||||
pluginName: string;
|
||||
iconFile: string;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
// Module-level cache so repeated renders don't re-fetch
|
||||
const svgCache = new Map<string, string>();
|
||||
|
||||
export default function PluginIcon({ pluginName, iconFile, className }: Props) {
|
||||
const url = `/api/plugins/${encodeURIComponent(pluginName)}/assets/${encodeURIComponent(iconFile)}`;
|
||||
const [svg, setSvg] = useState<string | null>(svgCache.get(url) ?? null);
|
||||
|
||||
useEffect(() => {
|
||||
if (svgCache.has(url)) return;
|
||||
authenticatedFetch(url)
|
||||
.then((r) => r.text())
|
||||
.then((text) => {
|
||||
if (text.trimStart().startsWith('<svg')) {
|
||||
svgCache.set(url, text);
|
||||
setSvg(text);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
}, [url]);
|
||||
|
||||
if (!svg) return <span className={className} />;
|
||||
|
||||
return (
|
||||
<span
|
||||
className={className}
|
||||
// SVG is fetched from the user's own installed plugin — same trust level as the plugin code itself
|
||||
dangerouslySetInnerHTML={{ __html: svg }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user