holoviz / panel

Panel: The powerful data exploration & web app framework for Python
https://panel.holoviz.org
BSD 3-Clause "New" or "Revised" License
4.62k stars 504 forks source link

Streaming rows of markdown into a ChatFeed, Feed, or Column breaks the styling of subsequent appended rows and leads to overlap of text #6970

Open DmitriyLeybel opened 2 months ago

DmitriyLeybel commented 2 months ago

ALL software version info

Panel: 1.4.4 Bokeh: 3.4.1

Description of expected behavior and the observed behavior

(See below for included video of behavior) In trying to populate an element such as a ChatFeed, Feed, or Column with a pn.Row that has pn.pane.Markdown streamed into it, subsequent rows that are added to that same element are broken with overlapping text. It appears that the new text is appearing positionally where the bottom of the element would be during the first stream of text.

This issue does not arise when I don't stream text into the created pn.Row(pn.Markdown) object (same case with plain pn.Markdown object)

Complete, minimal, self-contained example code that reproduces the issue

import panel as pn
import time

chat_column = pn.Column(height=200, width=400, scroll=True)
chat_input = pn.widgets.TextInput(placeholder='Type your message here...')
send_button = pn.widgets.Button(name='Send', button_type='primary')

def send_message(event):
    message = chat_input.value
    if message:
        message_pane = pn.pane.Markdown(message)
        chat_column.append(message_pane)
        for word in message.split():
            message_pane.object += word + " "
            time.sleep(0.01)  
        chat_input.value = ''  

send_button.on_click(send_message)
pn.Column(chat_column, pn.Row(chat_input, send_button))

https://github.com/holoviz/panel/assets/6779278/efefa7fa-3e19-4434-aafb-244a0f077281

https://discourse.holoviz.org/t/feed-not-scrolling-down-when-streaming-markdown-into-it-plus-an-overlap-of-text-when-appending-more-rows-with-markdown/7417/2

philippjfr commented 2 months ago

Seems to be because something is setting max_height: 100%. Looking into it.

philippjfr commented 2 months ago

The immediate cause is this bit of code in Bokeh

https://github.com/bokeh/bokeh/blob/04bde465230d8a27256fe80a19ca108a849efdf7/bokehjs/src/lib/models/layouts/layout_dom.ts#L333

which does not seem quite correct to me.

ahuang11 commented 2 months ago

I may have overridden that value in ChatMessage CSS, so it's possible that you can also workaround it with stylesheets

Maybe max-height: none

DmitriyLeybel commented 2 months ago

I may have overridden that value in ChatMessage CSS, so it's possible that you can also workaround it with stylesheets

Maybe max-height: none

Appreciate the heads up, Andrew.

How are you handling the auto-scroll aspect?

This does partly seem to work as expected:

import panel as pn
import time

chat_column = pn.Column(height=200, width=400, scroll=True)
chat_input = pn.widgets.TextInput(placeholder='Type your message here...')
send_button = pn.widgets.Button(name='Send', button_type='primary')

def send_message(event):
    message = chat_input.value
    if message:
        message_pane = pn.pane.Markdown(
            '',
            stylesheets=["""
                :host {
                    max-height: none;
                }
                """])
        chat_column.append(message_pane)
        for word in message.split():
            message_pane.object += word + " "
            time.sleep(0.01)  
        chat_input.value = ''  

send_button.on_click(send_message)
pn.Column(chat_column, pn.Row(chat_input, send_button)).servable()

https://github.com/user-attachments/assets/4ca13b8d-e756-4c24-a464-b3caf386b4e9

ahuang11 commented 2 months ago

It's done in the typescript side. Perhaps instead of watching for children, it should watch for scroll length from the bottom? https://github.com/holoviz/panel/blob/01c45380cf68b6f3460ba723c44abb7e4f1bb679/panel/models/column.ts#L14

Maybe you can help contribute a fix for this if you're interested and we can get it for Panel 1.5.0