Skip to main content

Reusable React-based Streamlit components with Tailwind CSS styling

Project description

Streamlit React Components

A collection of 12 reusable React-based Streamlit components with Tailwind CSS styling. All components support custom inline styles and Tailwind class names.

Installation

pip install streamlit-react-components

Quick Start

import streamlit as st
from streamlit_react_components import (
    panel, section_header, stat_card, metric_row,
    data_table, step_indicator, button_group, chart_legend,
    plotly_chart, form_select, form_slider, checkbox_group
)

Styling

All components accept two styling parameters:

Parameter Type Description
style dict Inline CSS as Python dict (e.g., {"background": "#1e293b", "padding": "16px"})
class_name str Tailwind CSS classes (e.g., "bg-slate-900 p-4 rounded-lg")

Example

stat_card(
    label="Revenue",
    value="$50K",
    color="blue",
    style={"minWidth": "200px", "boxShadow": "0 4px 6px rgba(0,0,0,0.3)"},
    class_name="border border-blue-500"
)

Components

1. Panel

A styled container/card wrapper.

panel(
    children: str = "",           # HTML content
    style: dict = None,
    class_name: str = "",
    key: str = None
) -> None

Example

panel(
    children="<h3 style='color: white;'>Title</h3><p style='color: #94a3b8;'>Content here</p>",
    class_name="border border-blue-500"
)

Default Styling

  • Background: bg-slate-900
  • Border radius: rounded-lg
  • Padding: p-4

2. Section Header

A section title with optional action buttons.

section_header(
    title: str,                   # Header text
    icon: str = "",               # Emoji or icon prefix
    actions: list = None,         # List of action buttons
    style: dict = None,
    class_name: str = "",
    key: str = None
) -> str | None                   # Returns clicked action ID

Actions Format

actions = [
    {"id": "refresh", "label": "Refresh", "color": "blue"},
    {"id": "export", "icon": "📥", "label": "Export", "color": "green"}
]
Action Key Type Description
id str Unique identifier (returned on click)
label str Button text (optional)
icon str Emoji/icon (optional)
color str Preset ("blue", "green", "red", "yellow", "purple", "slate") or hex (e.g., "#94a3b8")
style dict Inline CSS styles for this button (optional)
className str Tailwind classes for this button (optional)
href str URL for link actions. External URLs (http/https) open in new tab (optional)

Example

# Using preset colors
clicked = section_header(
    title="Executive Summary",
    icon="📊",
    actions=[
        {"id": "refresh", "label": "Refresh", "color": "blue"},
        {"id": "settings", "icon": "⚙️", "color": "slate"}
    ]
)

# Using hex colors and custom styling
clicked = section_header(
    title="Custom Actions",
    actions=[
        {"id": "custom", "label": "Custom", "color": "#ff5733"},
        {"id": "styled", "label": "Styled", "style": {"padding": "12px", "borderRadius": "20px"}}
    ]
)

# External link (opens in new tab)
section_header(
    title="Resources",
    actions=[
        {"id": "docs", "label": "Documentation", "href": "https://docs.example.com", "icon": "📚"},
        {"id": "github", "label": "GitHub", "href": "https://github.com", "color": "slate"}
    ]
)

# Internal page navigation
clicked = section_header(
    title="Settings",
    actions=[{"id": "home", "label": "Home", "icon": "🏠"}]
)
if clicked == "home":
    st.switch_page("pages/home.py")

3. Stat Card

A statistics display card with colored accent.

stat_card(
    label: str,                   # Description text
    value: str | int | float,     # The statistic value
    color: str = "blue",          # Accent color
    icon: str = "",               # Optional icon
    style: dict = None,
    class_name: str = "",
    key: str = None
) -> None

Colors

Supports preset color names or hex values:

Preset Border Text
"blue" border-blue-500 text-blue-400
"green" border-green-500 text-green-400
"red" border-red-500 text-red-400
"yellow" border-yellow-500 text-yellow-400
"purple" border-purple-500 text-purple-400
"slate" border-slate-500 text-slate-400
"#xxxxxx" Custom hex color Custom hex color

Example

col1, col2, col3, col4 = st.columns(4)

with col1:
    stat_card(label="Within Threshold", value="4", color="green")
with col2:
    stat_card(label="Above (Risk)", value="2", color="red")
with col3:
    stat_card(label="Below (Underutil)", value="1", color="yellow")
with col4:
    stat_card(label="Avg OEE", value="78.4%", color="blue")

# Using hex color
stat_card(label="Custom Color", value="42", color="#ff5733")

4. Metric Row

A key-value display row.

metric_row(
    label: str,                   # Left-side label
    value: str,                   # Right-side value
    value_color: str = "",        # Tailwind text color class
    style: dict = None,
    class_name: str = "",
    key: str = None
) -> None

Example

metric_row(label="Mean", value="78.4%")
metric_row(label="Median", value="79.0%")
metric_row(label="Outliers", value="3", value_color="text-red-400")
metric_row(label="Trend", value="↑ +0.4%/mo", value_color="text-green-400")

Common Value Colors

Color Class
Green text-green-400
Red text-red-400
Yellow text-yellow-400
Blue text-blue-400
Gray text-slate-400

5. Data Table

A styled data table with row click support.

data_table(
    columns: list,                # Column definitions
    rows: list,                   # Row data
    show_header: bool = True,
    style: dict = None,
    class_name: str = "",
    key: str = None
) -> dict | None                  # Returns {rowIndex, rowData} on click

Column Definition

columns = [
    {"key": "name", "label": "Name"},
    {"key": "value", "label": "Value", "align": "right", "format": "number"},
    {"key": "percent", "label": "%", "align": "center", "format": "percent"},
    {"key": "status", "label": "Status", "colorByValue": True}
]
Column Key Type Description
key str Data key in row dict
label str Column header text
align str "left", "center", "right"
format str "number" (adds commas), "percent" (adds %)
colorByValue bool Color based on status values

Auto-Colored Values

When colorByValue: True, these values get automatic colors:

Value Color
"above" Red
"below" Yellow
"within" Green
"approved" Green
"rejected" Red
"submitted" Yellow
"draft" Gray

Example

columns = [
    {"key": "site", "label": "Site"},
    {"key": "line", "label": "Line"},
    {"key": "util", "label": "Utilization", "align": "right", "format": "percent"},
    {"key": "volume", "label": "Volume", "align": "right", "format": "number"},
    {"key": "status", "label": "Status", "align": "center", "colorByValue": True}
]

rows = [
    {"site": "AML_14", "line": "L1", "util": 94, "volume": 125000, "status": "above"},
    {"site": "ADL", "line": "L2", "util": 72, "volume": 98000, "status": "within"},
    {"site": "Devens", "line": "L3", "util": 58, "volume": 45000, "status": "below"}
]

clicked = data_table(columns=columns, rows=rows)

if clicked:
    st.write(f"Selected row {clicked['rowIndex']}: {clicked['rowData']}")

6. Step Indicator

A multi-step wizard progress indicator.

step_indicator(
    steps: list,                  # List of step labels
    current_step: int,            # Current step (1-indexed)
    style: dict = None,
    class_name: str = "",
    key: str = None
) -> int | None                   # Returns clicked step number

Example

if "step" not in st.session_state:
    st.session_state.step = 1

clicked = step_indicator(
    steps=["Supply Plan", "Configure Levers", "Review & Submit"],
    current_step=st.session_state.step
)

if clicked:
    st.session_state.step = clicked
    st.rerun()

Visual States

State Appearance
Completed (< current) Green circle with ✓
Current Blue circle with number
Future (> current) Gray circle with number

7. Button Group

A group of action buttons.

button_group(
    buttons: list,                # List of button configs
    style: dict = None,
    class_name: str = "",
    key: str = None
) -> str | None                   # Returns clicked button ID

Button Definition

buttons = [
    {"id": "view", "icon": "👁️"},
    {"id": "edit", "icon": "✏️", "label": "Edit"},
    {"id": "approve", "icon": "✓", "color": "green"},
    {"id": "reject", "icon": "✕", "color": "red", "disabled": True}
]
Button Key Type Description
id str Unique identifier (returned on click)
label str Button text (optional)
icon str Emoji/icon (optional)
color str Preset ("blue", "green", "red", "yellow", "purple", "slate") or hex (e.g., "#94a3b8")
disabled bool Disable the button
style dict Inline CSS styles for this button (optional)
className str Tailwind classes for this button (optional)

Example

# Using preset colors
clicked = button_group(
    buttons=[
        {"id": "view", "icon": "👁️", "label": "View"},
        {"id": "edit", "icon": "✏️", "label": "Edit"},
        {"id": "delete", "icon": "🗑️", "color": "red"}
    ]
)

# Using hex colors and custom styling
clicked = button_group(
    buttons=[
        {"id": "custom", "icon": "🎨", "color": "#ff5733"},
        {"id": "styled", "label": "Styled", "style": {"padding": "12px"}}
    ]
)

if clicked == "delete":
    st.warning("Delete clicked!")

8. Chart Legend

A legend for charts with colored indicators.

chart_legend(
    items: list,                  # List of legend items
    style: dict = None,
    class_name: str = "",
    key: str = None
) -> None

Items Format

items = [
    {"color": "#94a3b8", "label": "Historical"},
    {"color": "#ef4444", "label": "Outlier"},
    {"color": "#8b5cf6", "label": "Prophet"},
    {"color": "#10b981", "label": "ARIMA"}
]

Example

# Display a chart (using st.line_chart, plotly, etc.)
st.line_chart(data)

# Add legend below
chart_legend(
    items=[
        {"color": "#3b82f6", "label": "Actual"},
        {"color": "#ef4444", "label": "Upper Threshold"},
        {"color": "#eab308", "label": "Lower Threshold"},
        {"color": "#8b5cf6", "label": "Forecast"}
    ]
)

9. Plotly Chart

Render Plotly charts with full interactivity and event callbacks.

plotly_chart(
    # Data source (one required)
    figure: Any = None,            # Plotly figure or dict
    data: DataFrame = None,        # pandas DataFrame

    # DataFrame options (when using data=)
    x: str = None,                 # Column name for x-axis
    y: str | list = None,          # Column name(s) for y-axis
    color: str = None,             # Column name for color grouping
    chart_type: str = "line",      # "line", "bar", "scatter", "area", "pie", "histogram"
    title: str = None,             # Chart title

    # Plotly config
    config: dict = None,           # Plotly config options

    # Event callbacks
    on_click: bool = False,        # Enable click events
    on_select: bool = False,       # Enable selection events
    on_hover: bool = False,        # Enable hover events
    on_relayout: bool = False,     # Enable zoom/pan events

    # Expandable dialog
    expandable: bool = False,      # Show expand button
    modal_title: str = "",         # Dialog header title

    # Styling
    style: dict = None,
    class_name: str = "",
    key: str = None
) -> dict | None                   # Returns event dict or None

Using Plotly Figure

import plotly.graph_objects as go

fig = go.Figure(
    data=[
        go.Scatter(x=[1,2,3,4,5], y=[10,15,13,17,20], mode='lines+markers', name='Sales'),
        go.Bar(x=[1,2,3,4,5], y=[5,8,6,9,12], name='Orders')
    ],
    layout=go.Layout(title='Sales Dashboard')
)

event = plotly_chart(
    figure=fig,
    on_click=True,
    on_select=True,
    style={"height": "400px"}
)

if event and event['type'] == 'click':
    st.write(f"Clicked: {event['points']}")

Using DataFrame

import pandas as pd

df = pd.DataFrame({
    'month': ['Jan', 'Feb', 'Mar', 'Apr'],
    'sales': [100, 150, 120, 180],
    'orders': [50, 75, 60, 90]
})

# Simple line chart
event = plotly_chart(
    data=df,
    x='month',
    y='sales',
    chart_type='line',
    title='Monthly Sales'
)

# Multiple y columns as bar chart
event = plotly_chart(
    data=df,
    x='month',
    y=['sales', 'orders'],
    chart_type='bar',
    title='Sales vs Orders'
)

# Scatter with color grouping
event = plotly_chart(
    data=df,
    x='sales',
    y='orders',
    color='month',
    chart_type='scatter'
)

Chart Types (DataFrame mode)

Type Description
"line" Line chart with connected points
"scatter" Scatter plot with markers only
"bar" Vertical bar chart
"area" Area chart (filled line)
"pie" Pie chart (x=labels, y=values)
"histogram" Histogram of x values

Event Types

Event When Triggered Data Returned
click User clicks a data point {type: 'click', points: [...]}
select User box/lasso selects points {type: 'select', points: [...]}
hover User hovers over a point {type: 'hover', points: [...]}
relayout User zooms/pans the chart {type: 'relayout', relayout: {...}}

Point Data Structure

Each point in the points array contains:

{
    "curveNumber": 0,      # Index of the trace
    "pointNumber": 2,      # Index of the point in the trace
    "pointIndex": 2,       # Same as pointNumber
    "x": "Mar",            # X value
    "y": 120,              # Y value
    "customdata": None     # Custom data if provided
}

Expandable Dialog

Charts can be expanded into a full-page dialog using Streamlit's native st.dialog():

event = plotly_chart(
    figure=fig,
    expandable=True,                    # Show expand button in corner
    modal_title="Sales Dashboard",      # Title in dialog header
    style={"height": "300px"}
)

Dialog Features:

  • Click the expand icon (⛶) in the top-right corner to open
  • Dialog uses Streamlit's native full-width dialog overlay
  • Click outside the dialog or press Escape to close
  • Chart renders at full dialog width for better visibility

10. Form Select

A styled dropdown select input.

form_select(
    label: str,                   # Label text
    options: list,                # Options list
    value: str = "",              # Selected value
    groups: list = None,          # Option groups (for optgroup)
    style: dict = None,
    class_name: str = "",
    key: str = None
) -> str                          # Returns selected value

Simple Options

options = ["Option A", "Option B", "Option C"]

Options with Labels

options = [
    {"value": "a", "label": "Option A"},
    {"value": "b", "label": "Option B"}
]

Grouped Options

groups = [
    {"label": "Baselines", "options": ["Baseline v7", "Baseline v6"]},
    {"label": "Scenarios", "options": ["Q2 Demand Surge", "OEE Initiative"]}
]

Example

# Simple
site = form_select(
    label="Site",
    options=["AML_14", "ADL", "Devens"],
    value="AML_14"
)

# With groups
scenario = form_select(
    label="Base On",
    groups=[
        {"label": "Baselines", "options": ["Baseline v7 (Current)", "Baseline v6"]},
        {"label": "Scenarios", "options": ["Q2 Demand Surge", "OEE Initiative"]}
    ],
    class_name="max-w-xs"
)

11. Form Slider

A styled range slider input.

form_slider(
    label: str,                   # Label text
    value: float,                 # Current value
    min_val: float,               # Minimum value
    max_val: float,               # Maximum value
    step: float = 1,              # Step increment
    unit: str = "",               # Unit suffix (e.g., "%", "hrs")
    color: str = "blue",          # Preset or hex color (e.g., "#94a3b8")
    style: dict = None,
    class_name: str = "",
    key: str = None
) -> float                        # Returns current value

Example

# Percentage slider with preset color
threshold = form_slider(
    label="Upper Threshold",
    value=90,
    min_val=75,
    max_val=100,
    unit="%",
    color="red"
)

# Time slider
hold_time = form_slider(
    label="VPHP Hold Time",
    value=5.0,
    min_val=2.0,
    max_val=8.0,
    step=0.5,
    unit=" hrs",
    color="blue"
)

# Slider with hex color
custom_slider = form_slider(
    label="Custom Color",
    value=50,
    min_val=0,
    max_val=100,
    color="#ff5733"
)

12. Checkbox Group

A group of checkboxes.

checkbox_group(
    items: list,                  # List of checkbox items
    label: str = "",              # Optional group label
    style: dict = None,
    class_name: str = "",
    key: str = None
) -> list                         # Returns list of checked item IDs

Items Format

items = [
    {"id": "opt1", "label": "Option 1", "checked": True},
    {"id": "opt2", "label": "Option 2", "checked": True},
    {"id": "opt3", "label": "Option 3"}  # checked defaults to False
]

Example

selected = checkbox_group(
    label="Parameters to Optimize",
    items=[
        {"id": "vphp", "label": "VPHP Hold Time", "checked": True},
        {"id": "lot_co", "label": "Lot Changeover", "checked": True},
        {"id": "campaign_co", "label": "Campaign Changeover"},
        {"id": "batch", "label": "Batch Size"}
    ]
)

st.write(f"Selected parameters: {selected}")
# Output: ['vphp', 'lot_co']

Complete Example App

import streamlit as st
from streamlit_react_components import (
    section_header, stat_card, data_table,
    form_select, form_slider, checkbox_group
)

st.set_page_config(page_title="Dashboard", layout="wide")

# Header
action = section_header(
    title="Production Dashboard",
    icon="🏭",
    actions=[{"id": "refresh", "label": "Refresh", "color": "blue"}]
)

# Stats row
col1, col2, col3 = st.columns(3)
with col1:
    stat_card(label="Lines Active", value="12", color="green")
with col2:
    stat_card(label="At Risk", value="3", color="red")
with col3:
    stat_card(label="Avg Utilization", value="82%", color="blue")

# Filters
st.markdown("### Filters")
col1, col2 = st.columns(2)
with col1:
    site = form_select(label="Site", options=["All", "AML", "ADL", "Devens"])
with col2:
    threshold = form_slider(label="Risk Threshold", value=90, min_val=80, max_val=100, unit="%")

# Data table
st.markdown("### Lines Overview")
clicked = data_table(
    columns=[
        {"key": "line", "label": "Line"},
        {"key": "util", "label": "Utilization", "format": "percent", "align": "right"},
        {"key": "status", "label": "Status", "colorByValue": True}
    ],
    rows=[
        {"line": "L1", "util": 94, "status": "above"},
        {"line": "L2", "util": 82, "status": "within"},
        {"line": "L3", "util": 65, "status": "below"}
    ]
)

if clicked:
    st.info(f"Selected: {clicked['rowData']['line']}")

Tailwind CSS Classes Reference

Since components use Tailwind CSS, here are commonly used classes:

Spacing

  • p-1 to p-8: Padding
  • m-1 to m-8: Margin
  • mt-4, mb-4, ml-4, mr-4: Directional margin

Layout

  • w-full: Full width
  • max-w-xs, max-w-sm, max-w-md: Max width
  • flex, grid: Display types
  • gap-2, gap-4: Gap between items

Colors (Dark Theme)

  • bg-slate-900, bg-slate-800: Backgrounds
  • text-white, text-slate-400: Text colors
  • border-slate-700: Border colors

Effects

  • rounded, rounded-lg: Border radius
  • shadow, shadow-lg: Box shadows
  • opacity-50: Transparency

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

streamlit_react_components-1.7.2.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

streamlit_react_components-1.7.2-py3-none-any.whl (1.6 MB view details)

Uploaded Python 3

File details

Details for the file streamlit_react_components-1.7.2.tar.gz.

File metadata

File hashes

Hashes for streamlit_react_components-1.7.2.tar.gz
Algorithm Hash digest
SHA256 9ddc16c077ac08c15f4a0918789339120b4f3fa3d4cfe3f9918fd14e1de43693
MD5 7be5c95fdd6cf7e4fcafbc01f87607c5
BLAKE2b-256 dd32acd5fd2a37cec9f5f8aba656ac3008dd0c15656505b657c8e25d9717086c

See more details on using hashes here.

File details

Details for the file streamlit_react_components-1.7.2-py3-none-any.whl.

File metadata

File hashes

Hashes for streamlit_react_components-1.7.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0e4d9cfab79884aacbab6994735c32abb7535ffa5b768591878954bb23d28820
MD5 d64afd03cb01d2ae86f31bbd1307b6f4
BLAKE2b-256 8d33941005d27bc8c61e8111b4759c644f3c474ce4b688609e45b9bf3b37ca0f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page