Metadata-Version: 2.4
Name: streamlit-rtr-components
Version: 1.2.0
Summary: Streamlit components: Org Chart, Hierarchical Grid e Timeline
Author-email: "Artur R. Oliveira" <arturroliveira87@gmail.com>
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: streamlit>=1.24
Requires-Dist: python-dateutil>=2.8.2
Provides-Extra: devel
Requires-Dist: build>=1.2; extra == "devel"
Requires-Dist: wheel; extra == "devel"
Requires-Dist: pytest==7.4.0; extra == "devel"
Requires-Dist: playwright==1.48.0; extra == "devel"
Requires-Dist: requests==2.31.0; extra == "devel"
Requires-Dist: pytest-playwright-snapshot==1.0; extra == "devel"
Requires-Dist: pytest-rerunfailures==12.0; extra == "devel"
Dynamic: license-file

<!-- PROJECT: streamlit-rtr-components -->
<!-- BADGES: start -->
<p align="center">
  <!-- Substitua o href se já estiver no PyPI -->
  <a href="https://pypi.org/project/streamlit-rtr-components/"><img alt="PyPI" src="https://img.shields.io/pypi/v/streamlit-rtr-components.svg"></a>
  <img alt="Python" src="https://img.shields.io/pypi/pyversions/streamlit-rtr-components.svg">
  <img alt="Streamlit" src="https://img.shields.io/badge/streamlit-%E2%89%A51.24-FF4B4B">
  <img alt="License" src="https://img.shields.io/badge/license-MIT-green">
</p>
<!-- BADGES: end -->

<h1 align="center">streamlit-rtr-components</h1>
<p align="center">Componentes customizados para <b>Streamlit</b>: organograma, grid hierárquico e timeline.</p>

<!-- TOC: start -->
## Sumário
- [Visão geral](#visão-geral)
- [Instalação](#instalação)
- [Exemplo rápido](#exemplo-rápido)
- [API](#api)
- [Formato de dados](#formato-de-dados)
- [Estrutura do repositório](#estrutura-do-repositório)
- [Desenvolvimento (Vite + Tailwind v4)](#desenvolvimento-vite--tailwind-v4)
- [Build de produção (frontend)](#build-de-produção-frontend)
- [Empacotamento Python](#empacotamento-python)
- [Solução de problemas](#solução-de-problemas)
- [Changelog](#changelog)
- [Contribuição](#contribuição)
- [Licença](#licença)
<!-- TOC: end -->

## Visão geral
Três componentes prontos para uso em Streamlit:
- `st_orgChart` — organograma (árvore hierárquica).
- `st_hierarchicalGrid` — grid hierárquico com colunas configuráveis e suporte a imagens (PNG/SVG via data URL).
- `st_timeline` — timeline horizontal com múltiplas linhas, zoom, hierarquia e eventos de clique.

> **Stack**: Python (Streamlit) + React/TypeScript (Vite) + Tailwind v4.  
> **Artefatos**: cada frontend gera `frontend/dist` e é empacotado junto ao wheel.

## Instalação
```bash
pip install streamlit-rtr-components
```


<!-- USAGE: start -->

## Exemplo rápido

```python
import streamlit as st
from rtr_componentes import st_orgChart, st_hierarchicalGrid, st_timeline

st.title("Demo • RTR Components")

st.subheader("Org Chart")
st_orgChart(
    data={
        "id": "CEO",
        "children": [{"id": "CTO"}, {"id": "CFO"}]
    }
)

st.subheader("Hierarchical Grid")
data = [
    {
        "estrutura": "Presidência",
        "avatar": "data:image/png;base64,....",   # PNG opcional (data URL)
        "quantidade_funcionarios": 2167,
        "salario_total": "R$ 5.239.551,21",
        "salario_medio": "R$ 2.417,88",
        "children": [
            {
                "estrutura": "Assessoria Financeira",
                "avatar": "data:image/svg+xml;base64,....",  # SVG opcional (data URL)
                "quantidade_funcionarios": 1,
                "salario_total": "R$ 5.184,00",
                "salario_medio": "R$ 5.184,00",
                "children": []
            }
        ]
    }
]
columns = [
    {"label": "Estrutura", "field": "estrutura"},
    {"label": "Quantidade Funcionarios", "field": "quantidade_funcionarios"},
    {"label": "Salario Total", "field": "salario_total", "secret": True},
    {"label": "Salario Medio", "field": "salario_medio"}
]

st_hierarchicalGrid(data=data, columns=columns, expanded=True)

event = st_timeline(
    rows=[{"id": "101", "label": "Linha 0101"}],
    items=[{
        "id": "viagem_1",
        "row_id": "101",
        "start": "2026-08-15T06:00:00",
        "end": "2026-08-15T07:15:00",
        "label": "Viagem 001",
        "kind": "planned",
    }],
    start="2026-08-15T05:00:00",
    end="2026-08-15T09:00:00",
    zoom="hour",
    timezone="America/Bahia",
    key="timeline_operacional",
)
```

<!-- USAGE: end -->

## API

```python
from rtr_componentes import st_orgChart, st_hierarchicalGrid, st_timeline

st_orgChart(
    data: dict | list | None = None,
    key: str | None = None,
    **kwargs
) -> Any


st_hierarchicalGrid(
    data: dict | list | None = None,
    columns: list[dict] | None = None,
    expanded: bool = False,
    key: str | None = None,
    **kwargs
) -> Any

st_timeline(
    rows,
    items,
    start,
    end,
    zoom="hour",
    *,
    timezone="UTC",
    colors=None,
    show_now=True,
    height=520,
    key=None,
) -> Any
```

```text
# data
# Org: objeto/array hierárquico com id, children, etc.
# Grid: nós com campos livres e children: [].
# columns (Grid): {"label": str, "field": str, "secret"?: bool, "type"?: "text"|"number"|"currency"|...}.
# expanded (Grid): expande nós por padrão.
```

O retorno dos componentes é o último valor enviado pelo frontend. Para `st_timeline`, o valor inicial é `None`.


<!-- DATA-FORMAT: start -->

## Formato de dados

### Timeline

`rows` preserva a ordem recebida e aceita hierarquia por `children`. Items só podem apontar para linhas folha:

```python
rows = [{
    "id": "garagem_a",
    "label": "Garagem A",
    "children": [{"id": "101", "label": "Linha 0101"}],
}]

items = [{
    "id": "viagem_1",
    "row_id": "101",
    "start": "2026-08-15T06:00:00",
    "end": "2026-08-15T07:15:00",
    "label": "Viagem 001",
    "kind": "planned",
}]
```

Timestamps usam ISO 8601. Valores com `Z` ou offset são instantes absolutos; valores sem offset são interpretados no argumento `timezone`. A normalização acontece no wrapper Python antes do envio ao frontend.

`zoom` aceita `minute`, `hour`, `day` ou `week`. `colors` associa um `kind` a uma cor hexadecimal:

Os controles locais `Anterior`, `Próxima`, `Agora` e `Fit` navegam dentro de `start/end` sem alterar a janela Python nem emitir eventos. `Fit` acompanha o resize, e o zoom local preserva o instante central quando possível.

Por teclado, a toolbar usa setas e `Home`/`End`; a zona de items mantém um único ponto de Tab e usa setas para navegar, enquanto `Enter`/`Space` produzem o mesmo `item_click` do mouse. Tooltips também abrem por foco e fecham com `Escape`.

```python
colors = {"planned": "#2563EB", "actual": "#16A34A"}
```

Um clique retorna somente o payload compacto abaixo. Cada interação recebe um `event_id` novo:

```json
{
  "type": "item_click",
  "event_id": "...",
  "item_id": "viagem_1",
  "row_id": "101"
}
```

Veja `example_timeline.py` para um exemplo completo com grupos, items sobrepostos, `planned`, `actual`, zoom e adaptação ao tema do Streamlit.

Documentação avançada do `st_timeline`:

- [Roadmap](docs/st_timeline/ROADMAP.md)
- [Arquitetura](docs/st_timeline/ARCHITECTURE.md)
- [Contratos públicos da versão 1.1.1](docs/st_timeline/CONTRACTS.md)

### Imagens nos componentes existentes

Imagens: envie como data URL

PNG → data:image/png;base64,<...>

SVG → data:image/svg+xml;base64,<...>

Perfomance: prefira miniaturas (ex.: 64–128 px) para reduzir payload.

Grid: garanta que os nomes em columns[].field existam em cada nó.

<!-- DATA-FORMAT: end -->


## Estrutura do repositório

```text
.
├─ st_orgChart/
│  ├─ __init__.py                 # wrapper Python (usa frontend/dist)
│  └─ frontend/                   # Vite/React/TS
├─ st_hierarchicalGrid/
│  ├─ __init__.py
│  └─ frontend/                   # Vite/React/TS
├─ st_timeline/
│  ├─ __init__.py
│  └─ frontend/                   # Vite/React/TS
├─ rtr_componentes/
│  └─ __init__.py                 # reexporta os três componentes
├─ example_timeline.py
├─ pyproject.toml
├─ MANIFEST.in
├─ README.md
└─ LICENSE
```

## Desenvolvimento (Vite + Tailwind v4)

Em cada frontend:

```bash
npm i
npm run dev
```

No app Streamlit, ative o modo de desenvolvimento e informe o host específico:

```powershell
$env:DEV_MODE="true"
$env:FRONTEND_HOST_TIMELINE="http://localhost:5174"
streamlit run example_timeline.py
```

Os componentes existentes usam `FRONTEND_HOST_ORG` e `FRONTEND_HOST_GRID`. Em produção, os wrappers leem `frontend/dist`.


<!-- BUILD-FRONTEND: start -->

## Build de produção (frontend)

```bash
cd st_orgChart/frontend && npm run build
cd ../../st_hierarchicalGrid/frontend && npm run build
cd ../../st_timeline/frontend && npm run build
```

<!-- BUILD-FRONTEND: end --> <!-- PACKAGING: start -->

## Empacotamento Python

O `MANIFEST.in` e o `package-data` do `pyproject.toml` incluem os três diretórios `frontend/dist`.

```text
recursive-include st_orgChart/frontend/dist *
recursive-include st_hierarchicalGrid/frontend/dist *
recursive-include st_timeline/frontend/dist *
include README.md
include LICENSE
```

```bash
python -m build
python -m pip install dist/*.whl
python -m pytest tests
```

<!-- PACKAGING: end --> <!-- TROUBLESHOOT: start -->

## Solução de problemas

- Tela branca/404 em produção: confirme `base: "./"` no Vite e a presença de `frontend/dist` no wheel.
- `RuntimeError: Build não encontrado`: execute `npm run build` no frontend correspondente.
- Timestamp ingênuo ambíguo ou inexistente durante transição DST: envie um offset explícito.
- Erros de JSX/TS: use TypeScript 5, `moduleResolution: "Bundler"` e `jsx: "react-jsx"`.

<!-- TROUBLESHOOT: end -->

## Changelog

- 1.2.0 — aprimora a navegação temporal com Fit, Anterior/Próxima/Agora e preservação de contexto em zoom/resize; adiciona navegação acessível por teclado, melhorias ARIA, tooltip acessível, contraste aprimorado e reduced motion, sem quebra da API Python.
- 1.1.1 — corrige a infraestrutura de publicação/CI da versão 1.1.0 para Node 20, sem mudanças funcionais no `st_timeline`.
- 1.1.0 — adiciona `st_timeline`.
- 1.0.0 — release inicial com `st_orgChart` e `st_hierarchicalGrid`.

## Contribuição

Issues e PRs são bem-vindos. Antes de abrir PR:

- rode `npm run build` nos três frontends;
- rode `python -m pytest tests`;
- atualize os exemplos e a documentação quando necessário.

## Licença

MIT — veja `LICENSE`.
