feat: add avatar border color customization and improve text contrast across user profile components

This commit is contained in:
2026-03-12 23:08:05 +11:00
parent 67f3ae4d34
commit 37f4297972
8 changed files with 127 additions and 48 deletions

View File

@@ -139,6 +139,32 @@ export const splitWithSpace = (content: string): string[] => {
return trimmedContent.split(' ');
};
/**
* Strip alpha channel from a color, returning a fully opaque hex color
* Supports: #RGB, #RGBA, #RRGGBB, #RRGGBBAA, rgb(), rgba()
*/
export const stripAlphaFromColor = (color: string): string => {
// Handle rgba() format
const rgbaMatch = color.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);
if (rgbaMatch) {
const r = parseInt(rgbaMatch[1], 10).toString(16).padStart(2, '0');
const g = parseInt(rgbaMatch[2], 10).toString(16).padStart(2, '0');
const b = parseInt(rgbaMatch[3], 10).toString(16).padStart(2, '0');
return `#${r}${g}${b}`.toUpperCase();
}
// Handle hex format
let hex = color.replace('#', '');
// Convert shorthand #RGB or #RGBA to full form
if (hex.length === 3 || hex.length === 4) {
hex = hex.split('').map(c => c + c).join('');
}
// Take only the first 6 characters (RGB), ignore alpha if present
return `#${hex.substring(0, 6).toUpperCase()}`;
};
/**
* Calculate contrasting text color (black or white) for a given background color
* @param bgColor - Hex color string (e.g., '#RRGGBB' or '#RRGGBBAA')
@@ -159,3 +185,24 @@ export const getContrastingTextColor = (bgColor: string): string => {
// Return black for light backgrounds, white for dark backgrounds
return luminance > 0.5 ? '#000000' : '#FFFFFF';
};
/**
* Calculate shadow color for text - white shadow only for very dark text
* @param textColor - Hex color string (e.g., '#RRGGBB')
* @returns '#FFFFFF' only for very dark text (close to black), '#000000' otherwise
*/
export const getTextShadowColor = (textColor: string): string => {
// Remove # if present
const hex = textColor.replace('#', '');
// Parse RGB values (ignore alpha if present)
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
// Calculate relative luminance using WCAG formula
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
// Return white shadow only for very dark text (luminance < 0.2)
return luminance < 0.2 ? '#FFFFFF' : '#000000';
};