@@ -43,6 +43,11 @@ const sizeClasses: Record<BadgeSize, string> = {
4343 md : "px-3.5 py-1 text-sm" ,
4444} ;
4545
46+ const iconSizeClasses : Record < BadgeSize , string > = {
47+ sm : "w-3 h-3" ,
48+ md : "w-4 h-4" ,
49+ } ;
50+
4651const interactiveClasses =
4752 "focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-current disabled:cursor-not-allowed disabled:opacity-60" ;
4853
@@ -62,87 +67,34 @@ const getBadgeClasses = (
6267 . filter ( Boolean )
6368 . join ( " " ) ;
6469
65- const renderBadgeContent = (
66- icon : React . ReactNode ,
67- children : React . ReactNode ,
68- label ?: string
69- ) => {
70- const content = children ?? label ;
71-
72- return (
73- < span
74- className = { `inline-flex items-center gap-1.5 rounded-full font-medium transition-colors ${ variantClasses [ variant ] } ${ sizeClasses [ size ] } ` }
75- >
76- { icon && < span className = "flex-shrink-0" > { icon } </ span > }
77- { content }
78- </ >
79- ) ;
80- } ;
81-
8270const Badge = ( props : BadgeProps ) => {
83- if ( props . as === "button" ) {
84- const {
85- as : Component ,
86- label,
87- children,
88- variant = "default" ,
89- size = "md" ,
90- icon,
91- className,
92- type = "button" ,
93- ...buttonProps
94- } = props ;
95-
96- return (
97- < Component
98- type = { type }
99- className = { getBadgeClasses ( variant , size , true , className ) }
100- { ...buttonProps }
101- >
102- { renderBadgeContent ( icon , children , label ) }
103- </ Component >
104- ) ;
105- }
106-
107- if ( props . as === "a" ) {
108- const {
109- as : Component ,
110- label,
111- children,
112- variant = "default" ,
113- size = "md" ,
114- icon,
115- className,
116- ...anchorProps
117- } = props ;
118-
119- return (
120- < Component
121- className = { getBadgeClasses ( variant , size , true , className ) }
122- { ...anchorProps }
123- >
124- { renderBadgeContent ( icon , children , label ) }
125- </ Component >
126- ) ;
127- }
128-
12971 const {
13072 as : Component = "span" ,
13173 label,
13274 children,
13375 variant = "default" ,
13476 size = "md" ,
13577 icon,
136- className,
137- ...spanProps
138- } = props ;
78+ className = "" ,
79+ ...restProps
80+ } = props as BadgeSpanProps & BadgeButtonProps & BadgeAnchorProps ;
81+
82+ const isInteractive = Component === "button" || Component === "a" ;
13983
14084 return (
14185 < Component
142- className = { getBadgeClasses ( variant , size , false , className ) }
143- { ...spanProps }
86+ className = { getBadgeClasses ( variant , size , isInteractive , className ) }
87+ { ...restProps }
14488 >
145- { renderBadgeContent ( icon , children , label ) }
89+ { icon && (
90+ < span
91+ className = { `inline-flex items-center justify-center shrink-0 text-current ${ iconSizeClasses [ size ] } ` }
92+ aria-hidden = "true"
93+ >
94+ { icon }
95+ </ span >
96+ ) }
97+ { children ?? label }
14698 </ Component >
14799 ) ;
148100} ;
0 commit comments