46 lines
952 B
TypeScript
46 lines
952 B
TypeScript
import React from 'react';
|
|
import { clsx, type ClassValue } from 'clsx';
|
|
import { twMerge } from 'tailwind-merge';
|
|
|
|
function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs));
|
|
}
|
|
|
|
type Status = 'online' | 'offline' | 'busy' | 'away';
|
|
|
|
interface StatusDotProps {
|
|
status: Status;
|
|
size?: 'sm' | 'md' | 'lg';
|
|
pulse?: boolean;
|
|
}
|
|
|
|
const statusColors: Record<Status, string> = {
|
|
online: 'bg-green-500',
|
|
offline: 'bg-gray-400',
|
|
busy: 'bg-red-500',
|
|
away: 'bg-yellow-500',
|
|
};
|
|
|
|
const sizeClasses: Record<'sm' | 'md' | 'lg', string> = {
|
|
sm: 'w-1.5 h-1.5',
|
|
md: 'w-2 h-2',
|
|
lg: 'w-3 h-3',
|
|
};
|
|
|
|
export default function StatusDot({
|
|
status,
|
|
size = 'md',
|
|
pulse = false
|
|
}: StatusDotProps) {
|
|
return (
|
|
<span
|
|
className={cn(
|
|
'rounded-full inline-block',
|
|
statusColors[status],
|
|
sizeClasses[size],
|
|
pulse && status === 'online' && 'animate-pulse'
|
|
)}
|
|
aria-hidden="true"
|
|
/>
|
|
);
|
|
} |