Hi developers, I just created a new component: streamlit-shadcn-ui It allows streamlit developers to use one of the most popular frontend components library shadcn to build streamlit data apps. Interested in any feedback (especially for experimental features like nest component)
Main features you can benefit from it:
Extends the options of components (with minimalism style of design) for building data app, (modal, hovercard, badges, etc)
Customization of UI design: it allows you to write tailwind CSS to adjust the design.
Nest component, it provide a basic element component, which supports multi-level components nesting to build more complex layouts.
Currently, only the element function allows for styling components with either style or className (using Tailwind). This feature is still experimental, but I plan to complete most of the work this week. For example:
import streamlit_shadcn_ui as ui
with ui.card(key="card1"):
ui.element("span", children=["Email"], className="text-gray-400 text-sm font-medium m-1", key="label1")
ui.element("input", key="email_input", placeholder="Your email")
ui.element("span", children=["User Name"], className="text-gray-400 text-sm font-medium m-1", key="label2")
ui.element("input", key="username_input", placeholder="Create a User Name")
ui.element("button", text="Submit", key="button", className="m-1")
One concern I have is preventing the frontend application from becoming too bulky. Each iframe incorporating its own complete bundle of Tailwind code could lead to excessively large files. Full Tailwind integration offers a great development experience, but at the cost of increased bundle size, which is particularly significant since a Streamlit app typically contains many iframe-based components.
To address this, I am considering offering two initial options: including the complete Tailwind style by default, but also providing a ‘lite-mode’ with limited Tailwind for those who prefer a leaner approach.
Another task to complete before making element a formal feature involves the handling of element values. When using nested elements, they share the same iframe and Streamlit values in the session state. Therefore, I need to slightly refactor the current value type to include the component key, allowing all components to share a single Streamlit value.
This is amazing. Congratulations on the great work! Its a very powerful component
If you accept suggestions, I would suggest making background colors transparent in some components. This makes it more flexible to use the component along with CSS changes in the app.
Second, I haven’t taken a look at the code, but I imagine it should be possible to add wrapper functions in the python script so that specific elements can be called as follows:
import streamlit_shadcn_ui as ui
import streamlit as st
trigger_btn = ui.button(text="Trigger Button", key="trigger_btn_1")
ui.alert_dialog(show=trigger_btn, title="Alert Dialog", description="This is an alert dialog", confirm_label="OK", cancel_label="Cancel", key="alert_dialog_1")
I am getting this error:
TypeError: 'type' object is not subscriptable
File "C:\Users\XXX\miniconda3\envs\streamlit_1_25\lib\site-packages\streamlit\runtime\scriptrunner\script_runner.py", line 552, in _run_script
exec(code, module.__dict__)
File "C:\XXXX\test.py", line 1, in <module>
import streamlit_shadcn_ui as ui
File "C:\Users\XXXX\miniconda3\envs\streamlit_1_25\lib\site-packages\streamlit_shadcn_ui\__init__.py", line 4, in <module>
from .py_components import *
File "C:\Users\XXXX\miniconda3\envs\streamlit_1_25\lib\site-packages\streamlit_shadcn_ui\py_components\__init__.py", line 3, in <module>
from .select import select
File "C:\Users\XXX\miniconda3\envs\streamlit_1_25\lib\site-packages\streamlit_shadcn_ui\py_components\select.py", line 14, in <module>
def select_options(options: list[str], x, y, open_status=False, key=None, default_value=None, on_change=None, args=None, kwargs=None):
Do you have any idea why this is throwing this error?
@ObservedObserver I’ve answered my own problem: this error is thrown because I am using a version of Python older than 3.9. I will upgrade my Python version and see how that goes
How do I add the download function to my UI.element? For example, I created the following code:
def filedownload(df):
csv = df.to_csv(index=False)
b64 = base64.b64encode(csv.encode()).decode() # strings ↔ bytes conversions
href=f’Download CSV File’
return href
this is fantastic, and thank you very much for this, we can really leverage one of the greatest frontend UI framwork easily into Streamlit, this is truly helpful for data scientists who wants to build beatiful data app!!!
@ObservedObserver How do I add the download function to my UI.element? For example, I created the following code:
def filedownload(df):
csv = df.to_csv(index=False)
b64 = base64.b64encode(csv.encode()).decode() # strings ↔ bytes conversions
href=f’Download CSV File’
return href