A faster way to build and share data apps
Custom component framework and column configuration for data editors and dataframes. These features enable extending Streamlit with custom functionality and fine-grained control over data presentation.
Framework for creating and integrating custom HTML/JavaScript components into Streamlit applications.
# Available in st.components.v1 namespace
def html(html, *, width=None, height=None, scrolling=False):
"""
Display HTML content in an iframe with optional sizing and scrolling.
Args:
html (str): HTML content to display
width (int, optional): Component width in pixels
height (int, optional): Component height in pixels
scrolling (bool): Whether to allow scrolling within the iframe
Returns:
Any: Data returned from the HTML component (if any)
"""
def iframe(src, *, width=None, height=None, scrolling=False):
"""
Display external web page or content in an iframe.
Args:
src (str): URL of the content to display
width (int, optional): Iframe width in pixels
height (int, optional): Iframe height in pixels
scrolling (bool): Whether to allow scrolling within the iframe
Returns:
Any: Data returned from the iframe (if any)
"""
def declare_component(name, path=None, url=None):
"""
Declare a custom Streamlit component for use in the application.
Args:
name (str): Component name for identification
path (str, optional): Local path to component files
url (str, optional): URL where component is hosted
Returns:
callable: Component function that can be called to render the component
"""Example usage:
import streamlit.components.v1 as components
# Simple HTML component
html_content = """
<div style="background: linear-gradient(90deg, #ff6b6b, #4ecdc4);
color: white; padding: 20px; border-radius: 10px; text-align: center;">
<h2>Custom HTML Component</h2>
<p>This is rendered from HTML!</p>
<button onclick="window.parent.postMessage({type: 'click', data: 'Button clicked!'})">
Click Me
</button>
</div>
"""
# Display HTML with return value
result = components.html(html_content, height=150)
if result:
st.write(f"Component returned: {result}")
# Iframe component
components.iframe("https://example.com", height=400)
# Custom component declaration
# Component files in ./my_component/
my_component = components.declare_component("my_component", path="./my_component")
# Use custom component
component_value = my_component(
name="example",
value=42,
options=["A", "B", "C"]
)Comprehensive configuration system for customizing dataframe and data editor column behavior and appearance.
# Available in st.column_config namespace
class Column:
"""
Base column configuration with common properties.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width ("small", "medium", "large", or pixels)
help (str, optional): Tooltip text for column header
disabled (bool, optional): Whether column is read-only
required (bool, optional): Whether column value is required
"""
class TextColumn(Column):
"""
Text column configuration for string data.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
disabled (bool, optional): Whether column is read-only
required (bool, optional): Whether column value is required
default (str, optional): Default value for new rows
max_chars (int, optional): Maximum number of characters allowed
validate (callable, optional): Validation function for input
"""
class NumberColumn(Column):
"""
Number column configuration for numeric data.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
disabled (bool, optional): Whether column is read-only
required (bool, optional): Whether column value is required
default (float, optional): Default value for new rows
min_value (float, optional): Minimum allowed value
max_value (float, optional): Maximum allowed value
step (float, optional): Step size for increment/decrement
format (str, optional): Number format string (e.g., "%.2f", "%d")
"""
class CheckboxColumn(Column):
"""
Checkbox column configuration for boolean data.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
disabled (bool, optional): Whether column is read-only
required (bool, optional): Whether column value is required
default (bool, optional): Default value for new rows
"""
class SelectboxColumn(Column):
"""
Selectbox column configuration for categorical data.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
disabled (bool, optional): Whether column is read-only
required (bool, optional): Whether column value is required
default (Any, optional): Default selected value
options (list): Available options to choose from
"""
class DatetimeColumn(Column):
"""
Datetime column configuration for timestamp data.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
disabled (bool, optional): Whether column is read-only
required (bool, optional): Whether column value is required
default (datetime, optional): Default datetime value
min_value (datetime, optional): Minimum allowed datetime
max_value (datetime, optional): Maximum allowed datetime
format (str, optional): Datetime display format
step (int, optional): Step size in seconds
"""
class DateColumn(Column):
"""
Date column configuration for date-only data.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
disabled (bool, optional): Whether column is read-only
required (bool, optional): Whether column value is required
default (date, optional): Default date value
min_value (date, optional): Minimum allowed date
max_value (date, optional): Maximum allowed date
format (str, optional): Date display format
"""
class TimeColumn(Column):
"""
Time column configuration for time-only data.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
disabled (bool, optional): Whether column is read-only
required (bool, optional): Whether column value is required
default (time, optional): Default time value
min_value (time, optional): Minimum allowed time
max_value (time, optional): Maximum allowed time
format (str, optional): Time display format
step (int, optional): Step size in seconds
"""
class ListColumn(Column):
"""
List column configuration for array/list data.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
"""
class LinkColumn(Column):
"""
Link column configuration for URL data with clickable links.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
disabled (bool, optional): Whether column is read-only
required (bool, optional): Whether column value is required
default (str, optional): Default URL value
max_chars (int, optional): Maximum URL length
validate (callable, optional): URL validation function
display_text (str or callable, optional): Text to display instead of URL
"""
class ImageColumn(Column):
"""
Image column configuration for displaying images from URLs.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
"""
class LineChartColumn(Column):
"""
Line chart column configuration for displaying small charts in cells.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
y_min (float, optional): Minimum Y-axis value
y_max (float, optional): Maximum Y-axis value
"""
class BarChartColumn(Column):
"""
Bar chart column configuration for displaying small bar charts in cells.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
y_min (float, optional): Minimum Y-axis value
y_max (float, optional): Maximum Y-axis value
"""
class ProgressColumn(Column):
"""
Progress bar column configuration for displaying progress indicators.
Args:
label (str, optional): Column display name
width (str or int, optional): Column width
help (str, optional): Tooltip text
min_value (float, optional): Minimum progress value (default 0)
max_value (float, optional): Maximum progress value (default 100)
format (str, optional): Progress display format
"""Example usage:
import pandas as pd
import streamlit as st
# Sample dataframe
data = pd.DataFrame({
"name": ["Alice", "Bob", "Charlie"],
"age": [25, 30, 35],
"active": [True, False, True],
"category": ["A", "B", "A"],
"score": [85.5, 92.1, 78.3],
"signup_date": ["2023-01-15", "2023-02-20", "2023-03-10"],
"website": ["https://alice.com", "https://bob.org", "https://charlie.net"],
"progress": [75, 90, 60],
"trend": [[1,3,2,4], [2,1,4,3], [3,4,2,1]]
})
# Configure columns
column_config = {
"name": st.column_config.TextColumn(
"Full Name",
help="Employee full name",
max_chars=50,
required=True
),
"age": st.column_config.NumberColumn(
"Age",
help="Employee age in years",
min_value=18,
max_value=65,
step=1,
format="%d years"
),
"active": st.column_config.CheckboxColumn(
"Active Status",
help="Whether employee is currently active",
default=True
),
"category": st.column_config.SelectboxColumn(
"Department",
help="Employee department",
options=["A", "B", "C"],
required=True
),
"score": st.column_config.NumberColumn(
"Performance Score",
help="Performance rating out of 100",
min_value=0,
max_value=100,
format="%.1f"
),
"signup_date": st.column_config.DateColumn(
"Start Date",
help="Employee start date",
format="YYYY-MM-DD"
),
"website": st.column_config.LinkColumn(
"Personal Website",
help="Employee personal website",
display_text="Visit"
),
"progress": st.column_config.ProgressColumn(
"Project Progress",
help="Current project completion percentage",
min_value=0,
max_value=100,
format="%d%%"
),
"trend": st.column_config.LineChartColumn(
"Performance Trend",
help="Performance over last 4 quarters"
)
}
# Display configured dataframe
st.data_editor(
data,
column_config=column_config,
use_container_width=True,
num_rows="dynamic" # Allow adding/removing rows
)def get_column_config(user_role, data_types):
"""Generate column config based on user role and data."""
config = {}
for col_name, col_type in data_types.items():
base_config = {"help": f"{col_name} column"}
# Role-based permissions
if user_role != "admin":
base_config["disabled"] = col_name in ["salary", "ssn"]
# Type-specific configuration
if col_type == "currency":
config[col_name] = st.column_config.NumberColumn(
col_name.title(),
format="$%.2f",
min_value=0,
**base_config
)
elif col_type == "percentage":
config[col_name] = st.column_config.ProgressColumn(
col_name.title(),
min_value=0,
max_value=100,
format="%d%%",
**base_config
)
elif col_type == "category":
config[col_name] = st.column_config.SelectboxColumn(
col_name.title(),
options=get_category_options(col_name),
**base_config
)
return config
# Usage
user_role = get_current_user_role()
data_types = analyze_dataframe_types(df)
column_config = get_column_config(user_role, data_types)
st.data_editor(df, column_config=column_config)# Image column with dynamic URLs
image_data = pd.DataFrame({
"product_name": ["Widget A", "Widget B", "Widget C"],
"image_url": [
"https://example.com/images/widget-a.jpg",
"https://example.com/images/widget-b.jpg",
"https://example.com/images/widget-c.jpg"
],
"price": [19.99, 24.99, 29.99]
})
column_config = {
"product_name": st.column_config.TextColumn("Product", width="medium"),
"image_url": st.column_config.ImageColumn("Product Image", width="large"),
"price": st.column_config.NumberColumn("Price", format="$%.2f")
}
st.dataframe(image_data, column_config=column_config)# Line chart column with time series data
chart_data = pd.DataFrame({
"stock": ["AAPL", "GOOGL", "MSFT"],
"current_price": [150.25, 2800.50, 300.75],
"price_history": [
[145, 148, 152, 150], # AAPL last 4 days
[2750, 2780, 2820, 2800], # GOOGL
[295, 298, 305, 301] # MSFT
],
"volatility": [0.15, 0.12, 0.18]
})
column_config = {
"stock": st.column_config.TextColumn("Symbol", width="small"),
"current_price": st.column_config.NumberColumn(
"Price",
format="$%.2f"
),
"price_history": st.column_config.LineChartColumn(
"4-Day Trend",
width="medium"
),
"volatility": st.column_config.ProgressColumn(
"Volatility",
min_value=0,
max_value=1,
format="%.1%%"
)
}
st.dataframe(chart_data, column_config=column_config)# my_component.py
import streamlit.components.v1 as components
def color_picker_component(default_color="#000000", key=None):
"""Custom color picker component."""
html_template = f"""
<div>
<label for="color-picker">Choose a color:</label>
<input type="color" id="color-picker" value="{default_color}"
onchange="sendColor(this.value)">
<div id="preview" style="width:50px;height:50px;background:{default_color};margin-top:10px;"></div>
</div>
<script>
function sendColor(color) {{
document.getElementById('preview').style.background = color;
window.parent.postMessage({{
type: 'streamlit:setComponentValue',
value: color
}});
}}
</script>
"""
return components.html(html_template, height=100, key=key)
# Usage
selected_color = color_picker_component(default_color="#ff6b6b", key="color")
if selected_color:
st.write(f"Selected color: {selected_color}")# Declare React component (assumes component built separately)
react_component = components.declare_component(
"my_react_component",
url="http://localhost:3001" # Development server
)
def data_table_component(data, editable=True, key=None):
"""Custom data table with advanced features."""
return react_component(
data=data.to_dict('records'),
columns=list(data.columns),
editable=editable,
key=key
)
# Usage
df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
edited_data = data_table_component(df, editable=True, key="table")
if edited_data:
st.write("Edited data:", edited_data)def interactive_chart_component(data, chart_type="bar", key=None):
"""Interactive chart that returns clicked data point."""
# Convert data to JSON for JavaScript
chart_data = data.to_dict('records')
html_template = f"""
<div id="chart-container" style="width: 100%; height: 400px;"></div>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script>
const data = {chart_data};
const chartType = "{chart_type}";
// Create Plotly chart
const plotData = [{{
x: data.map(d => d.x),
y: data.map(d => d.y),
type: chartType,
marker: {{ color: 'rgb(55, 128, 191)' }}
}}];
const layout = {{
title: 'Interactive Chart',
xaxis: {{ title: 'X Axis' }},
yaxis: {{ title: 'Y Axis' }}
}};
Plotly.newPlot('chart-container', plotData, layout);
// Handle click events
document.getElementById('chart-container').on('plotly_click', function(eventData) {{
const point = eventData.points[0];
const clickedData = {{
x: point.x,
y: point.y,
pointIndex: point.pointIndex
}};
// Send data back to Streamlit
window.parent.postMessage({{
type: 'streamlit:setComponentValue',
value: clickedData
}});
}});
</script>
"""
return components.html(html_template, height=450, key=key)
# Usage
chart_data = pd.DataFrame({
'x': ['A', 'B', 'C', 'D'],
'y': [10, 15, 13, 17]
})
clicked_point = interactive_chart_component(chart_data, chart_type="bar", key="chart")
if clicked_point:
st.write(f"Clicked point: {clicked_point}")
st.json(clicked_point)Install with Tessl CLI
npx tessl i tessl/pypi-streamlit