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
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.