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 { useState, useMemo, useEffect } from 'react';
|
||||||
import {
|
import {
|
||||||
Avatar,
|
|
||||||
Badge,
|
Badge,
|
||||||
Button,
|
Button,
|
||||||
Input,
|
Input,
|
||||||
@@ -394,24 +393,50 @@ export default function EnvironmentsPage() {
|
|||||||
|
|
||||||
// ── Env-colored Avatar ──────────────────────────────────────────────
|
// ── 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 }: {
|
function EnvColoredAvatar({ name, color, size }: {
|
||||||
name: string;
|
name: string;
|
||||||
color: string | null | undefined;
|
color: string | null | undefined;
|
||||||
size: 'sm' | 'md' | 'lg';
|
size: 'sm' | 'md' | 'lg';
|
||||||
}) {
|
}) {
|
||||||
const ringWidth = size === 'lg' ? 3 : 2;
|
const dimension = ENV_AVATAR_SIZES[size];
|
||||||
|
const fontSize = ENV_AVATAR_FONT[size];
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
|
aria-label={name}
|
||||||
|
title={name}
|
||||||
style={{
|
style={{
|
||||||
display: 'inline-flex',
|
display: 'inline-flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
width: dimension,
|
||||||
|
height: dimension,
|
||||||
borderRadius: '50%',
|
borderRadius: '50%',
|
||||||
boxShadow: `0 0 0 ${ringWidth}px ${envColorVar(color)}`,
|
background: envColorVar(color),
|
||||||
// inner white gap so the ring reads as a distinct band, not a border
|
color: '#fff',
|
||||||
outline: '1px solid var(--bg-surface)',
|
fontSize,
|
||||||
outlineOffset: 0,
|
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>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user