Streamlit Selectable Grid
A Streamlit component that displays a selectable grid of cells with support for headers, row indices, and custom styling options.
Requires Python 3.10 or newer and Streamlit 1.51 or newer.
Installation
pip install st-selectable-grid
Usage
import streamlit as st
from st_selectable_grid import st_selectable_grid
# Create a grid with header and index
cells = [
[
{"label": "A1", "cell_color": "#f0f8ff", "tooltip": "Cell A1", "mark": True},
{"label": "<b>A2</b>", "cell_color": "#e6e6fa", "html": True},
{"label": "A3", "cell_color": "#f5f5dc"}
],
[
{"label": "B1", "cell_color": "#f0ffff"},
{"label": "<span style='color:red'>B2</span>", "cell_color": "#f5f5f5", "html": True},
{"label": "B3", "cell_color": "#fffaf0"}
],
[
{"label": "C1", "cell_color": "#fff0f5"},
{"label": "C2", "cell_color": "#f0f0f0"},
{"label": "<i>C3</i>", "cell_color": "#fffff0", "html": True}
]
]
header = [
{"label": "Column 1", "cell_color": "#e0e0e0", "mark": True},
{"label": "Column 2", "cell_color": "#e0e0e0"},
{"label": "Column 3", "cell_color": "#e0e0e0"}
]
index = ["Row 1", "Row 2", "Row 3"]
selection = st_selectable_grid(
cells=cells,
header=header,
index=index,
aspect_ratio=1.0,
allow_secondary_selection=True,
allow_header_selection=True,
height=300,
grid_position="center",
resize=True,
mark_color="#2196F3",
primary_selection_color="#2196F3",
secondary_selection_color="#FF9800",
key="grid1"
)
if selection:
if "primary" in selection:
st.write("Primary selection (left click):", selection["primary"])
if "secondary" in selection:
st.write("Secondary selection (right click):", selection["secondary"])
Features
- Interactive grid with selectable cells
- Support for headers and row indices
- Customizable cell colors and aspect ratio
- Primary (left-click) and secondary (right-click) selections
- Tooltips on hover
- Cell marking with indicator dots
- Responsive design with positioning options
- Fixed or flexible sizing options
- HTML formatting support for cell content
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
cells |
List[List[dict or str]] | Required | 2D array of dictionaries or strings to be displayed in the grid. Dictionary keys: label, cell_color, tooltip, mark, html. |
header |
List[dict or str] or None | None | Optional 1D array for column headers. Same format as cells. |
index |
List[dict or str] or None | None | Optional 1D array for row indices. Same format as cells. |
aspect_ratio |
float | 1.0 | Controls the aspect ratio (height/width) of cells. |
allow_secondary_selection |
bool | False | If True, allows right-click to select a secondary cell. |
allow_secondary_selection_first |
bool | False | If True and allow_secondary_selection is True, allows right-clicking a secondary cell before selecting a primary cell. |
allow_header_selection |
bool | False | If True, allows header cells to be selected. |
height |
int or None | None | Optional height constraint in pixels. If None, grid sizes automatically based on width. |
resize |
bool | True | If True, grid resizes to fill available space. If False, maintains size based on content. |
grid_position |
str | 'center' | Horizontal alignment of the grid. Options: 'left', 'center', 'right'. Not applied if resize = True. |
mark_color |
str | '#2196F3' | Color for marker dots that appear on cells with mark=True. |
primary_selection_color |
str | '#2196F3' | Color for the primary (left-click) selection highlight. |
secondary_selection_color |
str | '#FF9800' | Color for the secondary (right-click) selection highlight. |
allow_copy_contents |
bool | False | If True, allows users to select and copy text within cells. If False, cells are clickable for selection but text cannot be highlighted. |
key |
str or None | None | Unique identifier for the component. |
Cell Dictionary Format
Each cell can be either a string (which becomes the label) or a dictionary with these keys:
label(str): The text to display in the cellcell_color(str): Background color in CSS format (e.g., "#f0f8ff" or "red")tooltip(str): Text to display when hovering over the cellmark(bool): If True, shows a marker dot in the top-right corner of the cellhtml(bool): If True, renders the label content as HTML, allowing formatting tags
HTML Formatting Example
You can use HTML tags in cell labels when the html flag is set to True:
cells = [
[
{"label": "Normal Text"},
{"label": "<b>Bold Text</b>", "html": True},
{"label": "<span style='color:red'>Red Text</span>", "html": True}
],
[
{"label": "<i>Italic</i>", "html": True},
{"label": "<b>Bold</b> and <i>italic</i>", "html": True},
{"label": "<u>Underlined</u>", "html": True}
]
]
Security Note: Use caution when setting html=True with untrusted content, as this could introduce security vulnerabilities.
Return Value
{
"primary": {"x": col_index, "y": row_index}, # For left-click selection
"secondary": {"x": col_index, "y": row_index} # For right-click selection (if enabled)
}
Secondary selection is only available after a primary selection has been made unless allow_secondary_selection_first=True.
Local example testing
-
Clone and enter the repo:
git clone https://github.com/hoggatt/st-selectable-grid.git cd st-selectable-grid
-
Create and activate a virtual environment (optional but recommended):
python -m venv venv # On Windows venv\Scripts\activate # On macOS/Linux source venv/bin/activate
-
Install Python and frontend dependencies:
pip install -e . npm --prefix st_selectable_grid/frontend install
-
Build the frontend assets:
npm --prefix st_selectable_grid/frontend run build
-
From the repo root, run the example against this checkout:
PYTHONPATH="$PWD" streamlit run st_selectable_grid/example.py
The PYTHONPATH="$PWD" prefix prevents Streamlit from importing an already-installed st-selectable-grid package instead of your local files.
While editing frontend files, run this in another terminal:
npm --prefix st_selectable_grid/frontend run dev
The v2 component loads from st_selectable_grid/frontend/build; npm run dev rebuilds that directory as files change.
Metadata
Release files for st-selectable-grid 2.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| st_selectable_grid-2.0.2.tar.gz | 74.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| st_selectable_grid-2.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 147.7 kB
Release files / st_selectable_grid-2.0.2.tar.gz
| Download URL | st_selectable_grid-2.0.2.tar.gz |
|---|---|
| Size | 74.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
feb472e4c202f72590d937f691ae68c6d796dc3f7808c669511a45916310af72
|
|
BLAKE2b-256 checksum How to use checksums |
8e72c674b46c9961a7e0f8188ca23042dcfe99e27d835b987816a3483d80c696
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 29, 2026.
Transparency logRelease files / st_selectable_grid-2.0.2-py3-none-any.whl
| Download URL | st_selectable_grid-2.0.2-py3-none-any.whl |
|---|---|
| Size | 73.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9f31837a3918d1778dd763daa80420af8e0ef38cc922acbcbe0d47a05693c233
|
|
BLAKE2b-256 checksum How to use checksums |
25e4d52c7a8f04d064a5d4822f681980b8ecef758b61464c243f37b3f880e246
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Apr 29, 2026.
Transparency log