I made this solution, without creating a new component, according to this discussion
import streamlit as st
import streamlit.components.v1 as components
import json
key_dict = {}
st.write('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css"/>', unsafe_allow_html=True)
def generate_key(icon, button_key):
key_dict[button_key] = icon
return {'label':button_key,'key':button_key}
st.button(**generate_key('<i class="fa-solid fa-circle-user fa-bounce"></i>',button_key = 'button_test_1'))
st.button(**generate_key('<i class="fa-brands fa-youtube fa-spin-pulse"></i>',button_key = 'button_test_2'))
st.button('test')
icon_config = f"""
<script>
var elements = window.parent.document.getElementsByClassName('css-x78sv8 eqr7zpz4');
let dict = {json.dumps(key_dict)};
let keys = Object.keys(dict);
let icons = Object.values(dict);
for (var i = 0; i < elements.length; ++i) {{
for (var j = 0; j < keys.length; ++j){{
if (elements[i].innerText == keys[j])
elements[i].innerHTML = icons[j];
}}
}}
</script>
"""
components.html(f"{icon_config}", height=0, width=0)
The idea is to first generate a button with a unique key, then search for it and replace its content with the icon