From 5fae7752f2785aea1db720a82f2af2b840204324 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Wed, 24 Dec 2025 10:32:39 +0700 Subject: [PATCH] feat(FE): Add status indicator to Badge and use theme types --- src/components/Badge.tsx | 48 ++++++++++++++++++++++++++++------------ src/types/theme.d.ts | 2 ++ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/components/Badge.tsx b/src/components/Badge.tsx index 5dc5022d..821aae42 100644 --- a/src/components/Badge.tsx +++ b/src/components/Badge.tsx @@ -3,29 +3,25 @@ import { HTMLAttributes, ReactNode } from 'react'; import { cn } from '@/lib/helper'; +import type { Color, Variant, Size } from '@/types/theme'; export interface BadgeProps extends Omit, 'className'> { children?: ReactNode; className?: { badge?: string; + status?: string; }; - variant?: 'default' | 'outline' | 'ghost' | 'soft' | 'dash'; - color?: - | 'neutral' - | 'primary' - | 'secondary' - | 'accent' - | 'info' - | 'success' - | 'warning' - | 'error'; - size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'; + statusIndicator?: boolean; + variant?: Variant; + color?: Color; + size?: Size; } const Badge = ({ children, className, + statusIndicator = false, variant = 'default', color, size = 'md', @@ -34,7 +30,7 @@ const Badge = ({ const getBadgeClasses = () => { const baseClasses = 'badge'; - const variantClasses = { + const variantClasses: Record = { default: '', outline: 'badge-outline', ghost: 'badge-ghost', @@ -42,7 +38,7 @@ const Badge = ({ dash: 'badge-dash', }; - const colorClasses = { + const colorClasses: Record = { neutral: 'badge-neutral', primary: 'badge-primary', secondary: 'badge-secondary', @@ -51,9 +47,10 @@ const Badge = ({ success: 'badge-success', warning: 'badge-warning', error: 'badge-error', + none: '', }; - const sizeClasses = { + const sizeClasses: Record = { xs: 'badge-xs', sm: 'badge-sm', md: 'badge-md', @@ -70,8 +67,31 @@ const Badge = ({ ); }; + const getStatusClasses = () => { + if (!statusIndicator) return ''; + + const statusIndicatorClasses: Record = { + neutral: 'bg-neutral', + primary: 'bg-primary', + secondary: 'bg-secondary', + accent: 'bg-accent', + info: 'bg-info', + success: 'bg-success', + warning: 'bg-warning', + error: 'bg-error', + none: '', + }; + + return cn( + 'w-2.5 h-2.5 rounded-full', + color && statusIndicatorClasses[color], + className?.status + ); + }; + return ( + {statusIndicator && } {children} ); diff --git a/src/types/theme.d.ts b/src/types/theme.d.ts index dcd9e13f..64413d8d 100644 --- a/src/types/theme.d.ts +++ b/src/types/theme.d.ts @@ -9,4 +9,6 @@ export type Color = | 'error' | 'none'; +export type Variant = 'default' | 'outline' | 'ghost' | 'soft' | 'dash'; + export type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl';