Metadata-Version: 2.4
Name: mm-streamlit-table
Version: 0.0.5
Summary: Themeable Streamlit table component (React + TanStack) with stable in-component state.
License: MIT
Keywords: streamlit,table,datagrid,tanstack,react
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: streamlit>=1.30
Requires-Dist: pandas>=2.0
Dynamic: license-file

# mm-streamlit-table

An opinionated, themeable Streamlit table component built with React +
[TanStack Table](https://tanstack.com/table). MIT-licensed and dependency-light.

Why this exists: most Streamlit table components either rerun the entire page
on every interaction (selection loops, lost filter state) or are styled in a
way that resists customisation. `mm-streamlit-table` keeps UI state inside
the component and only emits **semantic events** back to Streamlit.

## Features

- **No rerun loops.** Sort, filter, expand, and resize are local. Streamlit
  only hears about events you care about (selection, action clicks).
- **Themeable from Python** via a small set of generic design tokens that
  map to CSS custom properties. Drop in your own tokens or override the
  CSS variables directly.
- **Real React renderers** — bring your own cell components (tags, JSON
  chips, copy-to-clipboard, badges, anything you write in TSX).
- **No enterprise license.** Filtering features that AG Grid puts behind a
  paywall (multi-filter, set filter) are built in.

## Install

```bash
pip install mm-streamlit-table
```

## Quick start

```python
import pandas as pd
import streamlit as st
from mm_streamlit_table import mm_table

df = pd.DataFrame(
    {
        "id": [1, 2, 3],
        "name": ["Alpha", "Bravo", "Charlie"],
        "score": [42, 17, 99],
    }
)

result = mm_table(df, selection="single", row_id_column="id", key="demo")

if result and result.get("event") == "select":
    st.write("You picked:", result["row_ids"])
```

## Theming

Pass any subset of these tokens via `theme_tokens=`; missing keys fall back
to neutral defaults:

| Token            | Purpose                       |
| ---------------- | ----------------------------- |
| `bg`             | Table background              |
| `bg_alt`         | Striped row background        |
| `text`           | Body text colour              |
| `text_muted`     | Empty-state and hints         |
| `border`         | Outer border                  |
| `border_subtle`  | Row dividers                  |
| `header_bg`      | Header row background         |
| `header_text`    | Header row text               |
| `accent`         | Accent / selection ring       |
| `selected_bg`    | Selected row background       |
| `row_hover_bg`   | Hover background              |
| `font`           | Body font stack               |
| `font_mono`      | Header / mono font stack      |

## Repo layout

```
mm_streamlit_table/          ← Python package
  __init__.py                ← declare_component + public API
  frontend/build/            ← built JS bundle (generated)
frontend/                    ← React/TS source
  src/
  package.json
  vite.config.ts
```

## Dev loop

In one terminal:

```bash
cd frontend
npm install
npm run dev               # serves on http://localhost:3001
```

In another terminal, in your app:

```bash
pip install -e ../mm-streamlit-table
export MM_STREAMLIT_TABLE_DEV=1   # or set MM_STREAMLIT_TABLE_DEV=1 on Windows
streamlit run your_app.py
```

Edit a `.tsx` file → browser updates. No Streamlit restart needed.

## Release build

```bash
cd frontend
npm run build             # writes to ../mm_streamlit_table/frontend/build
cd ..
python -m build           # builds the wheel
```

## License

MIT.
