diff --git a/packages/panels/src/AvatarProviders/UiAvatarsProvider.php b/packages/panels/src/AvatarProviders/UiAvatarsProvider.php index 7cd18a40d7..72a33c0d5d 100644 --- a/packages/panels/src/AvatarProviders/UiAvatarsProvider.php +++ b/packages/panels/src/AvatarProviders/UiAvatarsProvider.php @@ -18,6 +18,8 @@ class UiAvatarsProvider implements Contracts\AvatarProvider ->map(fn (string $segment): string => filled($segment) ? mb_substr($segment, 0, 1) : '') ->join(' '); - return 'https://ui-avatars.com/api/?name=' . urlencode($name) . '&color=FFFFFF&background=' . urlencode(FilamentColor::getColor('gray')[950] ?? Color::Gray[950]); + $background = Color::convertToHex(FilamentColor::getColor('gray')[950] ?? Color::Gray[950]); + + return 'https://ui-avatars.com/api/?name=' . urlencode($name) . '&format=svg&color=FFFFFF&background=' . urlencode($background); } } diff --git a/packages/support/src/Colors/Color.php b/packages/support/src/Colors/Color.php index b8b92894a7..03f8ff0055 100644 --- a/packages/support/src/Colors/Color.php +++ b/packages/support/src/Colors/Color.php @@ -2,6 +2,8 @@ namespace Filament\Support\Colors; +use Illuminate\Support\Str; + class Color { public const Slate = [ @@ -478,6 +480,19 @@ class Color return "rgb({$red}, {$green}, {$blue})"; } + public static function convertToHex(string $color): string + { + if (str_starts_with($color, '#')) { + return Str::lower($color); + } + + $color = static::convertToRgb($color); + + [$red, $green, $blue] = sscanf($color, 'rgb(%d, %d, %d)'); + + return sprintf('#%02x%02x%02x', $red, $green, $blue); + } + public static function calculateContrastRatio(string $color1, string $color2): float { $color1 = str_replace(' ', '', static::convertToRgb($color1)); diff --git a/tests/src/Panels/Configuration/AvatarProviderTest.php b/tests/src/Panels/Configuration/AvatarProviderTest.php index f14b347ffe..1ea548c6b3 100644 --- a/tests/src/Panels/Configuration/AvatarProviderTest.php +++ b/tests/src/Panels/Configuration/AvatarProviderTest.php @@ -41,4 +41,5 @@ it('includes background color in the URL', function (): void { $url = $provider->get($user); expect($url)->toContain('background='); + expect($url)->toMatch('/background=%23([0-9a-f]{3}){1,2}$/'); }); diff --git a/tests/src/Support/ColorTest.php b/tests/src/Support/ColorTest.php index 358a42c948..7a3c2ceb05 100644 --- a/tests/src/Support/ColorTest.php +++ b/tests/src/Support/ColorTest.php @@ -122,6 +122,20 @@ it('converts an OKLCH color to RGB via `convertToRgb()`', function (): void { expect($result)->toStartWith('rgb('); }); +it('passes through a HEX color unchanged via `convertToHex()`', function (): void { + expect(Color::convertToHex('#ff0000'))->toBe('#ff0000'); +}); + +it('converts an RGB color to HEX via `convertToHex()`', function (): void { + expect(Color::convertToHex('rgb(255, 0, 0)'))->toBe('#ff0000'); +}); + +it('converts an OKLCH color to HEX via `convertToHex()`', function (): void { + $result = Color::convertToHex('oklch(0.637 0.237 25.331)'); + + expect($result)->toMatch('/^#[0-9a-f]{6}$/'); +}); + it('calculates a contrast ratio greater than 1 via `calculateContrastRatio()`', function (): void { $ratio = Color::calculateContrastRatio('#ffffff', '#000000');