Initial commit: Shelly Manager with Textual CLI, Streamlit UI, and comprehensive .gitignore

Shelly device management app with mDNS/subnet discovery, inventory,
configuration, and mass operations for Gen1/Gen2+ devices.

Includes .gitignore excluding runtime data (device DB, user config),
AI conversation history, build artifacts, and common Python/OS patterns.
This commit is contained in:
2026-03-23 21:51:59 +01:00
commit 71803418e5
152 changed files with 23405 additions and 0 deletions
@@ -0,0 +1,128 @@
# Streamlit theme templates
Ready-to-use theme templates for Streamlit apps.
## Available themes
| Theme | Base | Primary color | Fonts |
|-------|------|---------------|-------|
| **snowflake** | Light | `#29B5E8` (cyan) | Inter, JetBrains Mono |
| **dracula** | Dark | `#BD93F9` (purple) | Fira Sans, JetBrains Mono |
| **nord** | Dark | `#88C0D0` (frost blue) | Inter, JetBrains Mono |
| **stripe** | Light | `#635BFF` (indigo) | Inter, Source Code Pro |
| **solarized-light** | Light | `#268BD2` (blue) | Source Sans 3, Source Code Pro |
| **spotify** | Dark | `#1DB954` (green) | Inter, Fira Code |
| **github** | Light | `#0969DA` (blue) | Inter, JetBrains Mono |
| **minimal** | Dark | `#6366f1` (indigo) | Inter, JetBrains Mono |
## Quick start
```bash
# Run a theme locally
cd templates/themes/spotify
uv sync
uv run streamlit run streamlit_app.py
```
## Deploying to Snowflake
Before deploying, update `snowflake.yml` with your account-specific resources:
```yaml
# Find available compute pools
SHOW COMPUTE POOLS;
# Find available external access integrations
SHOW EXTERNAL ACCESS INTEGRATIONS;
```
Then edit `snowflake.yml` to replace the placeholders:
- `<YOUR_COMPUTE_POOL>` → e.g., `STREAMLIT_DEDICATED_POOL`
- `<YOUR_PYPI_INTEGRATION>` → e.g., `PYPI_ACCESS_INTEGRATION`
- `<FROM_CONNECTION>` values are filled from your active connection
Deploy with:
```bash
snow streamlit deploy --replace
```
## How Streamlit theming works
A custom theme requires two things:
### 1. Theme configuration in `.streamlit/config.toml`
```toml
[theme]
base = "dark" # "dark" or "light"
primaryColor = "#1DB954" # Buttons, links, highlights
backgroundColor = "#121212" # Main background
secondaryBackgroundColor = "#181818" # Sidebar, cards
textColor = "#FFFFFF" # Main text color
font = "Inter" # Body font
codeFont = "FiraCode" # Code blocks
```
### 2. For Snowflake deployment: local font files
Snowflake doesn't allow remote URL fetches, so fonts must be bundled locally:
```toml
[server]
enableStaticServing = true # Required for static files
[[theme.fontFaces]]
family = "Inter"
url = "app/static/Inter-Regular.ttf" # Note: app/ prefix required
weight = 400
[[theme.fontFaces]]
family = "Inter"
url = "app/static/Inter-Bold.ttf"
weight = 700
```
Font files go in `static/` directory and are referenced with `app/static/` prefix.
### Sidebar theming (optional)
```toml
[theme.sidebar]
backgroundColor = "#181818"
secondaryBackgroundColor = "#121212"
borderColor = "#282828"
```
## Theme file structure
Each theme directory contains:
```
{theme}/
├── .streamlit/config.toml # Theme colors and fonts
├── streamlit_app.py # Demo app showing the theme
├── pyproject.toml # Dependencies
├── snowflake.yml # Snowflake deployment config
└── static/ # Bundled font files (*.ttf)
```
## Dependencies
All themes require Python >=3.11 and use:
- `snowflake-connector-python>=3.3.0` (required — `streamlit[snowflake]` silently skips this on Python 3.12+)
- `streamlit[snowflake]>=1.54.0`
- `altair>=5.5.0`
- `pandas>=2.2.3`
## Font licensing
All bundled fonts are licensed under the [SIL Open Font License 1.1](https://openfontlicense.org/), which permits free use, redistribution, and modification:
| Font | Used by | Source |
|------|---------|--------|
| Inter | snowflake, nord, spotify, github, minimal, stripe | [github.com/rsms/inter](https://github.com/rsms/inter) |
| JetBrains Mono | snowflake, dracula, nord, github, minimal | [github.com/JetBrains/JetBrainsMono](https://github.com/JetBrains/JetBrainsMono) |
| Fira Sans | dracula | [github.com/mozilla/Fira](https://github.com/mozilla/Fira) |
| Fira Code | spotify | [github.com/tonsky/FiraCode](https://github.com/tonsky/FiraCode) |
| Source Sans 3 | solarized-light | [github.com/adobe-fonts/source-sans](https://github.com/adobe-fonts/source-sans) |
| Source Code Pro | solarized-light, stripe | [github.com/adobe-fonts/source-code-pro](https://github.com/adobe-fonts/source-code-pro) |
@@ -0,0 +1,39 @@
# Dracula Theme for Streamlit
# Popular dark theme with vibrant colors on dark background
[theme]
base = "dark"
primaryColor = "#bd93f9"
backgroundColor = "#282a36"
secondaryBackgroundColor = "#21222c"
codeBackgroundColor = "#21222c"
textColor = "#f8f8f2"
linkColor = "#8be9fd"
borderColor = "#44475a"
showWidgetBorder = true
showSidebarBorder = true
baseRadius = "8px"
buttonRadius = "8px"
font = "'Fira Sans':https://fonts.googleapis.com/css2?family=Fira+Sans:wght@400;500;600;700&display=swap"
codeFont = "'JetBrains Mono':https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap"
codeFontSize = "0.875rem"
codeTextColor = "#f8f8f2"
baseFontSize = 14
baseFontWeight = 400
headingFontSizes = ["32px", "24px", "20px", "16px", "14px", "12px"]
headingFontWeights = [700, 600, 600, 600, 600, 600]
linkUnderline = false
chartCategoricalColors = ["#bd93f9", "#50fa7b", "#ff79c6", "#8be9fd", "#ffb86c", "#ff5555", "#f1fa8c"]
# Dracula color palette
violetColor = "#bd93f9"
greenColor = "#50fa7b"
redColor = "#ff5555"
blueColor = "#8be9fd"
yellowColor = "#f1fa8c"
orangeColor = "#ffb86c"
[theme.sidebar]
backgroundColor = "#21222c"
secondaryBackgroundColor = "#191a21"
codeBackgroundColor = "#191a21"
borderColor = "#44475a"
@@ -0,0 +1,37 @@
# GitHub Theme for Streamlit
# Clean, developer-friendly, functional with signature blue accents
[theme]
primaryColor = "#0969da"
backgroundColor = "#ffffff"
secondaryBackgroundColor = "#f6f8fa"
codeBackgroundColor = "#f6f8fa"
textColor = "#1F2328"
linkColor = "#0969da"
borderColor = "#d0d7de"
showWidgetBorder = true
showSidebarBorder = true
baseRadius = "6px"
buttonRadius = "6px"
font = "Inter:https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
codeFont = "'JetBrains Mono':https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap"
codeFontSize = "0.85rem"
codeTextColor = "#1F2328"
baseFontSize = 14
baseFontWeight = 400
headingFontSizes = ["32px", "24px", "20px", "16px", "14px", "12px"]
headingFontWeights = [600, 600, 600, 600, 600, 600]
linkUnderline = false
chartCategoricalColors = ["#0969da", "#1a7f37", "#bf3989", "#8250df", "#cf222e", "#bf8700", "#57606a"]
# GitHub color palette
blueColor = "#0969da"
greenColor = "#1a7f37"
redColor = "#cf222e"
violetColor = "#8250df"
orangeColor = "#bf8700"
[theme.sidebar]
backgroundColor = "#f6f8fa"
secondaryBackgroundColor = "#eaeef2"
codeBackgroundColor = "#eaeef2"
borderColor = "#d0d7de"
@@ -0,0 +1,39 @@
# Minimal Dark Theme for Streamlit
# Clean, distraction-free dark theme with subtle accents
[theme]
base = "dark"
primaryColor = "#6366f1"
backgroundColor = "#18181b"
secondaryBackgroundColor = "#27272a"
codeBackgroundColor = "#27272a"
textColor = "#fafafa"
linkColor = "#818cf8"
borderColor = "#3f3f46"
showWidgetBorder = false
showSidebarBorder = false
baseRadius = "6px"
buttonRadius = "6px"
font = "Inter:https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
codeFont = "'JetBrains Mono':https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap"
codeFontSize = "0.85rem"
codeTextColor = "#e4e4e7"
baseFontSize = 14
baseFontWeight = 400
headingFontSizes = ["32px", "24px", "20px", "16px", "14px", "12px"]
headingFontWeights = [600, 600, 500, 500, 500, 500]
linkUnderline = false
chartCategoricalColors = ["#6366f1", "#8b5cf6", "#ec4899", "#14b8a6", "#f59e0b", "#ef4444", "#22c55e"]
# Color palette
violetColor = "#8b5cf6"
blueColor = "#6366f1"
greenColor = "#22c55e"
yellowColor = "#f59e0b"
orangeColor = "#f97316"
redColor = "#ef4444"
[theme.sidebar]
backgroundColor = "#09090b"
secondaryBackgroundColor = "#18181b"
codeBackgroundColor = "#18181b"
borderColor = "#27272a"
@@ -0,0 +1,39 @@
# Nord Theme for Streamlit
# Arctic, north-bluish color palette with frost-inspired accents
[theme]
base = "dark"
primaryColor = "#88c0d0"
backgroundColor = "#2e3440"
secondaryBackgroundColor = "#3b4252"
codeBackgroundColor = "#3b4252"
textColor = "#eceff4"
linkColor = "#81a1c1"
borderColor = "#4c566a"
showWidgetBorder = true
showSidebarBorder = true
baseRadius = "4px"
buttonRadius = "4px"
font = "Inter:https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
codeFont = "'JetBrains Mono':https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap"
codeFontSize = "0.875rem"
codeTextColor = "#d8dee9"
baseFontSize = 14
baseFontWeight = 400
headingFontSizes = ["32px", "24px", "20px", "16px", "14px", "12px"]
headingFontWeights = [600, 600, 600, 600, 600, 600]
linkUnderline = false
chartCategoricalColors = ["#88c0d0", "#81a1c1", "#5e81ac", "#a3be8c", "#ebcb8b", "#d08770", "#bf616a"]
# Nord color palette (Frost + Aurora)
blueColor = "#81a1c1"
greenColor = "#a3be8c"
yellowColor = "#ebcb8b"
orangeColor = "#d08770"
redColor = "#bf616a"
violetColor = "#b48ead"
[theme.sidebar]
backgroundColor = "#3b4252"
secondaryBackgroundColor = "#434c5e"
codeBackgroundColor = "#434c5e"
borderColor = "#4c566a"
@@ -0,0 +1,42 @@
# Snowflake Theme for Streamlit
# The Data Cloud company aesthetic - clean, professional, icy blue branding
[theme]
primaryColor = "#29B5E8"
backgroundColor = "#ffffff"
secondaryBackgroundColor = "#f4f9fc"
codeBackgroundColor = "#e8f4f8"
textColor = "#11567F"
linkColor = "#29B5E8"
borderColor = "#d0e8f2"
showWidgetBorder = true
showSidebarBorder = true
baseRadius = "8px"
buttonRadius = "8px"
font = "Inter:https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
codeFont = "'JetBrains Mono':https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap"
codeFontSize = "13px"
codeTextColor = "#11567F"
baseFontSize = 14
baseFontWeight = 400
headingFontSizes = ["32px", "24px", "20px", "16px", "14px", "12px"]
headingFontWeights = [600, 600, 600, 500, 500, 500]
linkUnderline = false
chartCategoricalColors = ["#29B5E8", "#FF8B00", "#36B37E", "#6554C0", "#DE350B", "#11567F", "#FFAB00", "#00A3BF"]
# Snowflake color palette
blueColor = "#29B5E8"
greenColor = "#36B37E"
yellowColor = "#FFAB00"
orangeColor = "#FF8B00"
redColor = "#DE350B"
violetColor = "#6554C0"
dataframeBorderColor = "#d0e8f2"
dataframeHeaderBackgroundColor = "#e8f4f8"
[theme.sidebar]
backgroundColor = "#11567F"
secondaryBackgroundColor = "#174D6A"
codeBackgroundColor = "#0E4D6B"
textColor = "#ffffff"
borderColor = "#1E6D94"
@@ -0,0 +1,38 @@
# Solarized Light Theme for Streamlit
# Precision colors designed for readability and reduced eye strain
[theme]
primaryColor = "#268bd2"
backgroundColor = "#fdf6e3"
secondaryBackgroundColor = "#eee8d5"
codeBackgroundColor = "#eee8d5"
textColor = "#657b83"
linkColor = "#268bd2"
borderColor = "#93a1a1"
showWidgetBorder = true
showSidebarBorder = true
baseRadius = "4px"
buttonRadius = "4px"
font = "'Source Sans 3':https://fonts.googleapis.com/css2?family=Source+Sans+3:wght@400;500;600;700&display=swap"
codeFont = "'Source Code Pro':https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@400;500&display=swap"
codeFontSize = "0.875rem"
codeTextColor = "#586e75"
baseFontSize = 14
baseFontWeight = 400
headingFontSizes = ["32px", "24px", "20px", "16px", "14px", "12px"]
headingFontWeights = [600, 600, 600, 600, 600, 600]
linkUnderline = false
chartCategoricalColors = ["#268bd2", "#2aa198", "#859900", "#b58900", "#cb4b16", "#dc322f", "#d33682"]
# Solarized color palette
blueColor = "#268bd2"
greenColor = "#859900"
yellowColor = "#b58900"
orangeColor = "#cb4b16"
redColor = "#dc322f"
violetColor = "#6c71c4"
[theme.sidebar]
backgroundColor = "#eee8d5"
secondaryBackgroundColor = "#fdf6e3"
codeBackgroundColor = "#fdf6e3"
borderColor = "#93a1a1"
@@ -0,0 +1,34 @@
# Spotify Theme for Streamlit
# Bold, energetic, high contrast with signature green
[theme]
base = "dark"
primaryColor = "#1DB954"
backgroundColor = "#191414"
secondaryBackgroundColor = "#282828"
codeBackgroundColor = "#282828"
textColor = "#ffffff"
linkColor = "#1DB954"
borderColor = "#404040"
showWidgetBorder = false
showSidebarBorder = false
baseRadius = "8px"
buttonRadius = "full"
font = "Inter:https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
codeFont = "'Fira Code':https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap"
codeFontSize = "0.85rem"
baseFontSize = 16
baseFontWeight = 400
headingFontWeights = [800, 700, 700, 600, 600, 600]
headingFontSizes = ["48px", "36px", "28px", "22px", "18px", "16px"]
chartCategoricalColors = ["#1DB954", "#1ED760", "#B3B3B3", "#535353", "#191414", "#FFFFFF", "#509BF5"]
# Spotify color palette
greenColor = "#1DB954"
blueColor = "#509BF5"
grayColor = "#B3B3B3"
[theme.sidebar]
backgroundColor = "#000000"
secondaryBackgroundColor = "#282828"
codeBackgroundColor = "#282828"
borderColor = "#333333"
@@ -0,0 +1,35 @@
# Stripe Theme for Streamlit
# Polished, professional, modern with signature purple/indigo gradients
[theme]
primaryColor = "#635bff"
backgroundColor = "#ffffff"
secondaryBackgroundColor = "#f6f9fc"
codeBackgroundColor = "#f7f9fc"
textColor = "#425466"
linkColor = "#635bff"
borderColor = "#e3e8ee"
showWidgetBorder = true
showSidebarBorder = true
baseRadius = "8px"
buttonRadius = "8px"
font = "Inter:https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
codeFont = "'Source Code Pro':https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@400;500&display=swap"
codeFontSize = "0.85rem"
codeTextColor = "#425466"
baseFontSize = 15
baseFontWeight = 400
headingFontSizes = ["40px", "32px", "24px", "20px", "16px", "14px"]
headingFontWeights = [600, 600, 600, 600, 600, 600]
linkUnderline = false
chartCategoricalColors = ["#635bff", "#00d4ff", "#0a2540", "#adbdcc", "#80e9ff", "#7a73ff", "#425466"]
# Stripe color palette
violetColor = "#635bff"
blueColor = "#00d4ff"
grayColor = "#adbdcc"
[theme.sidebar]
backgroundColor = "#f6f9fc"
secondaryBackgroundColor = "#ebeef1"
codeBackgroundColor = "#ebeef1"
borderColor = "#e3e8ee"
@@ -0,0 +1,336 @@
"""
Streamlit Element Explorer - Theme Demo
A comprehensive single-page app showcasing all major Streamlit components
with custom theming. Use this to preview how your theme looks across
different element types.
"""
import numpy as np
import pandas as pd
import streamlit as st
st.set_page_config(page_title="Element Explorer", page_icon="🎨", layout="wide")
# Initialize sample data in session state
if "chart_data" not in st.session_state:
np.random.seed(42)
st.session_state.chart_data = pd.DataFrame(
np.random.randn(20, 3), columns=["a", "b", "c"]
)
chart_data = st.session_state.chart_data
st.title("Streamlit Element Explorer")
st.markdown(
"Explore how Streamlit's built-in elements look with this theme. "
"Select a category below to preview different components."
)
# Navigation using segmented_control for better performance
section = st.segmented_control(
"Section",
["Widgets", "Data", "Charts", "Text", "Layouts", "Chat", "Status"],
default="Widgets",
label_visibility="collapsed",
)
st.divider()
# -----------------------------------------------------------------------------
# WIDGETS SECTION
# -----------------------------------------------------------------------------
if section == "Widgets":
st.header("Widgets")
# Buttons
st.subheader("Buttons")
cols = st.columns(4)
cols[0].button("Primary", type="primary")
cols[1].button("Secondary", type="secondary")
cols[2].button("Tertiary", type="tertiary")
cols[3].link_button("Link", url="https://streamlit.io", icon=":material/open_in_new:")
# Form
with st.form(key="demo_form"):
st.subheader("Form")
form_cols = st.columns(2)
form_cols[0].text_input("Name", placeholder="Enter your name")
form_cols[1].text_input("Email", placeholder="you@example.com")
st.form_submit_button("Submit", type="primary")
# Selection widgets
st.subheader("Selection Widgets")
sel_cols = st.columns(2)
with sel_cols[0]:
st.checkbox("Checkbox option")
st.toggle("Toggle switch")
st.selectbox("Selectbox", options=["Option A", "Option B", "Option C"])
st.multiselect("Multiselect", options=["Tag 1", "Tag 2", "Tag 3"], default=["Tag 1"])
with sel_cols[1]:
st.radio("Radio buttons", options=["Choice 1", "Choice 2", "Choice 3"], horizontal=True)
st.pills("Pills", options=["Small", "Medium", "Large"], default="Medium")
st.segmented_control("Segmented", options=["Day", "Week", "Month"], default="Week")
st.caption("Feedback widget")
st.feedback("stars")
# Numeric & Sliders
st.subheader("Numeric Inputs")
num_cols = st.columns(3)
num_cols[0].number_input("Number input", value=42)
num_cols[1].slider("Slider", 0, 100, 50)
num_cols[2].select_slider("Select slider", options=["XS", "S", "M", "L", "XL"], value="M")
# Date/Time
st.subheader("Date & Time")
dt_cols = st.columns(2)
dt_cols[0].date_input("Date input")
dt_cols[1].time_input("Time input")
# Text inputs
st.subheader("Text Inputs")
txt_cols = st.columns(2)
txt_cols[0].text_input("Text input", placeholder="Type something...")
txt_cols[1].text_area("Text area", placeholder="Longer text goes here...", height=100)
# File upload
st.subheader("File Upload")
st.file_uploader("Upload a file", type=["csv", "txt", "pdf"])
# -----------------------------------------------------------------------------
# DATA SECTION
# -----------------------------------------------------------------------------
elif section == "Data":
st.header("Data Display")
# Metrics
st.subheader("Metrics")
m_cols = st.columns(4)
m_cols[0].metric("Revenue", "$45,231", "+12.5%")
m_cols[1].metric("Users", "2,847", "+8.2%")
m_cols[2].metric("Conversion", "3.24%", "-0.4%", delta_color="inverse")
m_cols[3].metric("Avg. Session", "4m 32s", "+1.2%")
st.divider()
# Dataframe
st.subheader("Dataframe")
df = pd.DataFrame({
"Name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
"Department": ["Engineering", "Sales", "Marketing", "Engineering", "Sales"],
"Salary": [95000, 78000, 82000, 105000, 71000],
"Start Date": pd.date_range("2022-01-15", periods=5, freq="3M"),
"Active": [True, True, False, True, True],
})
st.dataframe(
df,
hide_index=True,
column_config={
"Salary": st.column_config.NumberColumn(format="$%d"),
"Start Date": st.column_config.DateColumn(format="MMM DD, YYYY"),
"Active": st.column_config.CheckboxColumn("Active?"),
},
)
# Table
st.subheader("Static Table")
st.table(chart_data.head(5))
# JSON
st.subheader("JSON Display")
st.json({"name": "Streamlit", "version": "1.41.0", "features": ["themes", "widgets", "charts"]})
# -----------------------------------------------------------------------------
# CHARTS SECTION
# -----------------------------------------------------------------------------
elif section == "Charts":
st.header("Charts")
chart_cols = st.columns(2)
with chart_cols[0]:
st.subheader("Line Chart")
st.line_chart(chart_data, height=250)
st.subheader("Bar Chart")
st.bar_chart(chart_data, height=250)
with chart_cols[1]:
st.subheader("Area Chart")
st.area_chart(chart_data, height=250)
st.subheader("Scatter Chart")
st.scatter_chart(chart_data, height=250)
# -----------------------------------------------------------------------------
# TEXT SECTION
# -----------------------------------------------------------------------------
elif section == "Text":
st.header("Text Elements")
# Headers
st.subheader("Headers")
st.title("Title Element")
st.header("Header Element")
st.subheader("Subheader Element")
st.caption("Caption text - smaller, muted")
st.divider()
# Markdown
st.subheader("Markdown Formatting")
st.markdown(
"**Bold text**, *italic text*, ~~strikethrough~~, "
"`inline code`, [link](https://streamlit.io)"
)
st.markdown("Math: $E = mc^2$ and $\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}$")
st.markdown("Emojis: 🚀 🎨 📊 ✨ and icons: :material/home: :material/settings:")
# Colored text
st.subheader("Colored Text")
color_cols = st.columns(3)
color_cols[0].markdown(":red[Red text] and :orange[Orange text]")
color_cols[1].markdown(":green[Green text] and :blue[Blue text]")
color_cols[2].markdown(":violet[Violet text] and :rainbow[Rainbow text]")
# Code blocks
st.subheader("Code Block")
st.code(
'''import streamlit as st
# Create a themed dashboard
st.set_page_config(page_title="My App", layout="wide")
st.title("Hello, Streamlit!")
# Display metrics
col1, col2 = st.columns(2)
col1.metric("Users", "1,234", "+5%")
col2.metric("Revenue", "$56K", "+12%")''',
language="python",
)
# -----------------------------------------------------------------------------
# LAYOUTS SECTION
# -----------------------------------------------------------------------------
elif section == "Layouts":
st.header("Layout Elements")
# Columns
st.subheader("Columns with Borders")
layout_cols = st.columns(3, border=True)
layout_cols[0].write("**Column 1**\n\nFirst column content")
layout_cols[1].write("**Column 2**\n\nSecond column content")
layout_cols[2].write("**Column 3**\n\nThird column content")
# Tabs
st.subheader("Tabs")
tab1, tab2, tab3 = st.tabs(["📈 Chart", "📋 Data", "⚙️ Settings"])
with tab1:
st.write("Chart tab content")
st.line_chart(chart_data["a"], height=150)
with tab2:
st.write("Data tab content")
st.dataframe(chart_data.head(3))
with tab3:
st.write("Settings tab content")
st.checkbox("Enable feature X")
st.checkbox("Enable feature Y", value=True)
# Expander
st.subheader("Expander")
with st.expander("Click to expand"):
st.write("This content is hidden by default.")
st.image("https://placehold.co/400x200/29B5E8/white?text=Expanded+Content")
# Popover
st.subheader("Popover")
pop_cols = st.columns(3)
with pop_cols[0].popover("Open popover", icon=":material/info:"):
st.write("Popover content here!")
st.slider("Popover slider", 0, 100, 50)
# Container
st.subheader("Container with Border")
with st.container(border=True):
st.write("**Bordered Container**")
st.write("Content inside a container with a visible border.")
st.button("Button inside container")
# -----------------------------------------------------------------------------
# CHAT SECTION
# -----------------------------------------------------------------------------
elif section == "Chat":
st.header("Chat Elements")
# Chat messages
st.subheader("Chat Messages")
with st.chat_message("user"):
st.write("Hello! How can I analyze my sales data?")
with st.chat_message("assistant"):
st.write("I can help you with that! Here are a few options:")
st.markdown("""
1. **Revenue trends** - View monthly/quarterly patterns
2. **Top products** - Identify best sellers
3. **Customer segments** - Analyze by region or category
""")
with st.chat_message("user"):
st.write("Show me the revenue trends please.")
with st.chat_message("assistant"):
st.write("Here's your revenue trend for the past 20 periods:")
st.line_chart(chart_data["a"], height=200)
# Chat input
st.chat_input("Type a message...")
# -----------------------------------------------------------------------------
# STATUS SECTION
# -----------------------------------------------------------------------------
elif section == "Status":
st.header("Status Elements")
# Alert messages
st.subheader("Alert Messages")
st.error("Error: Something went wrong with the data pipeline.")
st.warning("Warning: API rate limit approaching (80% used).")
st.info("Info: New features available in the latest release.")
st.success("Success: Data exported successfully to warehouse.")
# Exception
st.subheader("Exception Display")
try:
raise ValueError("This is an example exception for demonstration")
except ValueError as e:
st.exception(e)
# Interactive status
st.subheader("Interactive Status")
status_cols = st.columns(3)
if status_cols[0].button("Show Toast", icon=":material/notifications:"):
st.toast("This is a toast notification!", icon="🔔")
if status_cols[1].button("Balloons", icon=":material/celebration:"):
st.balloons()
if status_cols[2].button("Snow", icon=":material/ac_unit:"):
st.snow()
# Progress
st.subheader("Progress Indicators")
st.progress(0.7, text="70% complete")
with st.spinner("Loading..."):
st.write("Spinner is active (non-blocking in this demo)")
# -----------------------------------------------------------------------------
# SIDEBAR
# -----------------------------------------------------------------------------
with st.sidebar:
st.header("Settings")
st.selectbox("Time Period", ["Last 7 days", "Last 30 days", "Last 90 days", "All time"])
st.multiselect("Metrics", ["Revenue", "Users", "Sessions"], default=["Revenue", "Users"])
st.slider("Confidence threshold", 0.0, 1.0, 0.8)
st.divider()
st.caption("Element Explorer v1.0")
st.caption("Theme: **{{title}}**")
@@ -0,0 +1,12 @@
# DO NOT EDIT — managed by manage.py, edit _templates/pyproject.toml.tmpl instead
[project]
name = "theme-{{slug}}"
version = "1.0.0"
description = "{{title}} theme for Streamlit"
requires-python = ">=3.11"
dependencies = [
"numpy>=1.26.0",
"pandas>=2.2.3",
"snowflake-connector-python>=3.3.0",
"streamlit[snowflake]>=1.54.0",
]
@@ -0,0 +1,10 @@
[project]
name = "theme-dracula"
version = "1.0.0"
description = "Dracula theme for Streamlit"
requires-python = ">=3.11"
dependencies = [
"numpy>=1.26.0",
"pandas>=2.2.3",
"streamlit>=1.53.0",
]
@@ -0,0 +1,337 @@
"""
Streamlit Element Explorer - Theme Demo
A comprehensive single-page app showcasing all major Streamlit components
with custom theming. Use this to preview how your theme looks across
different element types.
"""
# DO NOT EDIT — managed by manage.py, edit _shared/streamlit_app.py instead
import numpy as np
import pandas as pd
import streamlit as st
st.set_page_config(page_title="Element Explorer", page_icon="🎨", layout="wide")
# Initialize sample data in session state
if "chart_data" not in st.session_state:
np.random.seed(42)
st.session_state.chart_data = pd.DataFrame(
np.random.randn(20, 3), columns=["a", "b", "c"]
)
chart_data = st.session_state.chart_data
st.title("Streamlit Element Explorer")
st.markdown(
"Explore how Streamlit's built-in elements look with this theme. "
"Select a category below to preview different components."
)
# Navigation using segmented_control for better performance
section = st.segmented_control(
"Section",
["Widgets", "Data", "Charts", "Text", "Layouts", "Chat", "Status"],
default="Widgets",
label_visibility="collapsed",
)
st.divider()
# -----------------------------------------------------------------------------
# WIDGETS SECTION
# -----------------------------------------------------------------------------
if section == "Widgets":
st.header("Widgets")
# Buttons
st.subheader("Buttons")
cols = st.columns(4)
cols[0].button("Primary", type="primary")
cols[1].button("Secondary", type="secondary")
cols[2].button("Tertiary", type="tertiary")
cols[3].link_button("Link", url="https://streamlit.io", icon=":material/open_in_new:")
# Form
with st.form(key="demo_form"):
st.subheader("Form")
form_cols = st.columns(2)
form_cols[0].text_input("Name", placeholder="Enter your name")
form_cols[1].text_input("Email", placeholder="you@example.com")
st.form_submit_button("Submit", type="primary")
# Selection widgets
st.subheader("Selection Widgets")
sel_cols = st.columns(2)
with sel_cols[0]:
st.checkbox("Checkbox option")
st.toggle("Toggle switch")
st.selectbox("Selectbox", options=["Option A", "Option B", "Option C"])
st.multiselect("Multiselect", options=["Tag 1", "Tag 2", "Tag 3"], default=["Tag 1"])
with sel_cols[1]:
st.radio("Radio buttons", options=["Choice 1", "Choice 2", "Choice 3"], horizontal=True)
st.pills("Pills", options=["Small", "Medium", "Large"], default="Medium")
st.segmented_control("Segmented", options=["Day", "Week", "Month"], default="Week")
st.caption("Feedback widget")
st.feedback("stars")
# Numeric & Sliders
st.subheader("Numeric Inputs")
num_cols = st.columns(3)
num_cols[0].number_input("Number input", value=42)
num_cols[1].slider("Slider", 0, 100, 50)
num_cols[2].select_slider("Select slider", options=["XS", "S", "M", "L", "XL"], value="M")
# Date/Time
st.subheader("Date & Time")
dt_cols = st.columns(2)
dt_cols[0].date_input("Date input")
dt_cols[1].time_input("Time input")
# Text inputs
st.subheader("Text Inputs")
txt_cols = st.columns(2)
txt_cols[0].text_input("Text input", placeholder="Type something...")
txt_cols[1].text_area("Text area", placeholder="Longer text goes here...", height=100)
# File upload
st.subheader("File Upload")
st.file_uploader("Upload a file", type=["csv", "txt", "pdf"])
# -----------------------------------------------------------------------------
# DATA SECTION
# -----------------------------------------------------------------------------
elif section == "Data":
st.header("Data Display")
# Metrics
st.subheader("Metrics")
m_cols = st.columns(4)
m_cols[0].metric("Revenue", "$45,231", "+12.5%")
m_cols[1].metric("Users", "2,847", "+8.2%")
m_cols[2].metric("Conversion", "3.24%", "-0.4%", delta_color="inverse")
m_cols[3].metric("Avg. Session", "4m 32s", "+1.2%")
st.divider()
# Dataframe
st.subheader("Dataframe")
df = pd.DataFrame({
"Name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
"Department": ["Engineering", "Sales", "Marketing", "Engineering", "Sales"],
"Salary": [95000, 78000, 82000, 105000, 71000],
"Start Date": pd.date_range("2022-01-15", periods=5, freq="3M"),
"Active": [True, True, False, True, True],
})
st.dataframe(
df,
hide_index=True,
column_config={
"Salary": st.column_config.NumberColumn(format="$%d"),
"Start Date": st.column_config.DateColumn(format="MMM DD, YYYY"),
"Active": st.column_config.CheckboxColumn("Active?"),
},
)
# Table
st.subheader("Static Table")
st.table(chart_data.head(5))
# JSON
st.subheader("JSON Display")
st.json({"name": "Streamlit", "version": "1.41.0", "features": ["themes", "widgets", "charts"]})
# -----------------------------------------------------------------------------
# CHARTS SECTION
# -----------------------------------------------------------------------------
elif section == "Charts":
st.header("Charts")
chart_cols = st.columns(2)
with chart_cols[0]:
st.subheader("Line Chart")
st.line_chart(chart_data, height=250)
st.subheader("Bar Chart")
st.bar_chart(chart_data, height=250)
with chart_cols[1]:
st.subheader("Area Chart")
st.area_chart(chart_data, height=250)
st.subheader("Scatter Chart")
st.scatter_chart(chart_data, height=250)
# -----------------------------------------------------------------------------
# TEXT SECTION
# -----------------------------------------------------------------------------
elif section == "Text":
st.header("Text Elements")
# Headers
st.subheader("Headers")
st.title("Title Element")
st.header("Header Element")
st.subheader("Subheader Element")
st.caption("Caption text - smaller, muted")
st.divider()
# Markdown
st.subheader("Markdown Formatting")
st.markdown(
"**Bold text**, *italic text*, ~~strikethrough~~, "
"`inline code`, [link](https://streamlit.io)"
)
st.markdown("Math: $E = mc^2$ and $\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}$")
st.markdown("Emojis: 🚀 🎨 📊 ✨ and icons: :material/home: :material/settings:")
# Colored text
st.subheader("Colored Text")
color_cols = st.columns(3)
color_cols[0].markdown(":red[Red text] and :orange[Orange text]")
color_cols[1].markdown(":green[Green text] and :blue[Blue text]")
color_cols[2].markdown(":violet[Violet text] and :rainbow[Rainbow text]")
# Code blocks
st.subheader("Code Block")
st.code(
'''import streamlit as st
# Create a themed dashboard
st.set_page_config(page_title="My App", layout="wide")
st.title("Hello, Streamlit!")
# Display metrics
col1, col2 = st.columns(2)
col1.metric("Users", "1,234", "+5%")
col2.metric("Revenue", "$56K", "+12%")''',
language="python",
)
# -----------------------------------------------------------------------------
# LAYOUTS SECTION
# -----------------------------------------------------------------------------
elif section == "Layouts":
st.header("Layout Elements")
# Columns
st.subheader("Columns with Borders")
layout_cols = st.columns(3, border=True)
layout_cols[0].write("**Column 1**\n\nFirst column content")
layout_cols[1].write("**Column 2**\n\nSecond column content")
layout_cols[2].write("**Column 3**\n\nThird column content")
# Tabs
st.subheader("Tabs")
tab1, tab2, tab3 = st.tabs(["📈 Chart", "📋 Data", "⚙️ Settings"])
with tab1:
st.write("Chart tab content")
st.line_chart(chart_data["a"], height=150)
with tab2:
st.write("Data tab content")
st.dataframe(chart_data.head(3))
with tab3:
st.write("Settings tab content")
st.checkbox("Enable feature X")
st.checkbox("Enable feature Y", value=True)
# Expander
st.subheader("Expander")
with st.expander("Click to expand"):
st.write("This content is hidden by default.")
st.image("https://placehold.co/400x200/29B5E8/white?text=Expanded+Content")
# Popover
st.subheader("Popover")
pop_cols = st.columns(3)
with pop_cols[0].popover("Open popover", icon=":material/info:"):
st.write("Popover content here!")
st.slider("Popover slider", 0, 100, 50)
# Container
st.subheader("Container with Border")
with st.container(border=True):
st.write("**Bordered Container**")
st.write("Content inside a container with a visible border.")
st.button("Button inside container")
# -----------------------------------------------------------------------------
# CHAT SECTION
# -----------------------------------------------------------------------------
elif section == "Chat":
st.header("Chat Elements")
# Chat messages
st.subheader("Chat Messages")
with st.chat_message("user"):
st.write("Hello! How can I analyze my sales data?")
with st.chat_message("assistant"):
st.write("I can help you with that! Here are a few options:")
st.markdown("""
1. **Revenue trends** - View monthly/quarterly patterns
2. **Top products** - Identify best sellers
3. **Customer segments** - Analyze by region or category
""")
with st.chat_message("user"):
st.write("Show me the revenue trends please.")
with st.chat_message("assistant"):
st.write("Here's your revenue trend for the past 20 periods:")
st.line_chart(chart_data["a"], height=200)
# Chat input
st.chat_input("Type a message...")
# -----------------------------------------------------------------------------
# STATUS SECTION
# -----------------------------------------------------------------------------
elif section == "Status":
st.header("Status Elements")
# Alert messages
st.subheader("Alert Messages")
st.error("Error: Something went wrong with the data pipeline.")
st.warning("Warning: API rate limit approaching (80% used).")
st.info("Info: New features available in the latest release.")
st.success("Success: Data exported successfully to warehouse.")
# Exception
st.subheader("Exception Display")
try:
raise ValueError("This is an example exception for demonstration")
except ValueError as e:
st.exception(e)
# Interactive status
st.subheader("Interactive Status")
status_cols = st.columns(3)
if status_cols[0].button("Show Toast", icon=":material/notifications:"):
st.toast("This is a toast notification!", icon="🔔")
if status_cols[1].button("Balloons", icon=":material/celebration:"):
st.balloons()
if status_cols[2].button("Snow", icon=":material/ac_unit:"):
st.snow()
# Progress
st.subheader("Progress Indicators")
st.progress(0.7, text="70% complete")
with st.spinner("Loading..."):
st.write("Spinner is active (non-blocking in this demo)")
# -----------------------------------------------------------------------------
# SIDEBAR
# -----------------------------------------------------------------------------
with st.sidebar:
st.header("Settings")
st.selectbox("Time Period", ["Last 7 days", "Last 30 days", "Last 90 days", "All time"])
st.multiselect("Metrics", ["Revenue", "Users", "Sessions"], default=["Revenue", "Users"])
st.slider("Confidence threshold", 0.0, 1.0, 0.8)
st.divider()
st.caption("Element Explorer v1.0")
st.caption("Theme: **Dracula**")
@@ -0,0 +1,10 @@
[project]
name = "theme-github"
version = "1.0.0"
description = "GitHub theme for Streamlit"
requires-python = ">=3.11"
dependencies = [
"numpy>=1.26.0",
"pandas>=2.2.3",
"streamlit>=1.53.0",
]
@@ -0,0 +1,337 @@
"""
Streamlit Element Explorer - Theme Demo
A comprehensive single-page app showcasing all major Streamlit components
with custom theming. Use this to preview how your theme looks across
different element types.
"""
# DO NOT EDIT — managed by manage.py, edit _shared/streamlit_app.py instead
import numpy as np
import pandas as pd
import streamlit as st
st.set_page_config(page_title="Element Explorer", page_icon="🎨", layout="wide")
# Initialize sample data in session state
if "chart_data" not in st.session_state:
np.random.seed(42)
st.session_state.chart_data = pd.DataFrame(
np.random.randn(20, 3), columns=["a", "b", "c"]
)
chart_data = st.session_state.chart_data
st.title("Streamlit Element Explorer")
st.markdown(
"Explore how Streamlit's built-in elements look with this theme. "
"Select a category below to preview different components."
)
# Navigation using segmented_control for better performance
section = st.segmented_control(
"Section",
["Widgets", "Data", "Charts", "Text", "Layouts", "Chat", "Status"],
default="Widgets",
label_visibility="collapsed",
)
st.divider()
# -----------------------------------------------------------------------------
# WIDGETS SECTION
# -----------------------------------------------------------------------------
if section == "Widgets":
st.header("Widgets")
# Buttons
st.subheader("Buttons")
cols = st.columns(4)
cols[0].button("Primary", type="primary")
cols[1].button("Secondary", type="secondary")
cols[2].button("Tertiary", type="tertiary")
cols[3].link_button("Link", url="https://streamlit.io", icon=":material/open_in_new:")
# Form
with st.form(key="demo_form"):
st.subheader("Form")
form_cols = st.columns(2)
form_cols[0].text_input("Name", placeholder="Enter your name")
form_cols[1].text_input("Email", placeholder="you@example.com")
st.form_submit_button("Submit", type="primary")
# Selection widgets
st.subheader("Selection Widgets")
sel_cols = st.columns(2)
with sel_cols[0]:
st.checkbox("Checkbox option")
st.toggle("Toggle switch")
st.selectbox("Selectbox", options=["Option A", "Option B", "Option C"])
st.multiselect("Multiselect", options=["Tag 1", "Tag 2", "Tag 3"], default=["Tag 1"])
with sel_cols[1]:
st.radio("Radio buttons", options=["Choice 1", "Choice 2", "Choice 3"], horizontal=True)
st.pills("Pills", options=["Small", "Medium", "Large"], default="Medium")
st.segmented_control("Segmented", options=["Day", "Week", "Month"], default="Week")
st.caption("Feedback widget")
st.feedback("stars")
# Numeric & Sliders
st.subheader("Numeric Inputs")
num_cols = st.columns(3)
num_cols[0].number_input("Number input", value=42)
num_cols[1].slider("Slider", 0, 100, 50)
num_cols[2].select_slider("Select slider", options=["XS", "S", "M", "L", "XL"], value="M")
# Date/Time
st.subheader("Date & Time")
dt_cols = st.columns(2)
dt_cols[0].date_input("Date input")
dt_cols[1].time_input("Time input")
# Text inputs
st.subheader("Text Inputs")
txt_cols = st.columns(2)
txt_cols[0].text_input("Text input", placeholder="Type something...")
txt_cols[1].text_area("Text area", placeholder="Longer text goes here...", height=100)
# File upload
st.subheader("File Upload")
st.file_uploader("Upload a file", type=["csv", "txt", "pdf"])
# -----------------------------------------------------------------------------
# DATA SECTION
# -----------------------------------------------------------------------------
elif section == "Data":
st.header("Data Display")
# Metrics
st.subheader("Metrics")
m_cols = st.columns(4)
m_cols[0].metric("Revenue", "$45,231", "+12.5%")
m_cols[1].metric("Users", "2,847", "+8.2%")
m_cols[2].metric("Conversion", "3.24%", "-0.4%", delta_color="inverse")
m_cols[3].metric("Avg. Session", "4m 32s", "+1.2%")
st.divider()
# Dataframe
st.subheader("Dataframe")
df = pd.DataFrame({
"Name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
"Department": ["Engineering", "Sales", "Marketing", "Engineering", "Sales"],
"Salary": [95000, 78000, 82000, 105000, 71000],
"Start Date": pd.date_range("2022-01-15", periods=5, freq="3M"),
"Active": [True, True, False, True, True],
})
st.dataframe(
df,
hide_index=True,
column_config={
"Salary": st.column_config.NumberColumn(format="$%d"),
"Start Date": st.column_config.DateColumn(format="MMM DD, YYYY"),
"Active": st.column_config.CheckboxColumn("Active?"),
},
)
# Table
st.subheader("Static Table")
st.table(chart_data.head(5))
# JSON
st.subheader("JSON Display")
st.json({"name": "Streamlit", "version": "1.41.0", "features": ["themes", "widgets", "charts"]})
# -----------------------------------------------------------------------------
# CHARTS SECTION
# -----------------------------------------------------------------------------
elif section == "Charts":
st.header("Charts")
chart_cols = st.columns(2)
with chart_cols[0]:
st.subheader("Line Chart")
st.line_chart(chart_data, height=250)
st.subheader("Bar Chart")
st.bar_chart(chart_data, height=250)
with chart_cols[1]:
st.subheader("Area Chart")
st.area_chart(chart_data, height=250)
st.subheader("Scatter Chart")
st.scatter_chart(chart_data, height=250)
# -----------------------------------------------------------------------------
# TEXT SECTION
# -----------------------------------------------------------------------------
elif section == "Text":
st.header("Text Elements")
# Headers
st.subheader("Headers")
st.title("Title Element")
st.header("Header Element")
st.subheader("Subheader Element")
st.caption("Caption text - smaller, muted")
st.divider()
# Markdown
st.subheader("Markdown Formatting")
st.markdown(
"**Bold text**, *italic text*, ~~strikethrough~~, "
"`inline code`, [link](https://streamlit.io)"
)
st.markdown("Math: $E = mc^2$ and $\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}$")
st.markdown("Emojis: 🚀 🎨 📊 ✨ and icons: :material/home: :material/settings:")
# Colored text
st.subheader("Colored Text")
color_cols = st.columns(3)
color_cols[0].markdown(":red[Red text] and :orange[Orange text]")
color_cols[1].markdown(":green[Green text] and :blue[Blue text]")
color_cols[2].markdown(":violet[Violet text] and :rainbow[Rainbow text]")
# Code blocks
st.subheader("Code Block")
st.code(
'''import streamlit as st
# Create a themed dashboard
st.set_page_config(page_title="My App", layout="wide")
st.title("Hello, Streamlit!")
# Display metrics
col1, col2 = st.columns(2)
col1.metric("Users", "1,234", "+5%")
col2.metric("Revenue", "$56K", "+12%")''',
language="python",
)
# -----------------------------------------------------------------------------
# LAYOUTS SECTION
# -----------------------------------------------------------------------------
elif section == "Layouts":
st.header("Layout Elements")
# Columns
st.subheader("Columns with Borders")
layout_cols = st.columns(3, border=True)
layout_cols[0].write("**Column 1**\n\nFirst column content")
layout_cols[1].write("**Column 2**\n\nSecond column content")
layout_cols[2].write("**Column 3**\n\nThird column content")
# Tabs
st.subheader("Tabs")
tab1, tab2, tab3 = st.tabs(["📈 Chart", "📋 Data", "⚙️ Settings"])
with tab1:
st.write("Chart tab content")
st.line_chart(chart_data["a"], height=150)
with tab2:
st.write("Data tab content")
st.dataframe(chart_data.head(3))
with tab3:
st.write("Settings tab content")
st.checkbox("Enable feature X")
st.checkbox("Enable feature Y", value=True)
# Expander
st.subheader("Expander")
with st.expander("Click to expand"):
st.write("This content is hidden by default.")
st.image("https://placehold.co/400x200/29B5E8/white?text=Expanded+Content")
# Popover
st.subheader("Popover")
pop_cols = st.columns(3)
with pop_cols[0].popover("Open popover", icon=":material/info:"):
st.write("Popover content here!")
st.slider("Popover slider", 0, 100, 50)
# Container
st.subheader("Container with Border")
with st.container(border=True):
st.write("**Bordered Container**")
st.write("Content inside a container with a visible border.")
st.button("Button inside container")
# -----------------------------------------------------------------------------
# CHAT SECTION
# -----------------------------------------------------------------------------
elif section == "Chat":
st.header("Chat Elements")
# Chat messages
st.subheader("Chat Messages")
with st.chat_message("user"):
st.write("Hello! How can I analyze my sales data?")
with st.chat_message("assistant"):
st.write("I can help you with that! Here are a few options:")
st.markdown("""
1. **Revenue trends** - View monthly/quarterly patterns
2. **Top products** - Identify best sellers
3. **Customer segments** - Analyze by region or category
""")
with st.chat_message("user"):
st.write("Show me the revenue trends please.")
with st.chat_message("assistant"):
st.write("Here's your revenue trend for the past 20 periods:")
st.line_chart(chart_data["a"], height=200)
# Chat input
st.chat_input("Type a message...")
# -----------------------------------------------------------------------------
# STATUS SECTION
# -----------------------------------------------------------------------------
elif section == "Status":
st.header("Status Elements")
# Alert messages
st.subheader("Alert Messages")
st.error("Error: Something went wrong with the data pipeline.")
st.warning("Warning: API rate limit approaching (80% used).")
st.info("Info: New features available in the latest release.")
st.success("Success: Data exported successfully to warehouse.")
# Exception
st.subheader("Exception Display")
try:
raise ValueError("This is an example exception for demonstration")
except ValueError as e:
st.exception(e)
# Interactive status
st.subheader("Interactive Status")
status_cols = st.columns(3)
if status_cols[0].button("Show Toast", icon=":material/notifications:"):
st.toast("This is a toast notification!", icon="🔔")
if status_cols[1].button("Balloons", icon=":material/celebration:"):
st.balloons()
if status_cols[2].button("Snow", icon=":material/ac_unit:"):
st.snow()
# Progress
st.subheader("Progress Indicators")
st.progress(0.7, text="70% complete")
with st.spinner("Loading..."):
st.write("Spinner is active (non-blocking in this demo)")
# -----------------------------------------------------------------------------
# SIDEBAR
# -----------------------------------------------------------------------------
with st.sidebar:
st.header("Settings")
st.selectbox("Time Period", ["Last 7 days", "Last 30 days", "Last 90 days", "All time"])
st.multiselect("Metrics", ["Revenue", "Users", "Sessions"], default=["Revenue", "Users"])
st.slider("Confidence threshold", 0.0, 1.0, 0.8)
st.divider()
st.caption("Element Explorer v1.0")
st.caption("Theme: **GitHub**")
@@ -0,0 +1,332 @@
#!/usr/bin/env python3
"""Manage theme template directories (fully generated from _configs/).
Usage:
python manage.py sync # Regenerate all theme directories
python manage.py check # Verify generated files haven't drifted
python manage.py new NAME # Scaffold a new theme config
"""
import ast
import re
import shutil
import sys
from pathlib import Path
ROOT = Path(__file__).parent
SHARED = ROOT / "_shared"
TEMPLATES = ROOT / "_templates"
CONFIGS = ROOT / "_configs"
FONTS = SHARED / "fonts"
MANAGED_HEADER_PY = (
"# DO NOT EDIT — managed by manage.py, edit _shared/streamlit_app.py instead\n"
)
MANAGED_HEADER_TOML = (
"# DO NOT EDIT — managed by manage.py, edit _configs/{slug}.toml instead\n"
)
GITATTR_START = "# BEGIN managed by manage.py"
GITATTR_END = "# END managed by manage.py"
# ---------------------------------------------------------------------------
# Theme discovery
# ---------------------------------------------------------------------------
TITLE_OVERRIDES = {"github": "GitHub"}
def slug_to_title(slug):
"""Derive a display title from a directory slug: 'solarized-light' -> 'Solarized Light'."""
if slug in TITLE_OVERRIDES:
return TITLE_OVERRIDES[slug]
return " ".join(w.capitalize() for w in slug.split("-"))
def discover_themes():
"""Find themes by scanning _configs/*.toml."""
return [
{"slug": c.stem, "title": slug_to_title(c.stem)}
for c in sorted(CONFIGS.glob("*.toml"))
]
# ---------------------------------------------------------------------------
# Font discovery from config content
# ---------------------------------------------------------------------------
def discover_fonts(config_text):
"""Extract font filenames referenced in config.toml content."""
return re.findall(r'url\s*=\s*["\']app/static/([^"\']+\.(?:ttf|otf|woff2?))["\']', config_text)
# ---------------------------------------------------------------------------
# Content builders
# ---------------------------------------------------------------------------
def expected_app(title):
"""Build expected streamlit_app.py content for a theme."""
source = (SHARED / "streamlit_app.py").read_text()
body = source.replace("{{title}}", title)
# Insert managed header after the module docstring
tree = ast.parse(body)
if ast.get_docstring(tree) is not None:
# The docstring is the first statement; find end of its line
docstring_node = tree.body[0]
end_line = docstring_node.end_lineno # 1-indexed
lines = body.split("\n")
insert_pos = end_line
return "\n".join(lines[:insert_pos]) + "\n" + MANAGED_HEADER_PY + "\n".join(lines[insert_pos:])
return MANAGED_HEADER_PY + body
def expected_config(slug):
"""Build expected .streamlit/config.toml content for a theme."""
source = (CONFIGS / f"{slug}.toml").read_text()
header = MANAGED_HEADER_TOML.replace("{slug}", slug)
return header + source
def expected_from_template(tmpl_path, replacements):
"""Build expected file content from a .tmpl template."""
text = tmpl_path.read_text()
for key, value in replacements.items():
text = text.replace("{{" + key + "}}", value)
return text
# ---------------------------------------------------------------------------
# Sync
# ---------------------------------------------------------------------------
def sync_theme(theme):
"""Regenerate all files for a single theme directory."""
slug = theme["slug"]
title = theme["title"]
identifier = slug.replace("-", "_")
theme_dir = ROOT / slug
# Create directories
theme_dir.mkdir(exist_ok=True)
(theme_dir / ".streamlit").mkdir(exist_ok=True)
(theme_dir / "static").mkdir(exist_ok=True)
# .streamlit/config.toml — from _configs/
(theme_dir / ".streamlit" / "config.toml").write_text(expected_config(slug))
# streamlit_app.py
(theme_dir / "streamlit_app.py").write_text(expected_app(title))
# pyproject.toml
(theme_dir / "pyproject.toml").write_text(
expected_from_template(
TEMPLATES / "pyproject.toml.tmpl",
{"slug": slug, "title": title},
)
)
# snowflake.yml
(theme_dir / "snowflake.yml").write_text(
expected_from_template(
TEMPLATES / "snowflake.yml.tmpl",
{"slug": slug, "title": title, "identifier": identifier},
)
)
# Fonts — copy from _shared/fonts/ based on config references
config_text = (CONFIGS / f"{slug}.toml").read_text()
font_names = discover_fonts(config_text)
static_dir = theme_dir / "static"
for fname in font_names:
src = FONTS / fname
if not src.exists():
print(f" Warning: font {fname} referenced in _configs/{slug}.toml not found in _shared/fonts/", file=sys.stderr)
continue
shutil.copy2(src, static_dir / fname)
def update_gitattributes():
"""Update .gitattributes with entries for generated theme files."""
gitattr_path = ROOT / ".gitattributes"
new_section = "\n".join([
GITATTR_START,
"*/.streamlit/config.toml linguist-generated",
"*/streamlit_app.py linguist-generated",
"*/pyproject.toml linguist-generated",
"*/snowflake.yml linguist-generated",
"*/static/*.ttf linguist-generated",
GITATTR_END,
])
if gitattr_path.exists():
content = gitattr_path.read_text()
if GITATTR_START in content:
start = content.index(GITATTR_START)
end = content.index(GITATTR_END) + len(GITATTR_END)
content = content[:start] + new_section + content[end:]
else:
content = content.rstrip() + "\n\n" + new_section + "\n"
else:
content = new_section + "\n"
gitattr_path.write_text(content)
def cmd_sync():
themes = discover_themes()
for t in themes:
sync_theme(t)
print(f" Synced {t['slug']}/")
# Remove orphaned theme directories (directories not matching any config)
config_slugs = {t["slug"] for t in themes}
orphans = [
d for d in sorted(ROOT.iterdir())
if d.is_dir() and not d.name.startswith("_") and d.name not in config_slugs
]
if orphans:
print("\nOrphaned directories (no matching config):")
for d in orphans:
print(f" {d.name}/")
answer = input("Remove these directories? [y/N] ").strip().lower()
if answer == "y":
for d in orphans:
shutil.rmtree(d)
print(f" Removed {d.name}/")
else:
print(" Skipped orphan removal.")
update_gitattributes()
print(f"\nSynced {len(themes)} theme directories.")
# ---------------------------------------------------------------------------
# Check
# ---------------------------------------------------------------------------
def cmd_check():
themes = discover_themes()
drifted = []
missing = []
for theme in themes:
slug = theme["slug"]
title = theme["title"]
identifier = slug.replace("-", "_")
theme_dir = ROOT / slug
# .streamlit/config.toml
target = theme_dir / ".streamlit" / "config.toml"
expected = expected_config(slug)
if not target.exists():
missing.append(f"{slug}/.streamlit/config.toml")
elif target.read_text() != expected:
drifted.append(f"{slug}/.streamlit/config.toml")
# streamlit_app.py
target = theme_dir / "streamlit_app.py"
if not target.exists():
missing.append(f"{slug}/streamlit_app.py")
elif target.read_text() != expected_app(title):
drifted.append(f"{slug}/streamlit_app.py")
# pyproject.toml
target = theme_dir / "pyproject.toml"
expected = expected_from_template(
TEMPLATES / "pyproject.toml.tmpl",
{"slug": slug, "title": title},
)
if not target.exists():
missing.append(f"{slug}/pyproject.toml")
elif target.read_text() != expected:
drifted.append(f"{slug}/pyproject.toml")
# snowflake.yml
target = theme_dir / "snowflake.yml"
expected = expected_from_template(
TEMPLATES / "snowflake.yml.tmpl",
{"slug": slug, "title": title, "identifier": identifier},
)
if not target.exists():
missing.append(f"{slug}/snowflake.yml")
elif target.read_text() != expected:
drifted.append(f"{slug}/snowflake.yml")
# Fonts
config_text = (CONFIGS / f"{slug}.toml").read_text()
font_names = discover_fonts(config_text)
for fname in font_names:
src = FONTS / fname
dest = theme_dir / "static" / fname
if not dest.exists():
missing.append(f"{slug}/static/{fname}")
elif src.exists() and src.read_bytes() != dest.read_bytes():
drifted.append(f"{slug}/static/{fname}")
ok = True
if missing:
print("Missing files (run 'python manage.py sync' to fix):")
for f in missing:
print(f" {f}")
ok = False
if drifted:
print("Drifted files (run 'python manage.py sync' to fix):")
for f in drifted:
print(f" {f}")
ok = False
if ok:
print(f"All generated files in sync across {len(themes)} theme directories.")
else:
sys.exit(1)
# ---------------------------------------------------------------------------
# New
# ---------------------------------------------------------------------------
def cmd_new(name):
config_path = CONFIGS / f"{name}.toml"
if config_path.exists():
print(f"Error: _configs/{name}.toml already exists", file=sys.stderr)
sys.exit(1)
config_path.write_text(
f"[server]\nenableStaticServing = true\n\n"
f"# {name} theme\n[theme]\nbase = \"dark\"\n"
)
print(f"Created _configs/{name}.toml — edit it, then run 'python manage.py sync'")
# ---------------------------------------------------------------------------
# CLI
# ---------------------------------------------------------------------------
if __name__ == "__main__":
if len(sys.argv) < 2 or sys.argv[1] in ("-h", "--help"):
print(__doc__.strip())
sys.exit(0 if len(sys.argv) > 1 else 1)
if not SHARED.is_dir():
print(f"Error: {SHARED} not found", file=sys.stderr)
sys.exit(1)
if not CONFIGS.is_dir():
print(f"Error: {CONFIGS} not found", file=sys.stderr)
sys.exit(1)
cmd = sys.argv[1]
if cmd == "sync":
cmd_sync()
elif cmd == "new":
if len(sys.argv) < 3:
print("Usage: python manage.py new NAME", file=sys.stderr)
sys.exit(1)
cmd_new(sys.argv[2])
elif cmd == "check":
cmd_check()
else:
print(f"Unknown command: {cmd}", file=sys.stderr)
sys.exit(1)
@@ -0,0 +1,10 @@
[project]
name = "theme-minimal"
version = "1.0.0"
description = "Minimal theme for Streamlit"
requires-python = ">=3.11"
dependencies = [
"numpy>=1.26.0",
"pandas>=2.2.3",
"streamlit>=1.53.0",
]
@@ -0,0 +1,337 @@
"""
Streamlit Element Explorer - Theme Demo
A comprehensive single-page app showcasing all major Streamlit components
with custom theming. Use this to preview how your theme looks across
different element types.
"""
# DO NOT EDIT — managed by manage.py, edit _shared/streamlit_app.py instead
import numpy as np
import pandas as pd
import streamlit as st
st.set_page_config(page_title="Element Explorer", page_icon="🎨", layout="wide")
# Initialize sample data in session state
if "chart_data" not in st.session_state:
np.random.seed(42)
st.session_state.chart_data = pd.DataFrame(
np.random.randn(20, 3), columns=["a", "b", "c"]
)
chart_data = st.session_state.chart_data
st.title("Streamlit Element Explorer")
st.markdown(
"Explore how Streamlit's built-in elements look with this theme. "
"Select a category below to preview different components."
)
# Navigation using segmented_control for better performance
section = st.segmented_control(
"Section",
["Widgets", "Data", "Charts", "Text", "Layouts", "Chat", "Status"],
default="Widgets",
label_visibility="collapsed",
)
st.divider()
# -----------------------------------------------------------------------------
# WIDGETS SECTION
# -----------------------------------------------------------------------------
if section == "Widgets":
st.header("Widgets")
# Buttons
st.subheader("Buttons")
cols = st.columns(4)
cols[0].button("Primary", type="primary")
cols[1].button("Secondary", type="secondary")
cols[2].button("Tertiary", type="tertiary")
cols[3].link_button("Link", url="https://streamlit.io", icon=":material/open_in_new:")
# Form
with st.form(key="demo_form"):
st.subheader("Form")
form_cols = st.columns(2)
form_cols[0].text_input("Name", placeholder="Enter your name")
form_cols[1].text_input("Email", placeholder="you@example.com")
st.form_submit_button("Submit", type="primary")
# Selection widgets
st.subheader("Selection Widgets")
sel_cols = st.columns(2)
with sel_cols[0]:
st.checkbox("Checkbox option")
st.toggle("Toggle switch")
st.selectbox("Selectbox", options=["Option A", "Option B", "Option C"])
st.multiselect("Multiselect", options=["Tag 1", "Tag 2", "Tag 3"], default=["Tag 1"])
with sel_cols[1]:
st.radio("Radio buttons", options=["Choice 1", "Choice 2", "Choice 3"], horizontal=True)
st.pills("Pills", options=["Small", "Medium", "Large"], default="Medium")
st.segmented_control("Segmented", options=["Day", "Week", "Month"], default="Week")
st.caption("Feedback widget")
st.feedback("stars")
# Numeric & Sliders
st.subheader("Numeric Inputs")
num_cols = st.columns(3)
num_cols[0].number_input("Number input", value=42)
num_cols[1].slider("Slider", 0, 100, 50)
num_cols[2].select_slider("Select slider", options=["XS", "S", "M", "L", "XL"], value="M")
# Date/Time
st.subheader("Date & Time")
dt_cols = st.columns(2)
dt_cols[0].date_input("Date input")
dt_cols[1].time_input("Time input")
# Text inputs
st.subheader("Text Inputs")
txt_cols = st.columns(2)
txt_cols[0].text_input("Text input", placeholder="Type something...")
txt_cols[1].text_area("Text area", placeholder="Longer text goes here...", height=100)
# File upload
st.subheader("File Upload")
st.file_uploader("Upload a file", type=["csv", "txt", "pdf"])
# -----------------------------------------------------------------------------
# DATA SECTION
# -----------------------------------------------------------------------------
elif section == "Data":
st.header("Data Display")
# Metrics
st.subheader("Metrics")
m_cols = st.columns(4)
m_cols[0].metric("Revenue", "$45,231", "+12.5%")
m_cols[1].metric("Users", "2,847", "+8.2%")
m_cols[2].metric("Conversion", "3.24%", "-0.4%", delta_color="inverse")
m_cols[3].metric("Avg. Session", "4m 32s", "+1.2%")
st.divider()
# Dataframe
st.subheader("Dataframe")
df = pd.DataFrame({
"Name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
"Department": ["Engineering", "Sales", "Marketing", "Engineering", "Sales"],
"Salary": [95000, 78000, 82000, 105000, 71000],
"Start Date": pd.date_range("2022-01-15", periods=5, freq="3M"),
"Active": [True, True, False, True, True],
})
st.dataframe(
df,
hide_index=True,
column_config={
"Salary": st.column_config.NumberColumn(format="$%d"),
"Start Date": st.column_config.DateColumn(format="MMM DD, YYYY"),
"Active": st.column_config.CheckboxColumn("Active?"),
},
)
# Table
st.subheader("Static Table")
st.table(chart_data.head(5))
# JSON
st.subheader("JSON Display")
st.json({"name": "Streamlit", "version": "1.41.0", "features": ["themes", "widgets", "charts"]})
# -----------------------------------------------------------------------------
# CHARTS SECTION
# -----------------------------------------------------------------------------
elif section == "Charts":
st.header("Charts")
chart_cols = st.columns(2)
with chart_cols[0]:
st.subheader("Line Chart")
st.line_chart(chart_data, height=250)
st.subheader("Bar Chart")
st.bar_chart(chart_data, height=250)
with chart_cols[1]:
st.subheader("Area Chart")
st.area_chart(chart_data, height=250)
st.subheader("Scatter Chart")
st.scatter_chart(chart_data, height=250)
# -----------------------------------------------------------------------------
# TEXT SECTION
# -----------------------------------------------------------------------------
elif section == "Text":
st.header("Text Elements")
# Headers
st.subheader("Headers")
st.title("Title Element")
st.header("Header Element")
st.subheader("Subheader Element")
st.caption("Caption text - smaller, muted")
st.divider()
# Markdown
st.subheader("Markdown Formatting")
st.markdown(
"**Bold text**, *italic text*, ~~strikethrough~~, "
"`inline code`, [link](https://streamlit.io)"
)
st.markdown("Math: $E = mc^2$ and $\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}$")
st.markdown("Emojis: 🚀 🎨 📊 ✨ and icons: :material/home: :material/settings:")
# Colored text
st.subheader("Colored Text")
color_cols = st.columns(3)
color_cols[0].markdown(":red[Red text] and :orange[Orange text]")
color_cols[1].markdown(":green[Green text] and :blue[Blue text]")
color_cols[2].markdown(":violet[Violet text] and :rainbow[Rainbow text]")
# Code blocks
st.subheader("Code Block")
st.code(
'''import streamlit as st
# Create a themed dashboard
st.set_page_config(page_title="My App", layout="wide")
st.title("Hello, Streamlit!")
# Display metrics
col1, col2 = st.columns(2)
col1.metric("Users", "1,234", "+5%")
col2.metric("Revenue", "$56K", "+12%")''',
language="python",
)
# -----------------------------------------------------------------------------
# LAYOUTS SECTION
# -----------------------------------------------------------------------------
elif section == "Layouts":
st.header("Layout Elements")
# Columns
st.subheader("Columns with Borders")
layout_cols = st.columns(3, border=True)
layout_cols[0].write("**Column 1**\n\nFirst column content")
layout_cols[1].write("**Column 2**\n\nSecond column content")
layout_cols[2].write("**Column 3**\n\nThird column content")
# Tabs
st.subheader("Tabs")
tab1, tab2, tab3 = st.tabs(["📈 Chart", "📋 Data", "⚙️ Settings"])
with tab1:
st.write("Chart tab content")
st.line_chart(chart_data["a"], height=150)
with tab2:
st.write("Data tab content")
st.dataframe(chart_data.head(3))
with tab3:
st.write("Settings tab content")
st.checkbox("Enable feature X")
st.checkbox("Enable feature Y", value=True)
# Expander
st.subheader("Expander")
with st.expander("Click to expand"):
st.write("This content is hidden by default.")
st.image("https://placehold.co/400x200/29B5E8/white?text=Expanded+Content")
# Popover
st.subheader("Popover")
pop_cols = st.columns(3)
with pop_cols[0].popover("Open popover", icon=":material/info:"):
st.write("Popover content here!")
st.slider("Popover slider", 0, 100, 50)
# Container
st.subheader("Container with Border")
with st.container(border=True):
st.write("**Bordered Container**")
st.write("Content inside a container with a visible border.")
st.button("Button inside container")
# -----------------------------------------------------------------------------
# CHAT SECTION
# -----------------------------------------------------------------------------
elif section == "Chat":
st.header("Chat Elements")
# Chat messages
st.subheader("Chat Messages")
with st.chat_message("user"):
st.write("Hello! How can I analyze my sales data?")
with st.chat_message("assistant"):
st.write("I can help you with that! Here are a few options:")
st.markdown("""
1. **Revenue trends** - View monthly/quarterly patterns
2. **Top products** - Identify best sellers
3. **Customer segments** - Analyze by region or category
""")
with st.chat_message("user"):
st.write("Show me the revenue trends please.")
with st.chat_message("assistant"):
st.write("Here's your revenue trend for the past 20 periods:")
st.line_chart(chart_data["a"], height=200)
# Chat input
st.chat_input("Type a message...")
# -----------------------------------------------------------------------------
# STATUS SECTION
# -----------------------------------------------------------------------------
elif section == "Status":
st.header("Status Elements")
# Alert messages
st.subheader("Alert Messages")
st.error("Error: Something went wrong with the data pipeline.")
st.warning("Warning: API rate limit approaching (80% used).")
st.info("Info: New features available in the latest release.")
st.success("Success: Data exported successfully to warehouse.")
# Exception
st.subheader("Exception Display")
try:
raise ValueError("This is an example exception for demonstration")
except ValueError as e:
st.exception(e)
# Interactive status
st.subheader("Interactive Status")
status_cols = st.columns(3)
if status_cols[0].button("Show Toast", icon=":material/notifications:"):
st.toast("This is a toast notification!", icon="🔔")
if status_cols[1].button("Balloons", icon=":material/celebration:"):
st.balloons()
if status_cols[2].button("Snow", icon=":material/ac_unit:"):
st.snow()
# Progress
st.subheader("Progress Indicators")
st.progress(0.7, text="70% complete")
with st.spinner("Loading..."):
st.write("Spinner is active (non-blocking in this demo)")
# -----------------------------------------------------------------------------
# SIDEBAR
# -----------------------------------------------------------------------------
with st.sidebar:
st.header("Settings")
st.selectbox("Time Period", ["Last 7 days", "Last 30 days", "Last 90 days", "All time"])
st.multiselect("Metrics", ["Revenue", "Users", "Sessions"], default=["Revenue", "Users"])
st.slider("Confidence threshold", 0.0, 1.0, 0.8)
st.divider()
st.caption("Element Explorer v1.0")
st.caption("Theme: **Minimal**")
@@ -0,0 +1,10 @@
[project]
name = "theme-nord"
version = "1.0.0"
description = "Nord theme for Streamlit"
requires-python = ">=3.11"
dependencies = [
"numpy>=1.26.0",
"pandas>=2.2.3",
"streamlit>=1.53.0",
]
@@ -0,0 +1,337 @@
"""
Streamlit Element Explorer - Theme Demo
A comprehensive single-page app showcasing all major Streamlit components
with custom theming. Use this to preview how your theme looks across
different element types.
"""
# DO NOT EDIT — managed by manage.py, edit _shared/streamlit_app.py instead
import numpy as np
import pandas as pd
import streamlit as st
st.set_page_config(page_title="Element Explorer", page_icon="🎨", layout="wide")
# Initialize sample data in session state
if "chart_data" not in st.session_state:
np.random.seed(42)
st.session_state.chart_data = pd.DataFrame(
np.random.randn(20, 3), columns=["a", "b", "c"]
)
chart_data = st.session_state.chart_data
st.title("Streamlit Element Explorer")
st.markdown(
"Explore how Streamlit's built-in elements look with this theme. "
"Select a category below to preview different components."
)
# Navigation using segmented_control for better performance
section = st.segmented_control(
"Section",
["Widgets", "Data", "Charts", "Text", "Layouts", "Chat", "Status"],
default="Widgets",
label_visibility="collapsed",
)
st.divider()
# -----------------------------------------------------------------------------
# WIDGETS SECTION
# -----------------------------------------------------------------------------
if section == "Widgets":
st.header("Widgets")
# Buttons
st.subheader("Buttons")
cols = st.columns(4)
cols[0].button("Primary", type="primary")
cols[1].button("Secondary", type="secondary")
cols[2].button("Tertiary", type="tertiary")
cols[3].link_button("Link", url="https://streamlit.io", icon=":material/open_in_new:")
# Form
with st.form(key="demo_form"):
st.subheader("Form")
form_cols = st.columns(2)
form_cols[0].text_input("Name", placeholder="Enter your name")
form_cols[1].text_input("Email", placeholder="you@example.com")
st.form_submit_button("Submit", type="primary")
# Selection widgets
st.subheader("Selection Widgets")
sel_cols = st.columns(2)
with sel_cols[0]:
st.checkbox("Checkbox option")
st.toggle("Toggle switch")
st.selectbox("Selectbox", options=["Option A", "Option B", "Option C"])
st.multiselect("Multiselect", options=["Tag 1", "Tag 2", "Tag 3"], default=["Tag 1"])
with sel_cols[1]:
st.radio("Radio buttons", options=["Choice 1", "Choice 2", "Choice 3"], horizontal=True)
st.pills("Pills", options=["Small", "Medium", "Large"], default="Medium")
st.segmented_control("Segmented", options=["Day", "Week", "Month"], default="Week")
st.caption("Feedback widget")
st.feedback("stars")
# Numeric & Sliders
st.subheader("Numeric Inputs")
num_cols = st.columns(3)
num_cols[0].number_input("Number input", value=42)
num_cols[1].slider("Slider", 0, 100, 50)
num_cols[2].select_slider("Select slider", options=["XS", "S", "M", "L", "XL"], value="M")
# Date/Time
st.subheader("Date & Time")
dt_cols = st.columns(2)
dt_cols[0].date_input("Date input")
dt_cols[1].time_input("Time input")
# Text inputs
st.subheader("Text Inputs")
txt_cols = st.columns(2)
txt_cols[0].text_input("Text input", placeholder="Type something...")
txt_cols[1].text_area("Text area", placeholder="Longer text goes here...", height=100)
# File upload
st.subheader("File Upload")
st.file_uploader("Upload a file", type=["csv", "txt", "pdf"])
# -----------------------------------------------------------------------------
# DATA SECTION
# -----------------------------------------------------------------------------
elif section == "Data":
st.header("Data Display")
# Metrics
st.subheader("Metrics")
m_cols = st.columns(4)
m_cols[0].metric("Revenue", "$45,231", "+12.5%")
m_cols[1].metric("Users", "2,847", "+8.2%")
m_cols[2].metric("Conversion", "3.24%", "-0.4%", delta_color="inverse")
m_cols[3].metric("Avg. Session", "4m 32s", "+1.2%")
st.divider()
# Dataframe
st.subheader("Dataframe")
df = pd.DataFrame({
"Name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
"Department": ["Engineering", "Sales", "Marketing", "Engineering", "Sales"],
"Salary": [95000, 78000, 82000, 105000, 71000],
"Start Date": pd.date_range("2022-01-15", periods=5, freq="3M"),
"Active": [True, True, False, True, True],
})
st.dataframe(
df,
hide_index=True,
column_config={
"Salary": st.column_config.NumberColumn(format="$%d"),
"Start Date": st.column_config.DateColumn(format="MMM DD, YYYY"),
"Active": st.column_config.CheckboxColumn("Active?"),
},
)
# Table
st.subheader("Static Table")
st.table(chart_data.head(5))
# JSON
st.subheader("JSON Display")
st.json({"name": "Streamlit", "version": "1.41.0", "features": ["themes", "widgets", "charts"]})
# -----------------------------------------------------------------------------
# CHARTS SECTION
# -----------------------------------------------------------------------------
elif section == "Charts":
st.header("Charts")
chart_cols = st.columns(2)
with chart_cols[0]:
st.subheader("Line Chart")
st.line_chart(chart_data, height=250)
st.subheader("Bar Chart")
st.bar_chart(chart_data, height=250)
with chart_cols[1]:
st.subheader("Area Chart")
st.area_chart(chart_data, height=250)
st.subheader("Scatter Chart")
st.scatter_chart(chart_data, height=250)
# -----------------------------------------------------------------------------
# TEXT SECTION
# -----------------------------------------------------------------------------
elif section == "Text":
st.header("Text Elements")
# Headers
st.subheader("Headers")
st.title("Title Element")
st.header("Header Element")
st.subheader("Subheader Element")
st.caption("Caption text - smaller, muted")
st.divider()
# Markdown
st.subheader("Markdown Formatting")
st.markdown(
"**Bold text**, *italic text*, ~~strikethrough~~, "
"`inline code`, [link](https://streamlit.io)"
)
st.markdown("Math: $E = mc^2$ and $\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}$")
st.markdown("Emojis: 🚀 🎨 📊 ✨ and icons: :material/home: :material/settings:")
# Colored text
st.subheader("Colored Text")
color_cols = st.columns(3)
color_cols[0].markdown(":red[Red text] and :orange[Orange text]")
color_cols[1].markdown(":green[Green text] and :blue[Blue text]")
color_cols[2].markdown(":violet[Violet text] and :rainbow[Rainbow text]")
# Code blocks
st.subheader("Code Block")
st.code(
'''import streamlit as st
# Create a themed dashboard
st.set_page_config(page_title="My App", layout="wide")
st.title("Hello, Streamlit!")
# Display metrics
col1, col2 = st.columns(2)
col1.metric("Users", "1,234", "+5%")
col2.metric("Revenue", "$56K", "+12%")''',
language="python",
)
# -----------------------------------------------------------------------------
# LAYOUTS SECTION
# -----------------------------------------------------------------------------
elif section == "Layouts":
st.header("Layout Elements")
# Columns
st.subheader("Columns with Borders")
layout_cols = st.columns(3, border=True)
layout_cols[0].write("**Column 1**\n\nFirst column content")
layout_cols[1].write("**Column 2**\n\nSecond column content")
layout_cols[2].write("**Column 3**\n\nThird column content")
# Tabs
st.subheader("Tabs")
tab1, tab2, tab3 = st.tabs(["📈 Chart", "📋 Data", "⚙️ Settings"])
with tab1:
st.write("Chart tab content")
st.line_chart(chart_data["a"], height=150)
with tab2:
st.write("Data tab content")
st.dataframe(chart_data.head(3))
with tab3:
st.write("Settings tab content")
st.checkbox("Enable feature X")
st.checkbox("Enable feature Y", value=True)
# Expander
st.subheader("Expander")
with st.expander("Click to expand"):
st.write("This content is hidden by default.")
st.image("https://placehold.co/400x200/29B5E8/white?text=Expanded+Content")
# Popover
st.subheader("Popover")
pop_cols = st.columns(3)
with pop_cols[0].popover("Open popover", icon=":material/info:"):
st.write("Popover content here!")
st.slider("Popover slider", 0, 100, 50)
# Container
st.subheader("Container with Border")
with st.container(border=True):
st.write("**Bordered Container**")
st.write("Content inside a container with a visible border.")
st.button("Button inside container")
# -----------------------------------------------------------------------------
# CHAT SECTION
# -----------------------------------------------------------------------------
elif section == "Chat":
st.header("Chat Elements")
# Chat messages
st.subheader("Chat Messages")
with st.chat_message("user"):
st.write("Hello! How can I analyze my sales data?")
with st.chat_message("assistant"):
st.write("I can help you with that! Here are a few options:")
st.markdown("""
1. **Revenue trends** - View monthly/quarterly patterns
2. **Top products** - Identify best sellers
3. **Customer segments** - Analyze by region or category
""")
with st.chat_message("user"):
st.write("Show me the revenue trends please.")
with st.chat_message("assistant"):
st.write("Here's your revenue trend for the past 20 periods:")
st.line_chart(chart_data["a"], height=200)
# Chat input
st.chat_input("Type a message...")
# -----------------------------------------------------------------------------
# STATUS SECTION
# -----------------------------------------------------------------------------
elif section == "Status":
st.header("Status Elements")
# Alert messages
st.subheader("Alert Messages")
st.error("Error: Something went wrong with the data pipeline.")
st.warning("Warning: API rate limit approaching (80% used).")
st.info("Info: New features available in the latest release.")
st.success("Success: Data exported successfully to warehouse.")
# Exception
st.subheader("Exception Display")
try:
raise ValueError("This is an example exception for demonstration")
except ValueError as e:
st.exception(e)
# Interactive status
st.subheader("Interactive Status")
status_cols = st.columns(3)
if status_cols[0].button("Show Toast", icon=":material/notifications:"):
st.toast("This is a toast notification!", icon="🔔")
if status_cols[1].button("Balloons", icon=":material/celebration:"):
st.balloons()
if status_cols[2].button("Snow", icon=":material/ac_unit:"):
st.snow()
# Progress
st.subheader("Progress Indicators")
st.progress(0.7, text="70% complete")
with st.spinner("Loading..."):
st.write("Spinner is active (non-blocking in this demo)")
# -----------------------------------------------------------------------------
# SIDEBAR
# -----------------------------------------------------------------------------
with st.sidebar:
st.header("Settings")
st.selectbox("Time Period", ["Last 7 days", "Last 30 days", "Last 90 days", "All time"])
st.multiselect("Metrics", ["Revenue", "Users", "Sessions"], default=["Revenue", "Users"])
st.slider("Confidence threshold", 0.0, 1.0, 0.8)
st.divider()
st.caption("Element Explorer v1.0")
st.caption("Theme: **Nord**")
@@ -0,0 +1,10 @@
[project]
name = "theme-snowflake"
version = "1.0.0"
description = "Snowflake theme for Streamlit"
requires-python = ">=3.11"
dependencies = [
"numpy>=1.26.0",
"pandas>=2.2.3",
"streamlit>=1.53.0",
]
@@ -0,0 +1,337 @@
"""
Streamlit Element Explorer - Theme Demo
A comprehensive single-page app showcasing all major Streamlit components
with custom theming. Use this to preview how your theme looks across
different element types.
"""
# DO NOT EDIT — managed by manage.py, edit _shared/streamlit_app.py instead
import numpy as np
import pandas as pd
import streamlit as st
st.set_page_config(page_title="Element Explorer", page_icon="🎨", layout="wide")
# Initialize sample data in session state
if "chart_data" not in st.session_state:
np.random.seed(42)
st.session_state.chart_data = pd.DataFrame(
np.random.randn(20, 3), columns=["a", "b", "c"]
)
chart_data = st.session_state.chart_data
st.title("Streamlit Element Explorer")
st.markdown(
"Explore how Streamlit's built-in elements look with this theme. "
"Select a category below to preview different components."
)
# Navigation using segmented_control for better performance
section = st.segmented_control(
"Section",
["Widgets", "Data", "Charts", "Text", "Layouts", "Chat", "Status"],
default="Widgets",
label_visibility="collapsed",
)
st.divider()
# -----------------------------------------------------------------------------
# WIDGETS SECTION
# -----------------------------------------------------------------------------
if section == "Widgets":
st.header("Widgets")
# Buttons
st.subheader("Buttons")
cols = st.columns(4)
cols[0].button("Primary", type="primary")
cols[1].button("Secondary", type="secondary")
cols[2].button("Tertiary", type="tertiary")
cols[3].link_button("Link", url="https://streamlit.io", icon=":material/open_in_new:")
# Form
with st.form(key="demo_form"):
st.subheader("Form")
form_cols = st.columns(2)
form_cols[0].text_input("Name", placeholder="Enter your name")
form_cols[1].text_input("Email", placeholder="you@example.com")
st.form_submit_button("Submit", type="primary")
# Selection widgets
st.subheader("Selection Widgets")
sel_cols = st.columns(2)
with sel_cols[0]:
st.checkbox("Checkbox option")
st.toggle("Toggle switch")
st.selectbox("Selectbox", options=["Option A", "Option B", "Option C"])
st.multiselect("Multiselect", options=["Tag 1", "Tag 2", "Tag 3"], default=["Tag 1"])
with sel_cols[1]:
st.radio("Radio buttons", options=["Choice 1", "Choice 2", "Choice 3"], horizontal=True)
st.pills("Pills", options=["Small", "Medium", "Large"], default="Medium")
st.segmented_control("Segmented", options=["Day", "Week", "Month"], default="Week")
st.caption("Feedback widget")
st.feedback("stars")
# Numeric & Sliders
st.subheader("Numeric Inputs")
num_cols = st.columns(3)
num_cols[0].number_input("Number input", value=42)
num_cols[1].slider("Slider", 0, 100, 50)
num_cols[2].select_slider("Select slider", options=["XS", "S", "M", "L", "XL"], value="M")
# Date/Time
st.subheader("Date & Time")
dt_cols = st.columns(2)
dt_cols[0].date_input("Date input")
dt_cols[1].time_input("Time input")
# Text inputs
st.subheader("Text Inputs")
txt_cols = st.columns(2)
txt_cols[0].text_input("Text input", placeholder="Type something...")
txt_cols[1].text_area("Text area", placeholder="Longer text goes here...", height=100)
# File upload
st.subheader("File Upload")
st.file_uploader("Upload a file", type=["csv", "txt", "pdf"])
# -----------------------------------------------------------------------------
# DATA SECTION
# -----------------------------------------------------------------------------
elif section == "Data":
st.header("Data Display")
# Metrics
st.subheader("Metrics")
m_cols = st.columns(4)
m_cols[0].metric("Revenue", "$45,231", "+12.5%")
m_cols[1].metric("Users", "2,847", "+8.2%")
m_cols[2].metric("Conversion", "3.24%", "-0.4%", delta_color="inverse")
m_cols[3].metric("Avg. Session", "4m 32s", "+1.2%")
st.divider()
# Dataframe
st.subheader("Dataframe")
df = pd.DataFrame({
"Name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
"Department": ["Engineering", "Sales", "Marketing", "Engineering", "Sales"],
"Salary": [95000, 78000, 82000, 105000, 71000],
"Start Date": pd.date_range("2022-01-15", periods=5, freq="3M"),
"Active": [True, True, False, True, True],
})
st.dataframe(
df,
hide_index=True,
column_config={
"Salary": st.column_config.NumberColumn(format="$%d"),
"Start Date": st.column_config.DateColumn(format="MMM DD, YYYY"),
"Active": st.column_config.CheckboxColumn("Active?"),
},
)
# Table
st.subheader("Static Table")
st.table(chart_data.head(5))
# JSON
st.subheader("JSON Display")
st.json({"name": "Streamlit", "version": "1.41.0", "features": ["themes", "widgets", "charts"]})
# -----------------------------------------------------------------------------
# CHARTS SECTION
# -----------------------------------------------------------------------------
elif section == "Charts":
st.header("Charts")
chart_cols = st.columns(2)
with chart_cols[0]:
st.subheader("Line Chart")
st.line_chart(chart_data, height=250)
st.subheader("Bar Chart")
st.bar_chart(chart_data, height=250)
with chart_cols[1]:
st.subheader("Area Chart")
st.area_chart(chart_data, height=250)
st.subheader("Scatter Chart")
st.scatter_chart(chart_data, height=250)
# -----------------------------------------------------------------------------
# TEXT SECTION
# -----------------------------------------------------------------------------
elif section == "Text":
st.header("Text Elements")
# Headers
st.subheader("Headers")
st.title("Title Element")
st.header("Header Element")
st.subheader("Subheader Element")
st.caption("Caption text - smaller, muted")
st.divider()
# Markdown
st.subheader("Markdown Formatting")
st.markdown(
"**Bold text**, *italic text*, ~~strikethrough~~, "
"`inline code`, [link](https://streamlit.io)"
)
st.markdown("Math: $E = mc^2$ and $\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}$")
st.markdown("Emojis: 🚀 🎨 📊 ✨ and icons: :material/home: :material/settings:")
# Colored text
st.subheader("Colored Text")
color_cols = st.columns(3)
color_cols[0].markdown(":red[Red text] and :orange[Orange text]")
color_cols[1].markdown(":green[Green text] and :blue[Blue text]")
color_cols[2].markdown(":violet[Violet text] and :rainbow[Rainbow text]")
# Code blocks
st.subheader("Code Block")
st.code(
'''import streamlit as st
# Create a themed dashboard
st.set_page_config(page_title="My App", layout="wide")
st.title("Hello, Streamlit!")
# Display metrics
col1, col2 = st.columns(2)
col1.metric("Users", "1,234", "+5%")
col2.metric("Revenue", "$56K", "+12%")''',
language="python",
)
# -----------------------------------------------------------------------------
# LAYOUTS SECTION
# -----------------------------------------------------------------------------
elif section == "Layouts":
st.header("Layout Elements")
# Columns
st.subheader("Columns with Borders")
layout_cols = st.columns(3, border=True)
layout_cols[0].write("**Column 1**\n\nFirst column content")
layout_cols[1].write("**Column 2**\n\nSecond column content")
layout_cols[2].write("**Column 3**\n\nThird column content")
# Tabs
st.subheader("Tabs")
tab1, tab2, tab3 = st.tabs(["📈 Chart", "📋 Data", "⚙️ Settings"])
with tab1:
st.write("Chart tab content")
st.line_chart(chart_data["a"], height=150)
with tab2:
st.write("Data tab content")
st.dataframe(chart_data.head(3))
with tab3:
st.write("Settings tab content")
st.checkbox("Enable feature X")
st.checkbox("Enable feature Y", value=True)
# Expander
st.subheader("Expander")
with st.expander("Click to expand"):
st.write("This content is hidden by default.")
st.image("https://placehold.co/400x200/29B5E8/white?text=Expanded+Content")
# Popover
st.subheader("Popover")
pop_cols = st.columns(3)
with pop_cols[0].popover("Open popover", icon=":material/info:"):
st.write("Popover content here!")
st.slider("Popover slider", 0, 100, 50)
# Container
st.subheader("Container with Border")
with st.container(border=True):
st.write("**Bordered Container**")
st.write("Content inside a container with a visible border.")
st.button("Button inside container")
# -----------------------------------------------------------------------------
# CHAT SECTION
# -----------------------------------------------------------------------------
elif section == "Chat":
st.header("Chat Elements")
# Chat messages
st.subheader("Chat Messages")
with st.chat_message("user"):
st.write("Hello! How can I analyze my sales data?")
with st.chat_message("assistant"):
st.write("I can help you with that! Here are a few options:")
st.markdown("""
1. **Revenue trends** - View monthly/quarterly patterns
2. **Top products** - Identify best sellers
3. **Customer segments** - Analyze by region or category
""")
with st.chat_message("user"):
st.write("Show me the revenue trends please.")
with st.chat_message("assistant"):
st.write("Here's your revenue trend for the past 20 periods:")
st.line_chart(chart_data["a"], height=200)
# Chat input
st.chat_input("Type a message...")
# -----------------------------------------------------------------------------
# STATUS SECTION
# -----------------------------------------------------------------------------
elif section == "Status":
st.header("Status Elements")
# Alert messages
st.subheader("Alert Messages")
st.error("Error: Something went wrong with the data pipeline.")
st.warning("Warning: API rate limit approaching (80% used).")
st.info("Info: New features available in the latest release.")
st.success("Success: Data exported successfully to warehouse.")
# Exception
st.subheader("Exception Display")
try:
raise ValueError("This is an example exception for demonstration")
except ValueError as e:
st.exception(e)
# Interactive status
st.subheader("Interactive Status")
status_cols = st.columns(3)
if status_cols[0].button("Show Toast", icon=":material/notifications:"):
st.toast("This is a toast notification!", icon="🔔")
if status_cols[1].button("Balloons", icon=":material/celebration:"):
st.balloons()
if status_cols[2].button("Snow", icon=":material/ac_unit:"):
st.snow()
# Progress
st.subheader("Progress Indicators")
st.progress(0.7, text="70% complete")
with st.spinner("Loading..."):
st.write("Spinner is active (non-blocking in this demo)")
# -----------------------------------------------------------------------------
# SIDEBAR
# -----------------------------------------------------------------------------
with st.sidebar:
st.header("Settings")
st.selectbox("Time Period", ["Last 7 days", "Last 30 days", "Last 90 days", "All time"])
st.multiselect("Metrics", ["Revenue", "Users", "Sessions"], default=["Revenue", "Users"])
st.slider("Confidence threshold", 0.0, 1.0, 0.8)
st.divider()
st.caption("Element Explorer v1.0")
st.caption("Theme: **Snowflake**")
@@ -0,0 +1,10 @@
[project]
name = "theme-solarized-light"
version = "1.0.0"
description = "Solarized Light theme for Streamlit"
requires-python = ">=3.11"
dependencies = [
"numpy>=1.26.0",
"pandas>=2.2.3",
"streamlit>=1.53.0",
]
@@ -0,0 +1,337 @@
"""
Streamlit Element Explorer - Theme Demo
A comprehensive single-page app showcasing all major Streamlit components
with custom theming. Use this to preview how your theme looks across
different element types.
"""
# DO NOT EDIT — managed by manage.py, edit _shared/streamlit_app.py instead
import numpy as np
import pandas as pd
import streamlit as st
st.set_page_config(page_title="Element Explorer", page_icon="🎨", layout="wide")
# Initialize sample data in session state
if "chart_data" not in st.session_state:
np.random.seed(42)
st.session_state.chart_data = pd.DataFrame(
np.random.randn(20, 3), columns=["a", "b", "c"]
)
chart_data = st.session_state.chart_data
st.title("Streamlit Element Explorer")
st.markdown(
"Explore how Streamlit's built-in elements look with this theme. "
"Select a category below to preview different components."
)
# Navigation using segmented_control for better performance
section = st.segmented_control(
"Section",
["Widgets", "Data", "Charts", "Text", "Layouts", "Chat", "Status"],
default="Widgets",
label_visibility="collapsed",
)
st.divider()
# -----------------------------------------------------------------------------
# WIDGETS SECTION
# -----------------------------------------------------------------------------
if section == "Widgets":
st.header("Widgets")
# Buttons
st.subheader("Buttons")
cols = st.columns(4)
cols[0].button("Primary", type="primary")
cols[1].button("Secondary", type="secondary")
cols[2].button("Tertiary", type="tertiary")
cols[3].link_button("Link", url="https://streamlit.io", icon=":material/open_in_new:")
# Form
with st.form(key="demo_form"):
st.subheader("Form")
form_cols = st.columns(2)
form_cols[0].text_input("Name", placeholder="Enter your name")
form_cols[1].text_input("Email", placeholder="you@example.com")
st.form_submit_button("Submit", type="primary")
# Selection widgets
st.subheader("Selection Widgets")
sel_cols = st.columns(2)
with sel_cols[0]:
st.checkbox("Checkbox option")
st.toggle("Toggle switch")
st.selectbox("Selectbox", options=["Option A", "Option B", "Option C"])
st.multiselect("Multiselect", options=["Tag 1", "Tag 2", "Tag 3"], default=["Tag 1"])
with sel_cols[1]:
st.radio("Radio buttons", options=["Choice 1", "Choice 2", "Choice 3"], horizontal=True)
st.pills("Pills", options=["Small", "Medium", "Large"], default="Medium")
st.segmented_control("Segmented", options=["Day", "Week", "Month"], default="Week")
st.caption("Feedback widget")
st.feedback("stars")
# Numeric & Sliders
st.subheader("Numeric Inputs")
num_cols = st.columns(3)
num_cols[0].number_input("Number input", value=42)
num_cols[1].slider("Slider", 0, 100, 50)
num_cols[2].select_slider("Select slider", options=["XS", "S", "M", "L", "XL"], value="M")
# Date/Time
st.subheader("Date & Time")
dt_cols = st.columns(2)
dt_cols[0].date_input("Date input")
dt_cols[1].time_input("Time input")
# Text inputs
st.subheader("Text Inputs")
txt_cols = st.columns(2)
txt_cols[0].text_input("Text input", placeholder="Type something...")
txt_cols[1].text_area("Text area", placeholder="Longer text goes here...", height=100)
# File upload
st.subheader("File Upload")
st.file_uploader("Upload a file", type=["csv", "txt", "pdf"])
# -----------------------------------------------------------------------------
# DATA SECTION
# -----------------------------------------------------------------------------
elif section == "Data":
st.header("Data Display")
# Metrics
st.subheader("Metrics")
m_cols = st.columns(4)
m_cols[0].metric("Revenue", "$45,231", "+12.5%")
m_cols[1].metric("Users", "2,847", "+8.2%")
m_cols[2].metric("Conversion", "3.24%", "-0.4%", delta_color="inverse")
m_cols[3].metric("Avg. Session", "4m 32s", "+1.2%")
st.divider()
# Dataframe
st.subheader("Dataframe")
df = pd.DataFrame({
"Name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
"Department": ["Engineering", "Sales", "Marketing", "Engineering", "Sales"],
"Salary": [95000, 78000, 82000, 105000, 71000],
"Start Date": pd.date_range("2022-01-15", periods=5, freq="3M"),
"Active": [True, True, False, True, True],
})
st.dataframe(
df,
hide_index=True,
column_config={
"Salary": st.column_config.NumberColumn(format="$%d"),
"Start Date": st.column_config.DateColumn(format="MMM DD, YYYY"),
"Active": st.column_config.CheckboxColumn("Active?"),
},
)
# Table
st.subheader("Static Table")
st.table(chart_data.head(5))
# JSON
st.subheader("JSON Display")
st.json({"name": "Streamlit", "version": "1.41.0", "features": ["themes", "widgets", "charts"]})
# -----------------------------------------------------------------------------
# CHARTS SECTION
# -----------------------------------------------------------------------------
elif section == "Charts":
st.header("Charts")
chart_cols = st.columns(2)
with chart_cols[0]:
st.subheader("Line Chart")
st.line_chart(chart_data, height=250)
st.subheader("Bar Chart")
st.bar_chart(chart_data, height=250)
with chart_cols[1]:
st.subheader("Area Chart")
st.area_chart(chart_data, height=250)
st.subheader("Scatter Chart")
st.scatter_chart(chart_data, height=250)
# -----------------------------------------------------------------------------
# TEXT SECTION
# -----------------------------------------------------------------------------
elif section == "Text":
st.header("Text Elements")
# Headers
st.subheader("Headers")
st.title("Title Element")
st.header("Header Element")
st.subheader("Subheader Element")
st.caption("Caption text - smaller, muted")
st.divider()
# Markdown
st.subheader("Markdown Formatting")
st.markdown(
"**Bold text**, *italic text*, ~~strikethrough~~, "
"`inline code`, [link](https://streamlit.io)"
)
st.markdown("Math: $E = mc^2$ and $\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}$")
st.markdown("Emojis: 🚀 🎨 📊 ✨ and icons: :material/home: :material/settings:")
# Colored text
st.subheader("Colored Text")
color_cols = st.columns(3)
color_cols[0].markdown(":red[Red text] and :orange[Orange text]")
color_cols[1].markdown(":green[Green text] and :blue[Blue text]")
color_cols[2].markdown(":violet[Violet text] and :rainbow[Rainbow text]")
# Code blocks
st.subheader("Code Block")
st.code(
'''import streamlit as st
# Create a themed dashboard
st.set_page_config(page_title="My App", layout="wide")
st.title("Hello, Streamlit!")
# Display metrics
col1, col2 = st.columns(2)
col1.metric("Users", "1,234", "+5%")
col2.metric("Revenue", "$56K", "+12%")''',
language="python",
)
# -----------------------------------------------------------------------------
# LAYOUTS SECTION
# -----------------------------------------------------------------------------
elif section == "Layouts":
st.header("Layout Elements")
# Columns
st.subheader("Columns with Borders")
layout_cols = st.columns(3, border=True)
layout_cols[0].write("**Column 1**\n\nFirst column content")
layout_cols[1].write("**Column 2**\n\nSecond column content")
layout_cols[2].write("**Column 3**\n\nThird column content")
# Tabs
st.subheader("Tabs")
tab1, tab2, tab3 = st.tabs(["📈 Chart", "📋 Data", "⚙️ Settings"])
with tab1:
st.write("Chart tab content")
st.line_chart(chart_data["a"], height=150)
with tab2:
st.write("Data tab content")
st.dataframe(chart_data.head(3))
with tab3:
st.write("Settings tab content")
st.checkbox("Enable feature X")
st.checkbox("Enable feature Y", value=True)
# Expander
st.subheader("Expander")
with st.expander("Click to expand"):
st.write("This content is hidden by default.")
st.image("https://placehold.co/400x200/29B5E8/white?text=Expanded+Content")
# Popover
st.subheader("Popover")
pop_cols = st.columns(3)
with pop_cols[0].popover("Open popover", icon=":material/info:"):
st.write("Popover content here!")
st.slider("Popover slider", 0, 100, 50)
# Container
st.subheader("Container with Border")
with st.container(border=True):
st.write("**Bordered Container**")
st.write("Content inside a container with a visible border.")
st.button("Button inside container")
# -----------------------------------------------------------------------------
# CHAT SECTION
# -----------------------------------------------------------------------------
elif section == "Chat":
st.header("Chat Elements")
# Chat messages
st.subheader("Chat Messages")
with st.chat_message("user"):
st.write("Hello! How can I analyze my sales data?")
with st.chat_message("assistant"):
st.write("I can help you with that! Here are a few options:")
st.markdown("""
1. **Revenue trends** - View monthly/quarterly patterns
2. **Top products** - Identify best sellers
3. **Customer segments** - Analyze by region or category
""")
with st.chat_message("user"):
st.write("Show me the revenue trends please.")
with st.chat_message("assistant"):
st.write("Here's your revenue trend for the past 20 periods:")
st.line_chart(chart_data["a"], height=200)
# Chat input
st.chat_input("Type a message...")
# -----------------------------------------------------------------------------
# STATUS SECTION
# -----------------------------------------------------------------------------
elif section == "Status":
st.header("Status Elements")
# Alert messages
st.subheader("Alert Messages")
st.error("Error: Something went wrong with the data pipeline.")
st.warning("Warning: API rate limit approaching (80% used).")
st.info("Info: New features available in the latest release.")
st.success("Success: Data exported successfully to warehouse.")
# Exception
st.subheader("Exception Display")
try:
raise ValueError("This is an example exception for demonstration")
except ValueError as e:
st.exception(e)
# Interactive status
st.subheader("Interactive Status")
status_cols = st.columns(3)
if status_cols[0].button("Show Toast", icon=":material/notifications:"):
st.toast("This is a toast notification!", icon="🔔")
if status_cols[1].button("Balloons", icon=":material/celebration:"):
st.balloons()
if status_cols[2].button("Snow", icon=":material/ac_unit:"):
st.snow()
# Progress
st.subheader("Progress Indicators")
st.progress(0.7, text="70% complete")
with st.spinner("Loading..."):
st.write("Spinner is active (non-blocking in this demo)")
# -----------------------------------------------------------------------------
# SIDEBAR
# -----------------------------------------------------------------------------
with st.sidebar:
st.header("Settings")
st.selectbox("Time Period", ["Last 7 days", "Last 30 days", "Last 90 days", "All time"])
st.multiselect("Metrics", ["Revenue", "Users", "Sessions"], default=["Revenue", "Users"])
st.slider("Confidence threshold", 0.0, 1.0, 0.8)
st.divider()
st.caption("Element Explorer v1.0")
st.caption("Theme: **Solarized Light**")
@@ -0,0 +1,10 @@
[project]
name = "theme-spotify"
version = "1.0.0"
description = "Spotify theme for Streamlit"
requires-python = ">=3.11"
dependencies = [
"numpy>=1.26.0",
"pandas>=2.2.3",
"streamlit>=1.53.0",
]
@@ -0,0 +1,337 @@
"""
Streamlit Element Explorer - Theme Demo
A comprehensive single-page app showcasing all major Streamlit components
with custom theming. Use this to preview how your theme looks across
different element types.
"""
# DO NOT EDIT — managed by manage.py, edit _shared/streamlit_app.py instead
import numpy as np
import pandas as pd
import streamlit as st
st.set_page_config(page_title="Element Explorer", page_icon="🎨", layout="wide")
# Initialize sample data in session state
if "chart_data" not in st.session_state:
np.random.seed(42)
st.session_state.chart_data = pd.DataFrame(
np.random.randn(20, 3), columns=["a", "b", "c"]
)
chart_data = st.session_state.chart_data
st.title("Streamlit Element Explorer")
st.markdown(
"Explore how Streamlit's built-in elements look with this theme. "
"Select a category below to preview different components."
)
# Navigation using segmented_control for better performance
section = st.segmented_control(
"Section",
["Widgets", "Data", "Charts", "Text", "Layouts", "Chat", "Status"],
default="Widgets",
label_visibility="collapsed",
)
st.divider()
# -----------------------------------------------------------------------------
# WIDGETS SECTION
# -----------------------------------------------------------------------------
if section == "Widgets":
st.header("Widgets")
# Buttons
st.subheader("Buttons")
cols = st.columns(4)
cols[0].button("Primary", type="primary")
cols[1].button("Secondary", type="secondary")
cols[2].button("Tertiary", type="tertiary")
cols[3].link_button("Link", url="https://streamlit.io", icon=":material/open_in_new:")
# Form
with st.form(key="demo_form"):
st.subheader("Form")
form_cols = st.columns(2)
form_cols[0].text_input("Name", placeholder="Enter your name")
form_cols[1].text_input("Email", placeholder="you@example.com")
st.form_submit_button("Submit", type="primary")
# Selection widgets
st.subheader("Selection Widgets")
sel_cols = st.columns(2)
with sel_cols[0]:
st.checkbox("Checkbox option")
st.toggle("Toggle switch")
st.selectbox("Selectbox", options=["Option A", "Option B", "Option C"])
st.multiselect("Multiselect", options=["Tag 1", "Tag 2", "Tag 3"], default=["Tag 1"])
with sel_cols[1]:
st.radio("Radio buttons", options=["Choice 1", "Choice 2", "Choice 3"], horizontal=True)
st.pills("Pills", options=["Small", "Medium", "Large"], default="Medium")
st.segmented_control("Segmented", options=["Day", "Week", "Month"], default="Week")
st.caption("Feedback widget")
st.feedback("stars")
# Numeric & Sliders
st.subheader("Numeric Inputs")
num_cols = st.columns(3)
num_cols[0].number_input("Number input", value=42)
num_cols[1].slider("Slider", 0, 100, 50)
num_cols[2].select_slider("Select slider", options=["XS", "S", "M", "L", "XL"], value="M")
# Date/Time
st.subheader("Date & Time")
dt_cols = st.columns(2)
dt_cols[0].date_input("Date input")
dt_cols[1].time_input("Time input")
# Text inputs
st.subheader("Text Inputs")
txt_cols = st.columns(2)
txt_cols[0].text_input("Text input", placeholder="Type something...")
txt_cols[1].text_area("Text area", placeholder="Longer text goes here...", height=100)
# File upload
st.subheader("File Upload")
st.file_uploader("Upload a file", type=["csv", "txt", "pdf"])
# -----------------------------------------------------------------------------
# DATA SECTION
# -----------------------------------------------------------------------------
elif section == "Data":
st.header("Data Display")
# Metrics
st.subheader("Metrics")
m_cols = st.columns(4)
m_cols[0].metric("Revenue", "$45,231", "+12.5%")
m_cols[1].metric("Users", "2,847", "+8.2%")
m_cols[2].metric("Conversion", "3.24%", "-0.4%", delta_color="inverse")
m_cols[3].metric("Avg. Session", "4m 32s", "+1.2%")
st.divider()
# Dataframe
st.subheader("Dataframe")
df = pd.DataFrame({
"Name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
"Department": ["Engineering", "Sales", "Marketing", "Engineering", "Sales"],
"Salary": [95000, 78000, 82000, 105000, 71000],
"Start Date": pd.date_range("2022-01-15", periods=5, freq="3M"),
"Active": [True, True, False, True, True],
})
st.dataframe(
df,
hide_index=True,
column_config={
"Salary": st.column_config.NumberColumn(format="$%d"),
"Start Date": st.column_config.DateColumn(format="MMM DD, YYYY"),
"Active": st.column_config.CheckboxColumn("Active?"),
},
)
# Table
st.subheader("Static Table")
st.table(chart_data.head(5))
# JSON
st.subheader("JSON Display")
st.json({"name": "Streamlit", "version": "1.41.0", "features": ["themes", "widgets", "charts"]})
# -----------------------------------------------------------------------------
# CHARTS SECTION
# -----------------------------------------------------------------------------
elif section == "Charts":
st.header("Charts")
chart_cols = st.columns(2)
with chart_cols[0]:
st.subheader("Line Chart")
st.line_chart(chart_data, height=250)
st.subheader("Bar Chart")
st.bar_chart(chart_data, height=250)
with chart_cols[1]:
st.subheader("Area Chart")
st.area_chart(chart_data, height=250)
st.subheader("Scatter Chart")
st.scatter_chart(chart_data, height=250)
# -----------------------------------------------------------------------------
# TEXT SECTION
# -----------------------------------------------------------------------------
elif section == "Text":
st.header("Text Elements")
# Headers
st.subheader("Headers")
st.title("Title Element")
st.header("Header Element")
st.subheader("Subheader Element")
st.caption("Caption text - smaller, muted")
st.divider()
# Markdown
st.subheader("Markdown Formatting")
st.markdown(
"**Bold text**, *italic text*, ~~strikethrough~~, "
"`inline code`, [link](https://streamlit.io)"
)
st.markdown("Math: $E = mc^2$ and $\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}$")
st.markdown("Emojis: 🚀 🎨 📊 ✨ and icons: :material/home: :material/settings:")
# Colored text
st.subheader("Colored Text")
color_cols = st.columns(3)
color_cols[0].markdown(":red[Red text] and :orange[Orange text]")
color_cols[1].markdown(":green[Green text] and :blue[Blue text]")
color_cols[2].markdown(":violet[Violet text] and :rainbow[Rainbow text]")
# Code blocks
st.subheader("Code Block")
st.code(
'''import streamlit as st
# Create a themed dashboard
st.set_page_config(page_title="My App", layout="wide")
st.title("Hello, Streamlit!")
# Display metrics
col1, col2 = st.columns(2)
col1.metric("Users", "1,234", "+5%")
col2.metric("Revenue", "$56K", "+12%")''',
language="python",
)
# -----------------------------------------------------------------------------
# LAYOUTS SECTION
# -----------------------------------------------------------------------------
elif section == "Layouts":
st.header("Layout Elements")
# Columns
st.subheader("Columns with Borders")
layout_cols = st.columns(3, border=True)
layout_cols[0].write("**Column 1**\n\nFirst column content")
layout_cols[1].write("**Column 2**\n\nSecond column content")
layout_cols[2].write("**Column 3**\n\nThird column content")
# Tabs
st.subheader("Tabs")
tab1, tab2, tab3 = st.tabs(["📈 Chart", "📋 Data", "⚙️ Settings"])
with tab1:
st.write("Chart tab content")
st.line_chart(chart_data["a"], height=150)
with tab2:
st.write("Data tab content")
st.dataframe(chart_data.head(3))
with tab3:
st.write("Settings tab content")
st.checkbox("Enable feature X")
st.checkbox("Enable feature Y", value=True)
# Expander
st.subheader("Expander")
with st.expander("Click to expand"):
st.write("This content is hidden by default.")
st.image("https://placehold.co/400x200/29B5E8/white?text=Expanded+Content")
# Popover
st.subheader("Popover")
pop_cols = st.columns(3)
with pop_cols[0].popover("Open popover", icon=":material/info:"):
st.write("Popover content here!")
st.slider("Popover slider", 0, 100, 50)
# Container
st.subheader("Container with Border")
with st.container(border=True):
st.write("**Bordered Container**")
st.write("Content inside a container with a visible border.")
st.button("Button inside container")
# -----------------------------------------------------------------------------
# CHAT SECTION
# -----------------------------------------------------------------------------
elif section == "Chat":
st.header("Chat Elements")
# Chat messages
st.subheader("Chat Messages")
with st.chat_message("user"):
st.write("Hello! How can I analyze my sales data?")
with st.chat_message("assistant"):
st.write("I can help you with that! Here are a few options:")
st.markdown("""
1. **Revenue trends** - View monthly/quarterly patterns
2. **Top products** - Identify best sellers
3. **Customer segments** - Analyze by region or category
""")
with st.chat_message("user"):
st.write("Show me the revenue trends please.")
with st.chat_message("assistant"):
st.write("Here's your revenue trend for the past 20 periods:")
st.line_chart(chart_data["a"], height=200)
# Chat input
st.chat_input("Type a message...")
# -----------------------------------------------------------------------------
# STATUS SECTION
# -----------------------------------------------------------------------------
elif section == "Status":
st.header("Status Elements")
# Alert messages
st.subheader("Alert Messages")
st.error("Error: Something went wrong with the data pipeline.")
st.warning("Warning: API rate limit approaching (80% used).")
st.info("Info: New features available in the latest release.")
st.success("Success: Data exported successfully to warehouse.")
# Exception
st.subheader("Exception Display")
try:
raise ValueError("This is an example exception for demonstration")
except ValueError as e:
st.exception(e)
# Interactive status
st.subheader("Interactive Status")
status_cols = st.columns(3)
if status_cols[0].button("Show Toast", icon=":material/notifications:"):
st.toast("This is a toast notification!", icon="🔔")
if status_cols[1].button("Balloons", icon=":material/celebration:"):
st.balloons()
if status_cols[2].button("Snow", icon=":material/ac_unit:"):
st.snow()
# Progress
st.subheader("Progress Indicators")
st.progress(0.7, text="70% complete")
with st.spinner("Loading..."):
st.write("Spinner is active (non-blocking in this demo)")
# -----------------------------------------------------------------------------
# SIDEBAR
# -----------------------------------------------------------------------------
with st.sidebar:
st.header("Settings")
st.selectbox("Time Period", ["Last 7 days", "Last 30 days", "Last 90 days", "All time"])
st.multiselect("Metrics", ["Revenue", "Users", "Sessions"], default=["Revenue", "Users"])
st.slider("Confidence threshold", 0.0, 1.0, 0.8)
st.divider()
st.caption("Element Explorer v1.0")
st.caption("Theme: **Spotify**")
@@ -0,0 +1,10 @@
[project]
name = "theme-stripe"
version = "1.0.0"
description = "Stripe theme for Streamlit"
requires-python = ">=3.11"
dependencies = [
"numpy>=1.26.0",
"pandas>=2.2.3",
"streamlit>=1.53.0",
]
@@ -0,0 +1,337 @@
"""
Streamlit Element Explorer - Theme Demo
A comprehensive single-page app showcasing all major Streamlit components
with custom theming. Use this to preview how your theme looks across
different element types.
"""
# DO NOT EDIT — managed by manage.py, edit _shared/streamlit_app.py instead
import numpy as np
import pandas as pd
import streamlit as st
st.set_page_config(page_title="Element Explorer", page_icon="🎨", layout="wide")
# Initialize sample data in session state
if "chart_data" not in st.session_state:
np.random.seed(42)
st.session_state.chart_data = pd.DataFrame(
np.random.randn(20, 3), columns=["a", "b", "c"]
)
chart_data = st.session_state.chart_data
st.title("Streamlit Element Explorer")
st.markdown(
"Explore how Streamlit's built-in elements look with this theme. "
"Select a category below to preview different components."
)
# Navigation using segmented_control for better performance
section = st.segmented_control(
"Section",
["Widgets", "Data", "Charts", "Text", "Layouts", "Chat", "Status"],
default="Widgets",
label_visibility="collapsed",
)
st.divider()
# -----------------------------------------------------------------------------
# WIDGETS SECTION
# -----------------------------------------------------------------------------
if section == "Widgets":
st.header("Widgets")
# Buttons
st.subheader("Buttons")
cols = st.columns(4)
cols[0].button("Primary", type="primary")
cols[1].button("Secondary", type="secondary")
cols[2].button("Tertiary", type="tertiary")
cols[3].link_button("Link", url="https://streamlit.io", icon=":material/open_in_new:")
# Form
with st.form(key="demo_form"):
st.subheader("Form")
form_cols = st.columns(2)
form_cols[0].text_input("Name", placeholder="Enter your name")
form_cols[1].text_input("Email", placeholder="you@example.com")
st.form_submit_button("Submit", type="primary")
# Selection widgets
st.subheader("Selection Widgets")
sel_cols = st.columns(2)
with sel_cols[0]:
st.checkbox("Checkbox option")
st.toggle("Toggle switch")
st.selectbox("Selectbox", options=["Option A", "Option B", "Option C"])
st.multiselect("Multiselect", options=["Tag 1", "Tag 2", "Tag 3"], default=["Tag 1"])
with sel_cols[1]:
st.radio("Radio buttons", options=["Choice 1", "Choice 2", "Choice 3"], horizontal=True)
st.pills("Pills", options=["Small", "Medium", "Large"], default="Medium")
st.segmented_control("Segmented", options=["Day", "Week", "Month"], default="Week")
st.caption("Feedback widget")
st.feedback("stars")
# Numeric & Sliders
st.subheader("Numeric Inputs")
num_cols = st.columns(3)
num_cols[0].number_input("Number input", value=42)
num_cols[1].slider("Slider", 0, 100, 50)
num_cols[2].select_slider("Select slider", options=["XS", "S", "M", "L", "XL"], value="M")
# Date/Time
st.subheader("Date & Time")
dt_cols = st.columns(2)
dt_cols[0].date_input("Date input")
dt_cols[1].time_input("Time input")
# Text inputs
st.subheader("Text Inputs")
txt_cols = st.columns(2)
txt_cols[0].text_input("Text input", placeholder="Type something...")
txt_cols[1].text_area("Text area", placeholder="Longer text goes here...", height=100)
# File upload
st.subheader("File Upload")
st.file_uploader("Upload a file", type=["csv", "txt", "pdf"])
# -----------------------------------------------------------------------------
# DATA SECTION
# -----------------------------------------------------------------------------
elif section == "Data":
st.header("Data Display")
# Metrics
st.subheader("Metrics")
m_cols = st.columns(4)
m_cols[0].metric("Revenue", "$45,231", "+12.5%")
m_cols[1].metric("Users", "2,847", "+8.2%")
m_cols[2].metric("Conversion", "3.24%", "-0.4%", delta_color="inverse")
m_cols[3].metric("Avg. Session", "4m 32s", "+1.2%")
st.divider()
# Dataframe
st.subheader("Dataframe")
df = pd.DataFrame({
"Name": ["Alice", "Bob", "Charlie", "Diana", "Eve"],
"Department": ["Engineering", "Sales", "Marketing", "Engineering", "Sales"],
"Salary": [95000, 78000, 82000, 105000, 71000],
"Start Date": pd.date_range("2022-01-15", periods=5, freq="3M"),
"Active": [True, True, False, True, True],
})
st.dataframe(
df,
hide_index=True,
column_config={
"Salary": st.column_config.NumberColumn(format="$%d"),
"Start Date": st.column_config.DateColumn(format="MMM DD, YYYY"),
"Active": st.column_config.CheckboxColumn("Active?"),
},
)
# Table
st.subheader("Static Table")
st.table(chart_data.head(5))
# JSON
st.subheader("JSON Display")
st.json({"name": "Streamlit", "version": "1.41.0", "features": ["themes", "widgets", "charts"]})
# -----------------------------------------------------------------------------
# CHARTS SECTION
# -----------------------------------------------------------------------------
elif section == "Charts":
st.header("Charts")
chart_cols = st.columns(2)
with chart_cols[0]:
st.subheader("Line Chart")
st.line_chart(chart_data, height=250)
st.subheader("Bar Chart")
st.bar_chart(chart_data, height=250)
with chart_cols[1]:
st.subheader("Area Chart")
st.area_chart(chart_data, height=250)
st.subheader("Scatter Chart")
st.scatter_chart(chart_data, height=250)
# -----------------------------------------------------------------------------
# TEXT SECTION
# -----------------------------------------------------------------------------
elif section == "Text":
st.header("Text Elements")
# Headers
st.subheader("Headers")
st.title("Title Element")
st.header("Header Element")
st.subheader("Subheader Element")
st.caption("Caption text - smaller, muted")
st.divider()
# Markdown
st.subheader("Markdown Formatting")
st.markdown(
"**Bold text**, *italic text*, ~~strikethrough~~, "
"`inline code`, [link](https://streamlit.io)"
)
st.markdown("Math: $E = mc^2$ and $\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}$")
st.markdown("Emojis: 🚀 🎨 📊 ✨ and icons: :material/home: :material/settings:")
# Colored text
st.subheader("Colored Text")
color_cols = st.columns(3)
color_cols[0].markdown(":red[Red text] and :orange[Orange text]")
color_cols[1].markdown(":green[Green text] and :blue[Blue text]")
color_cols[2].markdown(":violet[Violet text] and :rainbow[Rainbow text]")
# Code blocks
st.subheader("Code Block")
st.code(
'''import streamlit as st
# Create a themed dashboard
st.set_page_config(page_title="My App", layout="wide")
st.title("Hello, Streamlit!")
# Display metrics
col1, col2 = st.columns(2)
col1.metric("Users", "1,234", "+5%")
col2.metric("Revenue", "$56K", "+12%")''',
language="python",
)
# -----------------------------------------------------------------------------
# LAYOUTS SECTION
# -----------------------------------------------------------------------------
elif section == "Layouts":
st.header("Layout Elements")
# Columns
st.subheader("Columns with Borders")
layout_cols = st.columns(3, border=True)
layout_cols[0].write("**Column 1**\n\nFirst column content")
layout_cols[1].write("**Column 2**\n\nSecond column content")
layout_cols[2].write("**Column 3**\n\nThird column content")
# Tabs
st.subheader("Tabs")
tab1, tab2, tab3 = st.tabs(["📈 Chart", "📋 Data", "⚙️ Settings"])
with tab1:
st.write("Chart tab content")
st.line_chart(chart_data["a"], height=150)
with tab2:
st.write("Data tab content")
st.dataframe(chart_data.head(3))
with tab3:
st.write("Settings tab content")
st.checkbox("Enable feature X")
st.checkbox("Enable feature Y", value=True)
# Expander
st.subheader("Expander")
with st.expander("Click to expand"):
st.write("This content is hidden by default.")
st.image("https://placehold.co/400x200/29B5E8/white?text=Expanded+Content")
# Popover
st.subheader("Popover")
pop_cols = st.columns(3)
with pop_cols[0].popover("Open popover", icon=":material/info:"):
st.write("Popover content here!")
st.slider("Popover slider", 0, 100, 50)
# Container
st.subheader("Container with Border")
with st.container(border=True):
st.write("**Bordered Container**")
st.write("Content inside a container with a visible border.")
st.button("Button inside container")
# -----------------------------------------------------------------------------
# CHAT SECTION
# -----------------------------------------------------------------------------
elif section == "Chat":
st.header("Chat Elements")
# Chat messages
st.subheader("Chat Messages")
with st.chat_message("user"):
st.write("Hello! How can I analyze my sales data?")
with st.chat_message("assistant"):
st.write("I can help you with that! Here are a few options:")
st.markdown("""
1. **Revenue trends** - View monthly/quarterly patterns
2. **Top products** - Identify best sellers
3. **Customer segments** - Analyze by region or category
""")
with st.chat_message("user"):
st.write("Show me the revenue trends please.")
with st.chat_message("assistant"):
st.write("Here's your revenue trend for the past 20 periods:")
st.line_chart(chart_data["a"], height=200)
# Chat input
st.chat_input("Type a message...")
# -----------------------------------------------------------------------------
# STATUS SECTION
# -----------------------------------------------------------------------------
elif section == "Status":
st.header("Status Elements")
# Alert messages
st.subheader("Alert Messages")
st.error("Error: Something went wrong with the data pipeline.")
st.warning("Warning: API rate limit approaching (80% used).")
st.info("Info: New features available in the latest release.")
st.success("Success: Data exported successfully to warehouse.")
# Exception
st.subheader("Exception Display")
try:
raise ValueError("This is an example exception for demonstration")
except ValueError as e:
st.exception(e)
# Interactive status
st.subheader("Interactive Status")
status_cols = st.columns(3)
if status_cols[0].button("Show Toast", icon=":material/notifications:"):
st.toast("This is a toast notification!", icon="🔔")
if status_cols[1].button("Balloons", icon=":material/celebration:"):
st.balloons()
if status_cols[2].button("Snow", icon=":material/ac_unit:"):
st.snow()
# Progress
st.subheader("Progress Indicators")
st.progress(0.7, text="70% complete")
with st.spinner("Loading..."):
st.write("Spinner is active (non-blocking in this demo)")
# -----------------------------------------------------------------------------
# SIDEBAR
# -----------------------------------------------------------------------------
with st.sidebar:
st.header("Settings")
st.selectbox("Time Period", ["Last 7 days", "Last 30 days", "Last 90 days", "All time"])
st.multiselect("Metrics", ["Revenue", "Users", "Sessions"], default=["Revenue", "Users"])
st.slider("Confidence threshold", 0.0, 1.0, 0.8)
st.divider()
st.caption("Element Explorer v1.0")
st.caption("Theme: **Stripe**")