feat(FN-2591): add Bedrock provider icon support
- Add a dedicated Bedrock SVG provider icon and provider token styling - Wire Bedrock provider aliases so provider detection resolves to the new icon key - Update usage indicator mapping so Bedrock usage providers render the correct icon - Expand ProviderIcon tests to cover Bedrock icon rendering and alias coverage
This commit is contained in:
@@ -155,6 +155,25 @@ function KimiIcon({ size, color, label = "Kimi" }: { size: number; color: string
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function BedrockIcon({ size, color, label = "Amazon Bedrock" }: { 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="bedrock-icon"
|
||||||
|
aria-label={label}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M.045 18.02c.072-.116.187-.124.348-.022 2.344 1.476 4.878 2.212 7.607 2.212 1.86 0 3.68-.398 5.453-1.198.386-.168.71-.298.972-.39.26-.092.478-.113.654-.06.176.052.263.2.263.443 0 .222-.12.453-.358.693-.96.962-2.16 1.71-3.592 2.242A12.126 12.126 0 0 1 7.297 23c-2.456 0-4.583-.665-6.378-1.992a.39.39 0 0 1-.098-.096c-.05-.078-.05-.156 0-.234zm6.609-3.26c0-.37.093-.665.282-.886.188-.222.43-.332.727-.332.282 0 .524.105.726.314.2.21.3.498.3.866v4.116c0 .382-.098.676-.294.882-.196.206-.436.31-.72.31-.294 0-.54-.108-.738-.324-.198-.216-.296-.506-.296-.868v-4.078h.014zm-2.986 2.3c0-.376.096-.672.288-.89.192-.216.434-.324.726-.324.292 0 .534.108.726.324.192.218.288.514.288.89v1.778c0 .376-.096.672-.288.89-.192.216-.434.324-.726.324-.292 0-.534-.108-.726-.324-.192-.218-.288-.514-.288-.89v-1.778zm-2.92 1.334c0-.36.09-.65.27-.868.18-.218.42-.328.722-.328s.544.11.73.328c.186.218.278.508.278.868v.444c0 .36-.092.65-.278.868-.186.218-.428.328-.73.328s-.542-.11-.722-.328c-.18-.218-.27-.508-.27-.868v-.444zM21.93 16.4c.804.456 1.39.87 1.758 1.242.368.372.552.7.552.984 0 .208-.102.37-.308.488-.206.118-.462.128-.768.032-.306-.096-.674-.316-1.104-.66a12.728 12.728 0 0 1-1.864-1.75c-1.592.644-3.342.966-5.25.966-1.354 0-2.604-.178-3.752-.534a8.103 8.103 0 0 1-.09-.032l.03.012c-.136-.048.056.022-.042-.014-.04-.016-.04-.016 0 0l.012.004-.012-.004c-.32-.122-.528-.222-.624-.3-.096-.078-.144-.178-.144-.3 0-.098.04-.186.122-.264.082-.078.19-.116.326-.116.076 0 .284.054.624.162 1.078.34 2.264.51 3.558.51 1.642 0 3.194-.286 4.658-.856a17.018 17.018 0 0 1-1.904-3.326c-.416-.94-.726-1.86-.93-2.758-.206-.898-.308-1.728-.308-2.49 0-.664.094-1.194.28-1.592.188-.396.456-.594.804-.594.2 0 .392.074.576.224.184.148.312.354.384.614.1.358.178.758.234 1.198.056.44.084.876.084 1.306 0 .898-.116 1.862-.348 2.894-.232 1.032-.614 2.11-1.146 3.234a16.217 16.217 0 0 0 1.916 1.694z"
|
||||||
|
fill={color}
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function XaiIcon({ size, color, label = "xAI" }: { size: number; color: string; label?: string }) {
|
function XaiIcon({ size, color, label = "xAI" }: { size: number; color: string; label?: string }) {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
@@ -297,6 +316,9 @@ const providerConfig: Record<
|
|||||||
moonshot: { component: KimiIcon, color: "var(--provider-kimi)" }, // Moonshot alias
|
moonshot: { component: KimiIcon, color: "var(--provider-kimi)" }, // Moonshot alias
|
||||||
"kimi-coding": { component: KimiIcon, color: "var(--provider-kimi)", label: "Kimi" }, // Kimi alias
|
"kimi-coding": { component: KimiIcon, color: "var(--provider-kimi)", label: "Kimi" }, // Kimi alias
|
||||||
|
|
||||||
|
bedrock: { component: BedrockIcon, color: "var(--provider-bedrock)" },
|
||||||
|
"amazon-bedrock": { component: BedrockIcon, color: "var(--provider-bedrock)", label: "Amazon Bedrock" },
|
||||||
|
|
||||||
xai: { component: XaiIcon, color: "var(--text)" },
|
xai: { component: XaiIcon, color: "var(--text)" },
|
||||||
grok: { component: XaiIcon, color: "var(--text)", label: "xAI" },
|
grok: { component: XaiIcon, color: "var(--text)", label: "xAI" },
|
||||||
|
|
||||||
|
|||||||
@@ -238,6 +238,9 @@ function getProviderIconKey(providerName: string): string {
|
|||||||
if (normalized.includes('kimi') || normalized.includes('moonshot')) {
|
if (normalized.includes('kimi') || normalized.includes('moonshot')) {
|
||||||
return 'kimi';
|
return 'kimi';
|
||||||
}
|
}
|
||||||
|
if (normalized.includes('bedrock') || normalized.includes('amazon')) {
|
||||||
|
return 'bedrock';
|
||||||
|
}
|
||||||
if (normalized.includes('xai') || normalized.includes('grok')) {
|
if (normalized.includes('xai') || normalized.includes('grok')) {
|
||||||
return 'xai';
|
return 'xai';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -437,4 +437,43 @@ describe("ProviderIcon", () => {
|
|||||||
// Verify the new crescent moon geometry: contains circle arc notation "a9 9"
|
// Verify the new crescent moon geometry: contains circle arc notation "a9 9"
|
||||||
expect(pathD).toContain("a9 9");
|
expect(pathD).toContain("a9 9");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("renders Bedrock brand icon for bedrock provider", () => {
|
||||||
|
render(<ProviderIcon provider="bedrock" />);
|
||||||
|
expect(screen.getByTestId("bedrock-icon")).toBeInTheDocument();
|
||||||
|
expect(screen.getByLabelText("Amazon Bedrock")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("applies provider-specific color for bedrock", () => {
|
||||||
|
render(<ProviderIcon provider="bedrock" />);
|
||||||
|
const icon = screen.getByTestId("bedrock-icon").parentElement;
|
||||||
|
expect(icon).toHaveStyle({ color: "var(--provider-bedrock)" });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("passes correct color to SVG fill for bedrock", () => {
|
||||||
|
render(<ProviderIcon provider="bedrock" />);
|
||||||
|
const svg = screen.getByTestId("bedrock-icon");
|
||||||
|
const paths = svg.querySelectorAll("path");
|
||||||
|
expect(paths.length).toBeGreaterThan(0);
|
||||||
|
expect(paths[0]).toHaveAttribute("fill", "var(--provider-bedrock)");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("normalizes Bedrock (capitalized) to bedrock", () => {
|
||||||
|
render(<ProviderIcon provider="Bedrock" />);
|
||||||
|
expect(screen.getByTestId("bedrock-icon")).toBeInTheDocument();
|
||||||
|
const wrapper = screen.getByTestId("bedrock-icon").parentElement;
|
||||||
|
expect(wrapper).toHaveAttribute("data-provider", "bedrock");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders Bedrock brand icon for amazon-bedrock alias", () => {
|
||||||
|
render(<ProviderIcon provider="amazon-bedrock" />);
|
||||||
|
expect(screen.getByTestId("bedrock-icon")).toBeInTheDocument();
|
||||||
|
expect(screen.getByLabelText("Amazon Bedrock")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("applies provider-specific color for amazon-bedrock alias", () => {
|
||||||
|
render(<ProviderIcon provider="amazon-bedrock" />);
|
||||||
|
const icon = screen.getByTestId("bedrock-icon").parentElement;
|
||||||
|
expect(icon).toHaveStyle({ color: "var(--provider-bedrock)" });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -169,6 +169,7 @@
|
|||||||
--provider-minimax: #e73562;
|
--provider-minimax: #e73562;
|
||||||
--provider-zai: #1a6dff;
|
--provider-zai: #1a6dff;
|
||||||
--provider-kimi: #6c5ce7;
|
--provider-kimi: #6c5ce7;
|
||||||
|
--provider-bedrock: #ff9900;
|
||||||
--provider-opencode: #38bdf8;
|
--provider-opencode: #38bdf8;
|
||||||
--provider-icon-contrast: var(--bg);
|
--provider-icon-contrast: var(--bg);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user