@@ -446,6 +446,23 @@ export default class GleapCopilotTours {
446446 opacity: 0.8;
447447 }
448448
449+ .${ copilotJoinedContainerId } -dismiss {
450+ display: flex;
451+ align-items: center;
452+ justify-content: center;
453+ padding-right: 3px;
454+ }
455+
456+ .${ copilotJoinedContainerId } -dismiss svg {
457+ width: 15px;
458+ height: auto;
459+ cursor: pointer;
460+ }
461+
462+ .${ copilotJoinedContainerId } -dismiss svg:hover {
463+ opacity: 0.8;
464+ }
465+
449466 @keyframes pulsate {
450467 0% {
451468 transform: scale(1);
@@ -576,7 +593,13 @@ export default class GleapCopilotTours {
576593 <span>${ this . productTourData ?. kaiSlug } </span>
577594 <div class="${ copilotJoinedContainerId } -mute">
578595 ${ loadIcon ( this . audioMuted ? "unmute" : "mute" ) }
579- </div>
596+ </div>${
597+ this . productTourData ?. allowClose
598+ ? `<div class="${ copilotJoinedContainerId } -dismiss">
599+ ${ loadIcon ( "dismiss" ) }
600+ </div>`
601+ : ""
602+ }
580603 ` ;
581604 document . body . appendChild ( copilotInfoContainer ) ;
582605
@@ -596,6 +619,14 @@ export default class GleapCopilotTours {
596619 loadIcon ( self . audioMuted ? "unmute" : "mute" ) ;
597620 } ) ;
598621
622+ if ( this . productTourData ?. allowClose ) {
623+ document
624+ . querySelector ( `.${ copilotJoinedContainerId } -dismiss` )
625+ . addEventListener ( "click" , ( ) => {
626+ this . completeTour ( false ) ;
627+ } ) ;
628+ }
629+
599630 // Append elements
600631 container . appendChild ( svgMouse ) ;
601632 container . appendChild ( infoBubble ) ;
@@ -660,7 +691,7 @@ export default class GleapCopilotTours {
660691 const gotToNextStep = ( ) => {
661692 if ( currentStep . mode === "INPUT" && element ) {
662693 // Wait for text to be entered. Continue tour on enter. element is the input.
663- function handleClick ( ) {
694+ function proceedClickmode ( ) {
664695 document
665696 . querySelector ( `#${ pointerContainerId } ` )
666697 . classList . remove ( "copilot-pointer-container-clickmode" ) ;
@@ -676,38 +707,65 @@ export default class GleapCopilotTours {
676707 self . renderNextStep ( ) ;
677708 }
678709
679- function handleInputEvent ( e ) {
680- if ( e . target . value . length === 0 ) return ;
710+ const inputModeType = currentStep . inputType ?? "default" ;
681711
682- const cursor = document . getElementById (
683- `${ copilotInfoBubbleId } -content`
684- ) ;
685- if ( ! cursor ) return ;
712+ if ( inputModeType === "default" ) {
713+ function handleInputEvent ( e ) {
714+ if ( e . target . value . length === 0 ) return ;
686715
687- cursor . innerHTML = ` ${ GleapTranslationManager . translateText (
688- `next `
689- ) } ${ arrowRightIcon } ` ;
690- cursor . addEventListener ( "click" , handleClick , { once : true } ) ;
716+ const cursor = document . getElementById (
717+ ` ${ copilotInfoBubbleId } -content `
718+ ) ;
719+ if ( ! cursor ) return ;
691720
692- // Add highlight to the input fields. red shadow glow.
693- element . classList . add ( "gleap-input-highlight" ) ;
721+ cursor . innerHTML = `${ GleapTranslationManager . translateText (
722+ `next`
723+ ) } ${ arrowRightIcon } `;
724+ cursor . addEventListener ( "click" , proceedClickmode , {
725+ once : true ,
726+ } ) ;
694727
695- document
696- . querySelector ( `#${ pointerContainerId } ` )
697- . classList . add ( "copilot-pointer-container-clickmode" ) ;
728+ // Add highlight to the input fields. red shadow glow.
729+ element . classList . add ( "gleap-input-highlight" ) ;
698730
699- // Remove the input event listener after execution
700- element . removeEventListener ( "input" , handleInputEvent ) ;
701- }
731+ document
732+ . querySelector ( `# ${ pointerContainerId } ` )
733+ . classList . add ( "copilot-pointer-container-clickmode" ) ;
702734
703- element . addEventListener ( "input" , handleInputEvent ) ;
735+ // Remove the input event listener after execution
736+ element . removeEventListener ( "input" , handleInputEvent ) ;
737+ }
704738
705- // Focus on the input.
706- element . addEventListener ( "blur" , ( ) => {
707- element . focus ( ) ;
708- } ) ;
739+ element . addEventListener ( "input" , handleInputEvent ) ;
709740
710- element . focus ( ) ;
741+ // Focus on the input.
742+ element . addEventListener ( "blur" , ( ) => {
743+ element . focus ( ) ;
744+ } ) ;
745+
746+ element . focus ( ) ;
747+ } else {
748+ // Set the input value, wait and proceed.
749+ const inputValue = currentStep . inputValue ?? "" ;
750+
751+ let index = 0 ;
752+ function typeCharacter ( ) {
753+ if ( index < inputValue . length ) {
754+ // Append one character at a time.
755+ element . value += inputValue [ index ] ;
756+ index ++ ;
757+
758+ setTimeout ( typeCharacter , 100 ) ;
759+ } else {
760+ setTimeout ( ( ) => {
761+ proceedClickmode ( ) ;
762+ } , 1200 ) ;
763+ }
764+ }
765+
766+ // Start the typewriter effect.
767+ typeCharacter ( ) ;
768+ }
711769
712770 return ;
713771 }
0 commit comments