← Files NGS Analysis WorkbenchARCHIVED FILE
src/design-system/Icon.tsx
2.62 KB · Sep 30, 2026 · 23:20 UTC
import type { CSSProperties, HTMLAttributes } from "react";
import arrowLeft from "./icons/arrow-left.svg?inline";
import arrowTopRight from "./icons/arrow-top-right-sm-thin.svg?inline";
import barChart from "./icons/bar-chart.svg?inline";
import buildingBlocks from "./icons/building-blocks.svg?inline";
import checkMd from "./icons/check-md.svg?inline";
import chevronDown from "./icons/chevron-down-sm.svg?inline";
import chevronRight from "./icons/chevron-right-sm.svg?inline";
import close from "./icons/close-small.svg?inline";
import closeMedium from "./icons/close-medium.svg?inline";
import copy from "./icons/copy.svg?inline";
import info from "./icons/info-sm.svg?inline";
import menu from "./icons/menu.svg?inline";
import regenerate from "./icons/regenerate.svg?inline";
import spinner from "./icons/spinner.svg?inline";
import squareGrid from "./icons/square-grid.svg?inline";
import document from "./icons/upload-documents.svg?inline";
const icons = {
"arrow-left": arrowLeft,
"arrow-top-right-sm-thin": arrowTopRight,
"bar-chart": barChart,
"building-blocks": buildingBlocks,
"check-md": checkMd,
"chevron-down-sm": chevronDown,
"chevron-right-sm": chevronRight,
"close-small": close,
"close-medium": closeMedium,
copy,
"info-sm": info,
menu,
regenerate,
spinner,
"square-grid": squareGrid,
"upload-documents": document,
};
export type IconName = keyof typeof icons;
// The foundation Icon primitive, with inlined source assets so packaged MCP
// resources never depend on a host-relative /icons URL or external fetch.
export function Icon({
className,
label,
name,
size = 18,
style,
...props
}: Omit<HTMLAttributes<HTMLSpanElement>, "children"> & {
name: IconName;
label?: string;
size?: number;
}) {
return (
<span
{...props}
aria-hidden={label ? undefined : true}
aria-label={label}
className={["oai-icon", className].filter(Boolean).join(" ")}
role={label ? "img" : undefined}
style={
{
...style,
"--oai-icon-size": `${size}px`,
"--oai-icon-source": `url("${icons[name]}")`,
} as CSSProperties
}
/>
);
}
export function StatusIcon({
tone,
active = false,
size,
}: {
tone: string;
active?: boolean;
size?: number;
}) {
const name: IconName =
tone === "success" || tone === "complete"
? "check-md"
: ["danger", "failed", "blocked"].includes(tone)
? "close-medium"
: active
? "spinner"
: "info-sm";
return (
<Icon
className={active ? "ngs-spin" : undefined}
name={name}
size={size ?? (name === "check-md" ? 16 : 20)}
/>
);
}
SHA-256: 22ee71a10dbeb9ed7649d1536175e8db0990a785a4ffb1d52ff8f1c5fade680b