Files
web-ui/src/components/Chip.tsx
Beatrice Dellacà 6ba98fa6b6
All checks were successful
continuous-integration/drone/push Build is passing
fix build
2026-02-23 13:56:52 +01:00

66 lines
2.0 KiB
TypeScript

import * as tailwindColors from 'tailwindcss/colors';
import type { CSSProperties, ElementType, ReactNode } from 'react';
type ChipVariant = 'solid' | 'outlined';
type ChipProps<T extends ElementType> = {
variant?: ChipVariant;
// Tailwind color token, e.g. "cyan-700", "indigo-500", "rose-600".
tone?: string;
as?: T;
className?: string;
children: ReactNode;
};
const variantClassMap: Record<ChipVariant, string> = {
solid: 'chip-solid',
outlined: 'chip-outlined'
};
type TailwindPalette = Record<string, string>;
function resolveTailwindToneColor(tone: string | undefined): string | null {
const normalizedTone = tone?.trim().toLowerCase();
if (normalizedTone == null || normalizedTone === '') {
return null;
}
const colorSource = tailwindColors as unknown as Record<string, unknown>;
const lastDashIndex = normalizedTone.lastIndexOf('-');
if (lastDashIndex === -1) {
const direct = colorSource[normalizedTone];
return typeof direct === 'string' ? direct : null;
}
const colorName = normalizedTone.slice(0, lastDashIndex);
const shade = normalizedTone.slice(lastDashIndex + 1);
const palette = colorSource[colorName];
if (palette == null || typeof palette !== 'object') {
return null;
}
const shadeColor = (palette as TailwindPalette)[shade];
return typeof shadeColor === 'string' ? shadeColor : null;
}
export function Chip<T extends ElementType = 'span'>({
variant = 'solid',
tone,
as,
className = '',
children
}: Readonly<ChipProps<T>>) {
const Component = as ?? 'span' as ElementType;
const toneColor = resolveTailwindToneColor(tone);
const toneStyle: CSSProperties | undefined = toneColor == null
? undefined
: variant === 'solid'
? { borderColor: toneColor, backgroundColor: toneColor, color: '#ffffff' }
: { borderColor: toneColor, color: toneColor };
const classes = `chip-root ${variantClassMap[variant]} ${className}`.trim();
return <Component className={classes} style={toneStyle}>{children}</Component>;
}