Hello, streamlit community!
I needed some assistance, I am attempting to add chat buttons right next to the chat_message conversation as shown below. it seems to be working well currently but I’m concerned it might be a bit hacky? and there is a better approach that I don’t know.
import streamlit as st
temp = [
{"name": "user", "msg": "Ping"},
{"name": "assistant", "msg": "Pong"},
{"name": "user", "msg": "Can you help me with a Python script?"},
{"name": "assistant", "msg": "Of course! What do you need help with?"},
{"name": "user", "msg": "I need to sort a list of dictionaries by a key."},
{"name": "assistant",
"msg": "Here’s a sample code snippet to do that:\n\n```python\nlist_of_dicts = [{'name': 'Alice', 'age': 30}, "
"{'name': 'Bob', 'age': 25}]\n\nsorted_list = sorted(list_of_dicts, key=lambda x: x['age'])\nprint("
"sorted_list)\n```"},
{"name": "user", "msg": "Explain the difference between a list and a tuple in Python."},
{"name": "assistant",
"msg": "A list is mutable, meaning you can change its contents after it’s created, while a tuple is immutable, "
"so its contents cannot be modified after creation. Lists are defined with square brackets `[]` and "
"tuples with parentheses `()`. For example:\n\n```python\nmy_list = [1, 2, 3]\nmy_tuple = (1, 2, 3)\n```"},
{"name": "user", "msg": "Write a short poem about autumn."},
{"name": "assistant",
"msg": "Here’s a little poem for you:\n\n**Autumn Whispers**\nLeaves in golden hues descend,\nCrisp and cool, "
"the breezes send.\nPumpkin patches, apple spice,\nAutumn’s charm, a sweet delight."},
{"name": "user", "msg": "What’s the capital of France?"},
{"name": "assistant", "msg": "The capital of France is Paris."},
]
st.markdown("""
<style>
.stButton>button {
background-color: rgba(0, 123, 255, 0.0); /* Blue background with 50% opacity */
position: relative; /* Positioning context */
padding: 0px 0px;
min-width: 33px;
min-height: 31px;
left: -40px; /* Move the button to the left */
opacity: 0; /* Fully invisible */
}
.stButton>button:hover {
opacity: 1; /* Make visible on hover */
}
</style>
""", unsafe_allow_html=True)
parent = st.container()
with parent:
for val, item in enumerate(temp, start=1):
name = item["name"]
message = item["msg"]
with st.container():
col1, col2, col3 = st.columns([8, 1, 1])
with col1:
st.chat_message(name).write(message)
if name == "user":
with col2:
st.chat_message(name, avatar=":material/edit:").button("", key=val)
with col3:
st.chat_message(name, avatar=":material/delete:").button("", key=-val)
here’s my approach/thought process:
- Initially I tried to add buttons right next to messages, and the formatting kept messing up. without using a column format
- I tried making CSS buttons but the interactions between CSS and streamlit just would not work no matter how much I tried.
- After adding the column format the buttons were too big and would mess up the CSS again as more messages came through, so I switched to adding a container across one row and that fixed it.
- the hacky part is having a “button” that’s see-through but actually, it’s on top of the material icons giving the illusion that the icons are buttons.