@@ -151,6 +151,7 @@ export default function Hero() {
151151 const [ autoHoverIndex , setAutoHoverIndex ] = React . useState ( 1 )
152152 const [ isUserHovering , setIsUserHovering ] = React . useState ( false )
153153 const [ lastHoveredIndex , setLastHoveredIndex ] = React . useState < number | null > ( null )
154+ const [ selectedIconIndex , setSelectedIconIndex ] = React . useState < number | null > ( null )
154155 const intervalRef = React . useRef < NodeJS . Timeout | null > ( null )
155156
156157 const iconRowRef = React . useRef < HTMLDivElement | null > ( null )
@@ -166,7 +167,12 @@ export default function Hero() {
166167 /**
167168 * Handle service icon click to populate textarea with template
168169 */
169- const handleServiceClick = ( service : keyof typeof SERVICE_TEMPLATES ) => {
170+ const handleServiceClick = ( index : number , service : keyof typeof SERVICE_TEMPLATES ) => {
171+ setSelectedIconIndex ( index )
172+ if ( intervalRef . current ) {
173+ clearInterval ( intervalRef . current )
174+ intervalRef . current = null
175+ }
170176 setTextValue ( SERVICE_TEMPLATES [ service ] )
171177 }
172178
@@ -188,6 +194,21 @@ export default function Hero() {
188194 return ( ) => window . removeEventListener ( 'resize' , updateVisibleIcons )
189195 } , [ ] )
190196
197+ React . useEffect ( ( ) => {
198+ const maxIndex = visibleIconCount - 1
199+ setAutoHoverIndex ( ( i ) => Math . min ( i , maxIndex ) )
200+ setLastHoveredIndex ( ( idx ) =>
201+ idx !== null ? Math . min ( idx , maxIndex ) : null
202+ )
203+ setSelectedIconIndex ( ( idx ) =>
204+ idx !== null ? Math . min ( idx , maxIndex ) : null
205+ )
206+ } , [ visibleIconCount ] )
207+
208+ React . useEffect ( ( ) => {
209+ if ( textValue . trim ( ) . length === 0 ) setSelectedIconIndex ( null )
210+ } , [ textValue ] )
211+
191212 /**
192213 * Service icons array for easier indexing
193214 */
@@ -216,25 +237,20 @@ export default function Hero() {
216237 * Auto-hover animation effect
217238 */
218239 React . useEffect ( ( ) => {
219- // Start the interval when component mounts
220240 const startInterval = ( ) => {
221241 intervalRef . current = setInterval ( ( ) => {
222242 setAutoHoverIndex ( ( prev ) => ( prev + 1 ) % visibleIconCount )
223243 } , 2000 )
224244 }
225245
226- // Only run interval when user is not hovering
227- if ( ! isUserHovering ) {
228- startInterval ( )
229- }
246+ if ( selectedIconIndex === null && ! isUserHovering ) startInterval ( )
230247
231- // Cleanup on unmount or when hovering state changes
232248 return ( ) => {
233249 if ( intervalRef . current ) {
234250 clearInterval ( intervalRef . current )
235251 }
236252 }
237- } , [ isUserHovering , visibleIconCount ] )
253+ } , [ selectedIconIndex , isUserHovering , visibleIconCount ] )
238254
239255 /**
240256 * Handle mouse enter on icon container
@@ -258,11 +274,19 @@ export default function Hero() {
258274 }
259275
260276 const activeIconIndex =
261- isUserHovering && lastHoveredIndex !== null ? lastHoveredIndex : autoHoverIndex
277+ selectedIconIndex !== null
278+ ? selectedIconIndex
279+ : isUserHovering && lastHoveredIndex !== null
280+ ? lastHoveredIndex
281+ : autoHoverIndex
282+ const pillTargetIndex = Math . max (
283+ 0 ,
284+ Math . min ( activeIconIndex , visibleIconCount - 1 )
285+ )
262286
263287 React . useLayoutEffect ( ( ) => {
264288 const container = iconRowRef . current
265- const target = buttonRefs . current [ activeIconIndex ]
289+ const target = buttonRefs . current [ pillTargetIndex ]
266290 if ( ! container || ! target ) return
267291 const cr = container . getBoundingClientRect ( )
268292 const tr = target . getBoundingClientRect ( )
@@ -272,7 +296,7 @@ export default function Hero() {
272296 width : tr . width ,
273297 height : tr . height ,
274298 } )
275- } , [ activeIconIndex , layoutVersion , visibleIconCount ] )
299+ } , [ pillTargetIndex , layoutVersion , visibleIconCount ] )
276300
277301 React . useEffect ( ( ) => {
278302 const onResize = ( ) => setLayoutVersion ( ( v ) => v + 1 )
@@ -445,7 +469,9 @@ export default function Hero() {
445469 >
446470 < IconButton
447471 aria-label = { service . label }
448- onClick = { ( ) => handleServiceClick ( service . key as keyof typeof SERVICE_TEMPLATES ) }
472+ onClick = { ( ) =>
473+ handleServiceClick ( index , service . key as keyof typeof SERVICE_TEMPLATES )
474+ }
449475 onMouseEnter = { ( ) => setLastHoveredIndex ( index ) }
450476 style = { service . style }
451477 highlightFromParent
0 commit comments