mirror of
https://github.com/OFFIS-ESC/constellation-analyzer
synced 2026-03-13 20:18:47 +00:00
Implements configurable shape variants for actor nodes, allowing visual differentiation of node types beyond just color. Features: - Five shape options: rectangle, circle, rounded rectangle, ellipse, pill - All shapes use pure CSS (border-radius) for consistent behavior - Auto-grow with content - Perfect shadow and selection/highlight effects - Proper React Flow handle alignment - Shape selector UI with visual previews - Migration logic for existing documents (defaults to rectangle) Shape characteristics: - Rectangle: Standard, general purpose - Circle: Round, for people and concepts - Rounded Rectangle: Soft edges, friendly appearance - Ellipse: Oval/horizontal, for processes and stages - Pill: Capsule, compact for tags and labels Technical approach: - Uses border-radius for all shapes (no clip-path) - Ensures boxShadow follows shape contours properly - Each shape component maintains consistent props interface - NodeShapeRenderer routes to appropriate shape component 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
53 lines
1.4 KiB
TypeScript
53 lines
1.4 KiB
TypeScript
import { ReactNode } from 'react';
|
|
|
|
interface PillShapeProps {
|
|
color: string;
|
|
borderColor: string;
|
|
textColor: string;
|
|
selected?: boolean;
|
|
isHighlighted?: boolean;
|
|
children: ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
/**
|
|
* PillShape - Capsule/pill node shape
|
|
*
|
|
* Best for: Tags, labels, flow elements, actions
|
|
* Characteristics: Fully rounded ends, compact, modern look
|
|
* Handles: Positioned at cardinal points (top, right, bottom, left) of bounding box
|
|
*/
|
|
const PillShape = ({
|
|
color,
|
|
borderColor,
|
|
textColor,
|
|
selected = false,
|
|
isHighlighted = false,
|
|
children,
|
|
className = '',
|
|
}: PillShapeProps) => {
|
|
const shadowStyle = selected
|
|
? `0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1), 0 0 0 3px ${color}40`
|
|
: isHighlighted
|
|
? `0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1), 0 0 0 3px ${color}80, 0 0 12px ${color}60`
|
|
: '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)';
|
|
|
|
return (
|
|
<div
|
|
className={`px-6 py-3 min-w-[120px] flex items-center justify-center transition-shadow duration-200 ${className}`}
|
|
style={{
|
|
backgroundColor: color,
|
|
borderWidth: '3px',
|
|
borderStyle: 'solid',
|
|
borderColor: borderColor,
|
|
color: textColor,
|
|
borderRadius: '999px',
|
|
boxShadow: shadowStyle,
|
|
}}
|
|
>
|
|
{children}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default PillShape;
|