ui(admin): solid env-colored circle in place of name-hash Avatar
All checks were successful
All checks were successful
Previous ring approach was too subtle against most env colors. Replace the DS Avatar with a purpose-built circle rendered in the environment's chosen color, showing 1–2 letter initials in white. Fills the full circle so the color reads at a glance from across the list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { useState, useMemo, useEffect } from 'react';
|
||||
import {
|
||||
Avatar,
|
||||
Badge,
|
||||
Button,
|
||||
Input,
|
||||
@@ -394,24 +393,50 @@ export default function EnvironmentsPage() {
|
||||
|
||||
// ── Env-colored Avatar ──────────────────────────────────────────────
|
||||
|
||||
// Custom circular initial badge filled with the environment's color. We don't
|
||||
// wrap the DS `Avatar` because it picks its background from a name hash with
|
||||
// no color override — we need the env color to be the dominant signal.
|
||||
const ENV_AVATAR_SIZES = { sm: 24, md: 28, lg: 40 } as const;
|
||||
const ENV_AVATAR_FONT = { sm: 10, md: 12, lg: 16 } as const;
|
||||
|
||||
function envInitials(displayName: string): string {
|
||||
const words = displayName.trim().split(/\s+/).filter(Boolean);
|
||||
if (words.length === 0) return '?';
|
||||
if (words.length === 1) return words[0].slice(0, 2).toUpperCase();
|
||||
return (words[0][0] + words[1][0]).toUpperCase();
|
||||
}
|
||||
|
||||
function EnvColoredAvatar({ name, color, size }: {
|
||||
name: string;
|
||||
color: string | null | undefined;
|
||||
size: 'sm' | 'md' | 'lg';
|
||||
}) {
|
||||
const ringWidth = size === 'lg' ? 3 : 2;
|
||||
const dimension = ENV_AVATAR_SIZES[size];
|
||||
const fontSize = ENV_AVATAR_FONT[size];
|
||||
return (
|
||||
<span
|
||||
aria-label={name}
|
||||
title={name}
|
||||
style={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: dimension,
|
||||
height: dimension,
|
||||
borderRadius: '50%',
|
||||
boxShadow: `0 0 0 ${ringWidth}px ${envColorVar(color)}`,
|
||||
// inner white gap so the ring reads as a distinct band, not a border
|
||||
outline: '1px solid var(--bg-surface)',
|
||||
outlineOffset: 0,
|
||||
background: envColorVar(color),
|
||||
color: '#fff',
|
||||
fontSize,
|
||||
fontWeight: 600,
|
||||
flexShrink: 0,
|
||||
// subtle border so the circle still reads on bg-surface when the env
|
||||
// color itself is very light (amber, green)
|
||||
border: '1px solid var(--border-subtle)',
|
||||
userSelect: 'none',
|
||||
textShadow: '0 1px 1px rgba(0,0,0,0.25)',
|
||||
}}
|
||||
>
|
||||
<Avatar name={name} size={size} />
|
||||
{envInitials(name)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user