From 0c8c226acbae568074e20ac3550ac613872d40b5 Mon Sep 17 00:00:00 2001 From: masnwilliams <43387599+masnwilliams@users.noreply.github.com> Date: Tue, 12 May 2026 20:34:01 +0000 Subject: [PATCH] auto-resolve sso provider icons via simple icons cdn --- .../src/components/icons.tsx | 52 ------------ .../src/components/sso-provider.tsx | 82 +++++++++++-------- .../managed-auth-react/src/styles/styles.css | 12 +++ 3 files changed, 62 insertions(+), 84 deletions(-) diff --git a/packages/managed-auth-react/src/components/icons.tsx b/packages/managed-auth-react/src/components/icons.tsx index a9a368d..1624e75 100644 --- a/packages/managed-auth-react/src/components/icons.tsx +++ b/packages/managed-auth-react/src/components/icons.tsx @@ -198,55 +198,3 @@ export const SpinnerIcon = (p: IconProps) => ( /> ); - -// SSO provider marks -export const GoogleMark = (p: IconProps) => ( - -); - -export const GitHubMark = (p: IconProps) => ( - -); - -export const MicrosoftMark = (p: IconProps) => ( - -); - -export const FacebookMark = (p: IconProps) => ( - -); - -export const AppleMark = (p: IconProps) => ( - -); diff --git a/packages/managed-auth-react/src/components/sso-provider.tsx b/packages/managed-auth-react/src/components/sso-provider.tsx index 87a2421..d82c32b 100644 --- a/packages/managed-auth-react/src/components/sso-provider.tsx +++ b/packages/managed-auth-react/src/components/sso-provider.tsx @@ -1,40 +1,58 @@ -import type { ReactNode } from "react"; -import { - AppleMark, - BuildingIcon, - FacebookMark, - GitHubMark, - GoogleMark, - KeyIcon, - MicrosoftMark, -} from "./icons"; +import { useState, type ReactNode } from "react"; +import { BuildingIcon, KeyIcon } from "./icons"; export interface SSOProviderInfo { label: string; icon: ReactNode; } +const NON_BRAND_ICONS: Record = { + passkey: { label: "Passkey", icon: }, + sso: { label: "SSO", icon: }, + saml: { label: "SSO", icon: }, +}; + +function slugify(provider: string): string { + return provider.toLowerCase().replace(/[^a-z0-9]/g, ""); +} + +function titleCase(provider: string): string { + return provider + .split(/[\s_-]+/) + .filter(Boolean) + .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()) + .join(" "); +} + +function SSOProviderIcon({ provider }: { provider: string }) { + const [errored, setErrored] = useState(false); + const slug = slugify(provider); + const letter = provider.trim().charAt(0).toUpperCase() || "?"; + + if (!slug || errored) { + return ( + + ); + } + + return ( + setErrored(true)} + /> + ); +} + export function getSSOProviderInfo(provider: string): SSOProviderInfo { - const p = provider.toLowerCase(); - if (p.includes("google")) - return { label: "Google", icon: }; - if (p.includes("github")) - return { label: "GitHub", icon: }; - if (p.includes("microsoft") || p.includes("azure")) - return { - label: "Microsoft", - icon: , - }; - if (p.includes("facebook")) - return { - label: "Facebook", - icon: , - }; - if (p.includes("apple")) - return { label: "Apple", icon: }; - if (p.includes("saml") || p.includes("sso")) - return { label: "SSO", icon: }; - if (p.includes("passkey")) - return { label: "Passkey", icon: }; - return { label: provider, icon: null }; + const key = slugify(provider); + const nonBrand = NON_BRAND_ICONS[key]; + if (nonBrand) return nonBrand; + return { + label: titleCase(provider), + icon: , + }; } diff --git a/packages/managed-auth-react/src/styles/styles.css b/packages/managed-auth-react/src/styles/styles.css index ff3a2d5..c871c5e 100644 --- a/packages/managed-auth-react/src/styles/styles.css +++ b/packages/managed-auth-react/src/styles/styles.css @@ -510,6 +510,18 @@ height: 1.25rem; } +.kma-sso-icon--letter { + display: inline-flex; + align-items: center; + justify-content: center; + border-radius: 50%; + background: var(--kma-color-muted, #6b7280); + color: #fff; + font-size: 0.75rem; + font-weight: 600; + line-height: 1; +} + /* ---------- Form / Input ---------- */ .kma-form {