Metadata-Version: 2.5
Name: sp-reflex-components
Version: 0.3.0
Summary: Reflex component wrappers for AG Grid (community + enterprise modules) and React Flow - self-host on core Reflex without reflex-enterprise.
Project-URL: Repository, https://github.com/MIM-SP/sp-reflex-components
Project-URL: Issues, https://github.com/MIM-SP/sp-reflex-components/issues
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: ag-grid,components,react-flow,reflex
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: User Interfaces
Requires-Python: >=3.12
Requires-Dist: reflex<0.10,>=0.9.5
Description-Content-Type: text/markdown

# sp-reflex-components

Reflex component wrappers: **AG Grid** (ag-grid-react +
community + enterprise modules) and **React Flow** (@xyflow/react). These
replace `reflex-enterprise`'s component wrappers so apps self-host on core
Reflex (Apache-2.0) with **no Reflex tier, token, badge, or reflex.dev
dependency**.

Built and maintained by Solid Power for internal Reflex apps; published in
case others hit the same wall. Apache-2.0.

## Install

```bash
uv add sp-reflex-components
# or: pip install sp-reflex-components
```

## Use

```python
from sp_reflex_components import export_grid_csv, grid, flow

# AG Grid — drop-in for reflex_enterprise's ag_grid.root(...)
grid(
    id="my-grid",
    theme="quartz",  # or "alpine" (default); unknown values fall back to alpine
    row_data=State.rows,
    column_defs=[{"field": "name", "header_name": "Name", "editable": True}],
    on_selection_changed=State.on_select,  # (rows, source, type)
)

# Client-side CSV export of exactly the grid's own rows — no server surface.
# Requires the grid to carry an explicit unique id; safely no-ops until the
# grid is ready. (Replaces reflex-enterprise's AgGridAPI.export_data_as_csv.)
rx.button("Export CSV", on_click=export_grid_csv("my-grid"))

# React Flow — drop-in for reflex_enterprise's flow(...)
flow(
    flow.controls(),
    flow.background(variant="dots", gap=18, size=1),
    nodes=State.nodes,
    edges=State.edges,
    fit_view=True,
)
```

Column defs and default_col_def accept snake_case keys everywhere — `AgGrid.create`
camelizes them (`header_name` → `headerName`); `row_data` keys are never touched.

AG Grid Enterprise features (clipboard, cell selection, column/context menus,
Excel export) need `AG_GRID_LICENSE_KEY` in the environment **at compile
time** — that is AG Grid's own per-developer license, unrelated to Reflex.
Without a key, **every** grid loads in trial mode: a watermark on the grid
plus a "License Key Not Found" console notice at load. The enterprise
modules are registered globally, so this applies to all grids rendered by
this package, not only the ones exercising enterprise features
(browser-verified 2026-08-11 on a plain grid and a menus/Excel grid).

## Scope doctrine

- A wrapper exposes **exactly** the prop/event surface consuming apps use —
  no speculative props. Need a new prop? Add it here **with a test**, in the
  same PR that uses it; every app inherits it.
- npm versions are **pinned exactly** in this package. A bump is a deliberate
  release with a changelog read (AG Grid majors change behavior: v35 added
  no-matching-rows/exporting overlays, v36 overhauled the DOM containers).
- Legacy CSS theming (`ag-theme-alpine` + `theme: "legacy"`) is deprecated
  upstream; some future AG Grid major will force a Theming API migration —
  that lands here once, for everyone.
- Each consuming app should keep an adapter/wrapper **prop-equality test**
  (both directions, derived from a real render) — see ATLAS's
  `tests/unit/reflex_runtime/components/test_vendor_ag_grid.py` for the
  pattern.

## Known issues

- React Flow renders nodes but **edge rendering has an unresolved defect**
  (edges reach the ReactFlow component as props but no edge elements render;
  reproduces identically under reflex-enterprise's own wrapper on
  @xyflow/react 12.8.4 and 12.11.2, so it is not specific to this package).
  Root cause TBD; issues/PRs welcome.

## Dev

```bash
uv sync
uv run pytest -q
uv run ruff check src tests && uv run ruff format --check .
```
