@@ -7,6 +7,10 @@ import { Color } from 'three';
77import type { NodeRendererProps } from '../../types' ;
88import { animationConfig } from '../../utils' ;
99
10+ // Layout constants
11+ const CHAR_WIDTH_ESTIMATE = 0.15 ;
12+ const ICON_TEXT_GAP = 0.15 ;
13+
1014export type BadgePosition =
1115 | 'top-right'
1216 | 'top-left'
@@ -74,6 +78,10 @@ export interface BadgeProps extends NodeRendererProps {
7478
7579 /**
7680 * Position of the icon relative to the text or custom coordinates [x, y].
81+ * - 'start': Icon appears before the text (left side)
82+ * - 'end': Icon appears after the text (right side)
83+ * - [x, y]: Custom coordinates within the badge. When using custom coordinates,
84+ * the text remains centered and only the icon moves to the specified position.
7785 */
7886 iconPosition ?: IconPosition | [ number , number ] ;
7987}
@@ -141,7 +149,7 @@ export const Badge: FC<BadgeProps> = ({
141149 const charCount = label . length ;
142150 let estimatedWidth = Math . max (
143151 minWidth ,
144- Math . min ( charCount * 0.15 + padding , 2.0 + padding )
152+ Math . min ( charCount * CHAR_WIDTH_ESTIMATE + padding , 2.0 + padding )
145153 ) ; // Add padding to width
146154
147155 // Add icon width if icon is present
@@ -196,21 +204,22 @@ export const Badge: FC<BadgeProps> = ({
196204 } ;
197205 }
198206
199- const totalContentWidth = iconSize + ( label . length * 0.15 ) ;
207+ const estimatedTextWidth = label . length * CHAR_WIDTH_ESTIMATE ;
208+ const totalContentWidth = iconSize + estimatedTextWidth ;
200209 const startX = - totalContentWidth / 2 ;
201210
202211 if ( iconPosition === 'start' ) {
203212 return {
204213 iconX : startX + iconSize - 0.5 / 2 ,
205214 iconY : 0 ,
206- textX : startX + iconSize + ( label . length * 0.15 ) / 2 ,
215+ textX : startX + iconSize + estimatedTextWidth / 2 ,
207216 textY : 0
208217 } ;
209218 } else {
210219 return {
211- textX : startX + ( label . length * 0.15 ) / 2 ,
220+ textX : startX + estimatedTextWidth / 2 ,
212221 textY : 0 ,
213- iconX : startX + ( label . length * 0.15 ) + 0.15 + iconSize / 2 ,
222+ iconX : startX + estimatedTextWidth + ICON_TEXT_GAP + iconSize / 2 ,
214223 iconY : 0
215224 } ;
216225 }
0 commit comments