@@ -2,6 +2,7 @@ import { LitElement, css, html } from "lit";
22import { unsafeHTML } from "lit-html/directives/unsafe-html.js" ;
33import { property } from "lit/decorators.js" ;
44
5+ import { MarkdownElement } from "../markdown-stream/markdown-stream" ;
56import {
67 LightElement ,
78 createElement ,
@@ -114,17 +115,55 @@ class ChatMessage extends LitElement {
114115 < div class ="message-icon ">
115116 < slot name ="icon "> ${ unsafeHTML ( defaultIcon ) } </ slot >
116117 </ div >
117- < shiny-markdown-stream
118- content =${ this . content }
119- content-type =${ this . content_type }
120- ?streaming=${ this . streaming }
121- auto-scroll
122- .onContentChange=${ this . #onContentChange}
123- .onStreamEnd=${ this . #makeSuggestionsAccessible}
124- > </ shiny-markdown-stream >
118+ < slot name ="content "> ${ this . content } </ slot >
125119 ` ;
126120 }
127121
122+ updated ( changedProperties : Map < string , unknown > ) {
123+ super . updated ( changedProperties ) ;
124+
125+ if (
126+ changedProperties . has ( "content" ) ||
127+ changedProperties . has ( "content_type" ) ||
128+ changedProperties . has ( "streaming" )
129+ ) {
130+ this . #onContentUpdate( ) ;
131+ }
132+ }
133+
134+ #onContentUpdate( ) {
135+ const markdownStream = this . #getOrCreateMarkdownStream( ) ;
136+ if ( ! markdownStream ) return ;
137+
138+ markdownStream . setAttribute ( "content" , this . content ) ;
139+ markdownStream . setAttribute ( "content-type" , this . content_type ) ;
140+ markdownStream . toggleAttribute ( "streaming" , this . streaming ) ;
141+ }
142+
143+ #getOrCreateMarkdownStream( ) : MarkdownElement | void {
144+ if ( this . content_type === "text" ) return ;
145+
146+ let markdownStream = this . querySelector ( '[slot="content"]' ) ;
147+
148+ if ( ! markdownStream ) {
149+ markdownStream = document . createElement ( "shiny-markdown-stream" ) ;
150+ markdownStream . setAttribute ( "slot" , "content" ) ;
151+ markdownStream . setAttribute ( "auto-scroll" , "" ) ;
152+ this . appendChild ( markdownStream ) ;
153+
154+ if ( markdownStream instanceof MarkdownElement ) {
155+ markdownStream . onContentChange = this . #onContentChange. bind ( this ) ;
156+ markdownStream . onStreamEnd = this . #makeSuggestionsAccessible. bind ( this ) ;
157+ }
158+ }
159+
160+ if ( ! ( markdownStream instanceof MarkdownElement ) ) {
161+ throw `ChatMessage only accepts <shiny-markdown-stream> in the "content" slot.` ;
162+ }
163+
164+ return markdownStream ;
165+ }
166+
128167 #onContentChange( ) : void {
129168 if ( ! this . streaming ) this . #makeSuggestionsAccessible( ) ;
130169 }
0 commit comments