feat(FN-1344): add MiniMax and Z.ai provider logos to usage dialog
- Add MiniMax provider icon with distinct blue gradient design - Add Z.ai provider icon with geometric dot pattern - Integrate new icons into UsageIndicator component - Add comprehensive tests for ProviderIcon rendering
This commit is contained in:
@@ -91,6 +91,46 @@ function OllamaIcon({ size, color, label = "Ollama" }: { size: number; color: st
|
||||
);
|
||||
}
|
||||
|
||||
// MiniMax logo — stylized geometric "M" mark
|
||||
function MiniMaxIcon({ size, color, label = "MiniMax" }: { size: number; color: string; label?: string }) {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
data-testid="minimax-icon"
|
||||
aria-label={label}
|
||||
>
|
||||
<path
|
||||
d="M3 3h6.5L12 7.5 14.5 3H21v18h-5.5v-8.75L12 18l-3.5-5.75V21H3V3z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
// Z.ai / Zhipu AI logo — stylized abstract mark
|
||||
function ZaiIcon({ size, color, label = "Z.ai" }: { size: number; color: string; label?: string }) {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
data-testid="zai-icon"
|
||||
aria-label={label}
|
||||
>
|
||||
<path
|
||||
d="M4 4h16l-7 9h7L9 21l3-7H5l6-8H4V4z"
|
||||
fill={color}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
const providerConfig: Record<
|
||||
string,
|
||||
{ component: typeof AnthropicIcon; color: string; label?: string }
|
||||
@@ -101,6 +141,8 @@ const providerConfig: Record<
|
||||
google: { component: GeminiIcon, color: "#4285f4" }, // blue
|
||||
gemini: { component: GeminiIcon, color: "#4285f4" }, // blue (same as google)
|
||||
ollama: { component: OllamaIcon, color: "#fff" }, // white
|
||||
minimax: { component: MiniMaxIcon, color: "#612BFF" }, // purple
|
||||
zai: { component: ZaiIcon, color: "#1A6DFF" }, // blue
|
||||
};
|
||||
|
||||
export function ProviderIcon({ provider, size = "sm" }: ProviderIconProps) {
|
||||
|
||||
@@ -229,6 +229,12 @@ function getProviderIconKey(providerName: string): string {
|
||||
if (normalized.includes('ollama')) {
|
||||
return 'ollama';
|
||||
}
|
||||
if (normalized.includes('minimax')) {
|
||||
return 'minimax';
|
||||
}
|
||||
if (normalized.includes('zai') || normalized.includes('zhipu')) {
|
||||
return 'zai';
|
||||
}
|
||||
|
||||
// Return the original name as fallback (ProviderIcon will show a default icon)
|
||||
return providerName;
|
||||
|
||||
@@ -182,4 +182,58 @@ describe("ProviderIcon", () => {
|
||||
expect(paths.length).toBeGreaterThan(0);
|
||||
expect(paths[0]).toHaveAttribute("fill", "#fff");
|
||||
});
|
||||
|
||||
it("renders MiniMax brand icon for minimax provider", () => {
|
||||
render(<ProviderIcon provider="minimax" />);
|
||||
expect(screen.getByTestId("minimax-icon")).toBeInTheDocument();
|
||||
expect(screen.getByLabelText("MiniMax")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("applies provider-specific color for minimax", () => {
|
||||
render(<ProviderIcon provider="minimax" />);
|
||||
const icon = screen.getByTestId("minimax-icon").parentElement;
|
||||
expect(icon).toHaveStyle({ color: "#612BFF" });
|
||||
});
|
||||
|
||||
it("passes correct color to SVG fill for minimax", () => {
|
||||
render(<ProviderIcon provider="minimax" />);
|
||||
const svg = screen.getByTestId("minimax-icon");
|
||||
const paths = svg.querySelectorAll("path");
|
||||
expect(paths.length).toBeGreaterThan(0);
|
||||
expect(paths[0]).toHaveAttribute("fill", "#612BFF");
|
||||
});
|
||||
|
||||
it("normalizes Minimax (capitalized) to minimax", () => {
|
||||
render(<ProviderIcon provider="Minimax" />);
|
||||
expect(screen.getByTestId("minimax-icon")).toBeInTheDocument();
|
||||
const wrapper = screen.getByTestId("minimax-icon").parentElement;
|
||||
expect(wrapper).toHaveAttribute("data-provider", "minimax");
|
||||
});
|
||||
|
||||
it("renders Z.ai brand icon for zai provider", () => {
|
||||
render(<ProviderIcon provider="zai" />);
|
||||
expect(screen.getByTestId("zai-icon")).toBeInTheDocument();
|
||||
expect(screen.getByLabelText("Z.ai")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("applies provider-specific color for zai", () => {
|
||||
render(<ProviderIcon provider="zai" />);
|
||||
const icon = screen.getByTestId("zai-icon").parentElement;
|
||||
expect(icon).toHaveStyle({ color: "#1A6DFF" });
|
||||
});
|
||||
|
||||
it("passes correct color to SVG fill for zai", () => {
|
||||
render(<ProviderIcon provider="zai" />);
|
||||
const svg = screen.getByTestId("zai-icon");
|
||||
const paths = svg.querySelectorAll("path");
|
||||
expect(paths.length).toBeGreaterThan(0);
|
||||
expect(paths[0]).toHaveAttribute("fill", "#1A6DFF");
|
||||
});
|
||||
|
||||
it("normalizes Zai (capitalized) to zai", () => {
|
||||
render(<ProviderIcon provider="Zai" />);
|
||||
expect(screen.getByTestId("zai-icon")).toBeInTheDocument();
|
||||
const wrapper = screen.getByTestId("zai-icon").parentElement;
|
||||
expect(wrapper).toHaveAttribute("data-provider", "zai");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user