@@ -187,16 +187,21 @@ function renderBlockNodes(
187187 const key = `${ blockStart } -${ si } `
188188
189189 if ( 'code' in seg ) {
190- if ( ! didPlace && revealed >= start && revealed < end ) {
191- nodes . push ( < Caret key = { `${ key } -c` } who = { AGENT } /> )
192- didPlace = true
193- }
190+ // Type the chip in character by character, at the same cadence as the surrounding text, with
191+ // the caret moving through it. The box reserves its full width up front (the unrevealed tail is
192+ // visibility:hidden inside it) so the card never reflows. Revealing it as one chunk instead made
193+ // it either freeze-and-jump (caret parked before an empty gap) or fly past as a skipped unit.
194+ const reached = revealed >= start
195+ const shown = reached ? Math . min ( raw . length , revealed - start ) : 0
196+ const atBoundary = ! didPlace && reached && shown < raw . length
197+ if ( atBoundary ) didPlace = true
194198 nodes . push (
195- < code
196- key = { key }
197- style = { { ...codeStyle , visibility : revealed >= end ? 'visible' : 'hidden' } }
198- >
199- { raw }
199+ < code key = { key } style = { { ...codeStyle , visibility : reached ? 'visible' : 'hidden' } } >
200+ { reached ? raw . slice ( 0 , shown ) : raw }
201+ { atBoundary && < Caret key = { `${ key } -c` } who = { AGENT } /> }
202+ { reached && shown < raw . length && (
203+ < span style = { { visibility : 'hidden' } } > { raw . slice ( shown ) } </ span >
204+ ) }
200205 </ code >
201206 )
202207 } else {
@@ -254,13 +259,27 @@ function AgentDoc({ revealed }: { revealed: number }) {
254259
255260 for ( let bi = 0 ; bi < AGENT_BLOCKS . length ; bi ++ ) {
256261 const block = AGENT_BLOCKS [ bi ]
257- const res = renderBlockNodes ( block , offset , revealed , placed , bi === AGENT_BLOCKS . length - 1 )
262+ const blockStart = offset
263+ const res = renderBlockNodes (
264+ block ,
265+ blockStart ,
266+ revealed ,
267+ placed ,
268+ bi === AGENT_BLOCKS . length - 1
269+ )
258270 placed = res . placed
259- offset += block . segs . reduce ( ( m , s ) => m + segText ( s ) . length , 0 )
271+ offset = blockStart + block . segs . reduce ( ( m , s ) => m + segText ( s ) . length , 0 )
260272
261273 if ( block . kind === 'li' ) {
274+ // The bullet is the <li>'s own list marker, so hiding the item's text with visibility:hidden
275+ // would still leave an empty bullet showing. Hide the whole item until the caret reaches it, so
276+ // each bullet appears with its line rather than all of them up front. The hidden item still
277+ // reserves its height, so the card never changes size.
262278 list . push (
263- < li key = { `li-${ bi } ` } style = { { marginTop : 0 } } >
279+ < li
280+ key = { `li-${ bi } ` }
281+ style = { { marginTop : 0 , visibility : revealed >= blockStart ? 'visible' : 'hidden' } }
282+ >
264283 { res . nodes }
265284 </ li >
266285 )
0 commit comments