@@ -442,16 +442,12 @@ function buildDiff(oldStr: string, newStr: string): DiffInfo {
442442 hunks . push ( {
443443 type : "remove" ,
444444 text : removeLines [ j ] ,
445- wordParts : parts
446- . filter ( ( p ) => ! p . added )
447- . map ( ( p ) => ( { text : p . value , highlight : ! ! p . removed } ) ) ,
445+ wordParts : parts . filter ( ( p ) => ! p . added ) . map ( ( p ) => ( { text : p . value , highlight : ! ! p . removed } ) ) ,
448446 } ) ;
449447 hunks . push ( {
450448 type : "add" ,
451449 text : addLines [ j ] ,
452- wordParts : parts
453- . filter ( ( p ) => ! p . removed )
454- . map ( ( p ) => ( { text : p . value , highlight : ! ! p . added } ) ) ,
450+ wordParts : parts . filter ( ( p ) => ! p . removed ) . map ( ( p ) => ( { text : p . value , highlight : ! ! p . added } ) ) ,
455451 } ) ;
456452 }
457453 } else {
@@ -492,6 +488,8 @@ function DiffSummary({ diff, width, keyPrefix }: { diff: DiffInfo; width: number
492488 return (
493489 < Box flexDirection = "column" marginLeft = { 2 } >
494490 < Text dimColor > { counts } </ Text >
491+ { /* biome-ignore lint/suspicious/noArrayIndexKey: hunks are freshly built per render from
492+ immutable args; no reorder, no insertion, so index is a stable per-render key */ }
495493 { diff . hunks . map ( ( h , i ) => {
496494 const isRemove = h . type === "remove" ;
497495 const sign = isRemove ? " - " : " + " ;
@@ -513,17 +511,23 @@ function DiffSummary({ diff, width, keyPrefix }: { diff: DiffInfo; width: number
513511 break ;
514512 }
515513 }
514+ // Stable keys per-word: counter-suffix is only for collision when
515+ // the same word appears multiple times in a line. Avoids the
516+ // array-index-as-key smell while keeping React's reconciler happy.
517+ const seenCounts = new Map < string , number > ( ) ;
518+ const keyedParts = visibleParts . map ( ( p ) => {
519+ const baseKey = `${ p . highlight ? "h" : "n" } :${ p . text } ` ;
520+ const count = seenCounts . get ( baseKey ) ?? 0 ;
521+ seenCounts . set ( baseKey , count + 1 ) ;
522+ return { part : p , k : `${ key } -w-${ baseKey } -${ count } ` } ;
523+ } ) ;
516524 return (
517525 < Box key = { key } >
518526 < Text color = { lineColor } > { sign } </ Text >
519527 < Text >
520- { visibleParts . map ( ( p , j ) => (
521- < Text
522- key = { `${ key } -w-${ j } ` }
523- color = { lineColor }
524- backgroundColor = { p . highlight ? hlBg : undefined }
525- >
526- { p . text }
528+ { keyedParts . map ( ( { part, k } ) => (
529+ < Text key = { k } color = { lineColor } backgroundColor = { part . highlight ? hlBg : undefined } >
530+ { part . text }
527531 </ Text >
528532 ) ) }
529533 </ Text >
0 commit comments