mirror of
https://github.com/coder/coder.git
synced 2026-10-16 14:48:56 +08:00
chore(site): add OpenRouter provider icon (#29558)
## Problem OpenRouter is a supported provider type (AI Bridge, AI settings, model selectors), but it had no icon. Everywhere else shows a provider logo, OpenRouter fell back to the generic `Building2` glyph (or a question mark in AI Bridge), which looks like a broken or unknown provider. ## Fix Added the OpenRouter logo from [Simple Icons](https://github.com/simple-icons/simple-icons/blob/develop/icons/openrouter.svg) and wired it into both provider icon maps. | File | Change | |---|---| | `site/static/icon/openrouter.svg` | New asset, path coordinates baked into the repo's 256x256 viewBox with a white fill, matching `anthropic.svg` | | `site/src/modules/aiModels/ProviderIcon.tsx` | Map `openrouter` to the new icon | | `site/src/pages/AIBridgePage/icons/AIBridgeProviderIcon.tsx` | Same mapping for the AI Bridge provider icon | | `site/src/theme/externalImages.ts` | Register as `monochrome` so it adapts to light and dark themes | | `site/src/theme/icons.json` | Regenerated with `make site/src/theme/icons.json` | | `site/src/modules/aiModels/ProviderIcon.stories.tsx` | Add an `OpenRouter` story, drop OpenRouter from the fallback comment | Provider labels already existed in `formatProviderLabel` and `addableProviderTypes`, so only the icon was missing. ## Validation - Rendered the icon in headless Chromium on dark and light backgrounds with the light-theme monochrome filter applied, to confirm geometry and contrast. - Audited all 148 icons in `site/static/icon`: every one uses a `0 0 256 256` viewBox, and 145 now carry baked coordinates with no geometry transform. The upstream 24x24 path was scaled into 256 space so this icon follows that convention rather than relying on a wrapper `scale()`. The baked version renders byte-identical to the transform-based version. - `pnpm exec tsc --noEmit`: clean - `pnpm exec biome check` on the touched directories: clean - `pnpm exec vitest run --project unit src/modules/aiModels src/pages/AIBridgePage/utils.test.ts`: 185 passed > 🤖 This PR was created with the help of Coder Agents, and needs a human review. 🧑💻
This commit is contained in:
@@ -51,8 +51,14 @@ export const Vercel: Story = {
|
||||
},
|
||||
};
|
||||
|
||||
// Provider types without a bundled icon (openai-compat, openrouter, or
|
||||
// anything we don't recognize) render the generic Building2 glyph.
|
||||
export const OpenRouter: Story = {
|
||||
args: {
|
||||
provider: "openrouter",
|
||||
},
|
||||
};
|
||||
|
||||
// Provider types without a bundled icon (openai-compat or anything we don't
|
||||
// recognize) render the generic Building2 glyph.
|
||||
export const Fallback: Story = {
|
||||
args: {
|
||||
provider: "openai-compat",
|
||||
|
||||
@@ -26,6 +26,8 @@ export const getProviderIcon = (provider: string): string | undefined => {
|
||||
return "/icon/vercel.svg";
|
||||
case "gemini":
|
||||
return "/icon/gemini.svg";
|
||||
case "openrouter":
|
||||
return "/icon/openrouter.svg";
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,13 @@ export const AIBridgeProviderIcon = ({
|
||||
className={cn(iconClassName, className)}
|
||||
/>
|
||||
);
|
||||
case "openrouter":
|
||||
return (
|
||||
<ExternalImage
|
||||
src="/icon/openrouter.svg"
|
||||
className={cn(iconClassName, className)}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<CircleQuestionMarkIcon
|
||||
|
||||
@@ -179,6 +179,7 @@ export const defaultParametersForBuiltinIcons = new Map<string, string>([
|
||||
["/icon/okta.svg", "monochrome"],
|
||||
["/icon/openai-codex.svg", "monochrome"],
|
||||
["/icon/openai.svg", "monochrome"],
|
||||
["/icon/openrouter.svg", "monochrome"],
|
||||
["/icon/openwebui.svg", "monochrome"],
|
||||
["/icon/perplexica.svg", "monochrome"],
|
||||
["/icon/roo-code.svg", "whiteWithColor"],
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
"openai-codex.svg",
|
||||
"openai.svg",
|
||||
"opencode.svg",
|
||||
"openrouter.svg",
|
||||
"openwebui.svg",
|
||||
"perplexica.svg",
|
||||
"personalize.svg",
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg width="256" height="256" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M178.965 19.669v20.469q-6.069-0.277-12.139-0.341-7.552-0.085-15.093 0.395c-20.587 1.344-42.912 7.765-65.589 23.861-31.051 22.037-29.131 20.8-44.16 29.333-4.224 2.379-14.315 6.123-23.307 8.512-8.971 2.4-18.699 3.552-18.677 3.552v45.109s8.192 1.152 17.173 3.552c8.981 2.389 19.083 6.133 23.307 8.523 15.04 8.512 13.099 7.285 44.16 29.333 22.677 16.096 45.013 22.507 65.579 23.851 9.387 0.619 18.304 0.437 27.253 0.053v20.459l77.035-44.459-77.035-44.48v23.211c-9.173 0.405-17.184 0.693-24.299 0.224-14.549-0.96-25.781-3.808-42.443-15.627-23.936-16.992-30.571-21.621-39.253-26.752 9.483-5.525 15.456-9.664 40.768-27.627 16.64-11.829 27.883-14.688 42.432-15.637 7.115-0.469 15.125-0.181 24.299 0.213v23.211L256 64.149Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 846 B |
Reference in New Issue
Block a user