55 * 2.0.
66 */
77
8- import React from 'react' ;
8+ import React , { useState , useEffect } from 'react' ;
99import { EuiTitle , EuiPageHeaderSection , useEuiTheme } from '@elastic/eui' ;
1010import { css } from '@emotion/react' ;
1111import { i18n } from '@kbn/i18n' ;
@@ -15,6 +15,9 @@ export const ConversationTitle: React.FC<{}> = () => {
1515 const { euiTheme } = useEuiTheme ( ) ;
1616 const { title, isLoading } = useConversationTitle ( ) ;
1717
18+ const [ previousTitle , setPreviousTitle ] = useState < string > ( '' ) ;
19+ const [ currentText , setCurrentText ] = useState < string > ( '' ) ;
20+
1821 const labels = {
1922 ariaLabel : i18n . translate ( 'xpack.onechat.conversationTitle.ariaLabel' , {
2023 defaultMessage : 'Conversation title' ,
@@ -27,6 +30,32 @@ export const ConversationTitle: React.FC<{}> = () => {
2730 ) ,
2831 } ;
2932
33+ useEffect ( ( ) => {
34+ if ( isLoading ) return ;
35+
36+ const fullText = title || labels . newConversationDisplay ;
37+
38+ // Typewriter effect: only when transitioning from "New conversation" to actual title
39+ if ( previousTitle === labels . newConversationDisplay && title ) {
40+ if ( currentText . length < fullText . length ) {
41+ // start typewriter effect
42+ const typingSpeed = 50 ;
43+ const timeout = setTimeout ( ( ) => {
44+ setCurrentText ( fullText . substring ( 0 , currentText . length + 1 ) ) ;
45+ } , typingSpeed ) ;
46+
47+ return ( ) => clearTimeout ( timeout ) ;
48+ }
49+ } else if ( title && title !== previousTitle ) {
50+ // Normal title change: set immediately without typewriter effect I.e. when changing from one conversation to another
51+ setCurrentText ( fullText ) ;
52+ }
53+ // always track the previous title
54+ setPreviousTitle ( fullText ) ;
55+ } , [ title , currentText , labels . newConversationDisplay , isLoading , previousTitle ] ) ;
56+
57+ const titleDisplayText = currentText || previousTitle ;
58+
3059 const sectionStyles = css `
3160 display : flex;
3261 flex-direction : row;
@@ -37,7 +66,7 @@ export const ConversationTitle: React.FC<{}> = () => {
3766 < EuiPageHeaderSection css = { sectionStyles } >
3867 { ! isLoading && (
3968 < EuiTitle aria-label = { labels . ariaLabel } size = "xxs" >
40- < h1 > { title || labels . newConversationDisplay } </ h1 >
69+ < h1 > { titleDisplayText } </ h1 >
4170 </ EuiTitle >
4271 ) }
4372 </ EuiPageHeaderSection >
0 commit comments