mirror of
https://github.com/OFFIS-ESC/constellation-analyzer
synced 2026-01-26 23:43:40 +00:00
fix: improve minimized group label contrast and typography
Applied luminosity-based contrast color calculation to minimized group labels, matching the same accessibility approach used for actor nodes. Changes: - Added rgbToHex() helper to convert rgb/rgba colors to hex format - Import getContrastColor() from colorUtils - Calculate text color based on background luminosity - Apply calculated color to both label and subtitle Typography updates to match actor nodes: - Main label: text-base font-bold (was text-sm font-semibold) - Subtitle: text-xs font-medium with 0.7 opacity (was text-gray-600) - Both use dynamic textColor instead of fixed gray values Benefits: - ✅ Readable labels on both light and dark group backgrounds - ✅ Consistent typography between actor nodes and group nodes - ✅ Follows WCAG 2.0 luminance contrast standards - ✅ Professional appearance across all color choices The minimized group labels now automatically switch between white and black text based on the background color's luminosity, ensuring optimal readability in all cases. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
60748a2235
commit
f29c55a1b8
1 changed files with 27 additions and 2 deletions
|
|
@ -2,6 +2,21 @@ import { memo, useState, useMemo } from 'react';
|
|||
import { NodeProps, NodeResizer, useStore, Handle, Position } from '@xyflow/react';
|
||||
import type { Group } from '../../types';
|
||||
import type { Actor } from '../../types';
|
||||
import { getContrastColor } from '../../utils/colorUtils';
|
||||
|
||||
/**
|
||||
* Helper function to convert rgb/rgba color string to hex
|
||||
*/
|
||||
const rgbToHex = (rgb: string): string => {
|
||||
const match = rgb.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*[\d.]+)?\)/);
|
||||
if (!match) return '#000000';
|
||||
|
||||
const r = parseInt(match[1]).toString(16).padStart(2, '0');
|
||||
const g = parseInt(match[2]).toString(16).padStart(2, '0');
|
||||
const b = parseInt(match[3]).toString(16).padStart(2, '0');
|
||||
|
||||
return `#${r}${g}${b}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* GroupNode - Simple label overlay for React Flow's native group nodes
|
||||
|
|
@ -91,6 +106,10 @@ const GroupNode = ({ id, data, selected }: NodeProps<Group>) => {
|
|||
? data.color.replace(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*[\d.]+)?\)/, 'rgb($1, $2, $3)')
|
||||
: '#f0f2f5';
|
||||
|
||||
// Calculate contrast color for text based on background
|
||||
const hexColor = rgbToHex(solidColor);
|
||||
const textColor = getContrastColor(hexColor);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="group-minimized"
|
||||
|
|
@ -175,10 +194,16 @@ const GroupNode = ({ id, data, selected }: NodeProps<Group>) => {
|
|||
textAlign: 'center',
|
||||
}}
|
||||
>
|
||||
<div className="text-sm font-semibold text-gray-800 leading-tight">
|
||||
<div
|
||||
className="text-base font-bold leading-tight"
|
||||
style={{ color: textColor }}
|
||||
>
|
||||
{data.label}
|
||||
</div>
|
||||
<div className="text-xs text-gray-600 mt-1.5">
|
||||
<div
|
||||
className="text-xs font-medium leading-tight mt-1.5"
|
||||
style={{ color: textColor, opacity: 0.7 }}
|
||||
>
|
||||
{data.actorIds.length} actor{data.actorIds.length !== 1 ? 's' : ''}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue