Metadata-Version: 2.4
Name: sat-ds
Version: 0.2.0
Summary: Biblioteca de componentes reutilizáveis
Author: lpozza
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: streamlit>=1.35.0
Dynamic: license-file

# SAT Design System — `sat-ds`

> Biblioteca de componentes reutilizáveis para aplicações Streamlit embarcadas no sistema SAT via MainFrame.

---

## 🇧🇷 Português

### Sobre o projeto

O **SAT Design System** (`sat-ds`) é uma biblioteca de componentes Python construída sobre o [Streamlit](https://streamlit.io), criada para padronizar a interface visual das aplicações embarcadas no sistema **SAT** via MainFrame.

A biblioteca nasceu da necessidade de reutilizar componentes com identidade visual consistente em aplicações subsequentes que são embedadas dentro do sistema principal. Em vez de recriar estilos e lógica de UI em cada projeto, o `sat-ds` centraliza esses elementos em um único pacote instalável via `pip`.

Cada componente foi cuidadosamente redesenhado seguindo as diretrizes do Design System exclusivo do SAT, garantindo coesão visual e experiência de uso uniforme entre todas as aplicações da plataforma.

---

### Instalação

#### Requisitos

- Python >= 3.9
- Streamlit instalado no projeto consumidor

#### Via pip (repositório interno / local)

```bash
pip install sat-ds
```

#### Via pip apontando para o repositório Git

```bash
pip install git+https://github.com/seu-org/sat-ds.git
```

#### Via arquivo local (durante desenvolvimento)

Clone o repositório e instale em modo editável:

```bash
git clone https://github.com/seu-org/sat-ds.git
cd sat-ds
pip install -e .
```

---

### Tema e variáveis CSS

Antes de usar qualquer componente, injete as variáveis CSS do tema **uma vez** no topo do seu app. Isso garante que todos os tokens de cor (`var(--color-xxx)`) estejam disponíveis na página:

```python
from theme import inject_theme_css
inject_theme_css()
```

---

### Componentes disponíveis

| Componente | Função principal | Descrição |
|---|---|---|
| `accordeon_ds` | `with accordeon(label, expanded, key, icon_color)` | Seção expansível estilizada com suporte a cor de ícone |
| `button_ds` | `button_ds(title, bg_color, icon_width, icon_height, ...)` | Botão estilizado em formato pílula com ícone SVG opcional |
| `card_caption_ds` | `card_caption_ds(title, subtitle, icon, ...)` | Card simples com ícone opcional, título em negrito e subtítulo |
| `card_dist_ds` | `card_dist_ds(title, value, percent, itens, companys, ...)` | Card de distribuição com valores monetários, percentuais e labels de meta |
| `card_metric_ds` | `card_metric_ds(title, value, delta_visible, footer_visible, ...)` | Card de métrica com delta, tooltip, footer e variação de tamanho |
| `fieldset_legend_ds` | `fieldset_legend_ds(legend, fields, ...)` | Card fieldset com legend sobreposta e campos label/value dinâmicos |
| `identification_field_ds` | `identification_field_ds(label, placeholder, ...)` | Campo de texto estilizado para entrada de identificadores |
| `info_bar_ds` | `info_bar_ds(text, icon_visible, content_copy_visible, ...)` | Barra de informação com ícone, cor e botão de cópia opcionais |
| `loader_ds` | `loader_ds(title, steps, duration_ms, manual, ...)` | Overlay de carregamento animado com suporte a steps e modo manual |
| `panel_ds` | `with panel_ds(key, ...)` | Container com borda estilizada, usado como gerenciador de contexto |
| `record_ds` | `record_ds(razao_social, cnpj, ie, gerfe, ...)` | Ficha de identificação do contribuinte |
| `tabs_ds` | `tabs_ds(["Aba A", "Aba B"])` | Wrapper estilizado sobre `st.tabs()` |

---

### Uso básico

```python
import streamlit as st
from theme import inject_theme_css
from components import (
    accordeon,
    button_ds,
    card_caption_ds,
    card_metric_ds,
    CategoryType,
    fieldset_legend_ds,
    info_bar_ds,
    loader_ds,
    panel_ds,
    record_ds,
    tabs_ds,
)

# Injeta variáveis CSS do tema (obrigatório, uma vez por app)
inject_theme_css()

# Botão
if button_ds("Consultar", bg_color="#375C38", enabled_icon=True, key="btn_1"):
    st.write("Clicado!")

# Card de métrica com delta e footer
card_metric_ds(
    title="Total Apurado",
    value="R$ 1.250.000,00",
    delta_visible=True,
    delta="▲ 12,5%",
    delta_color="#6A9B53",
    footer_visible=True,
    footer_value="Exercício 2024",
    category_type=CategoryType.HIGH,
    size="md",
    key="metric_1",
)

# Card caption (legenda)
card_caption_ds(
    title="ALTA",
    subtitle=" - Consenso 3 IAs",
    icon="✅",
    border="1px solid #6A9B53",
    bg_color="#F0F7EE",
)

# Fieldset com campos dinâmicos
fieldset_legend_ds(
    legend="Empresa",
    fields=[
        {"label": "Razão Social", "value": "Empresa LTDA"},
        {"label": "CNPJ", "value": "00.000.000/0001-00"},
        {"label": "IE", "value": "123.456.789"},
    ],
)

# Ficha do contribuinte
record_ds(
    razao_social="Empresa Exemplo LTDA",
    cnpj="00.000.000/0001-00",
    ie="123.456.789",
    gerfe="GERFE 01",
    icon_visible=True,
)

# Barra de informação com ícone e cópia
info_bar_ds(
    "Dados referentes ao exercício fiscal vigente.",
    icon_visible=True,
    icon_title="info",
    content_copy_visible=True,
)

# Loader (overlay animado)
placeholder = st.empty()
placeholder.markdown(
    loader_ds_html(
        title="Processando...",
        steps=["Carregando dados", "Calculando", "Finalizando"],
        duration_ms=6000,
    ),
    unsafe_allow_html=True,
)
# ... processamento ...
placeholder.empty()  # remove o overlay

# Panel (container com borda)
with panel_ds(key="painel_principal"):
    st.write("Conteúdo dentro do painel")

# Tabs
aba_a, aba_b = tabs_ds(["Resumo", "Detalhes"])
with aba_a:
    st.write("Conteúdo da aba Resumo")

# Accordeon com cor de ícone
with accordeon(":material/bar_chart: Distribuição por Ano", expanded=False, key="acc_1", icon_color="#6A9B53"):
    st.write("Conteúdo expansível")
```

---

### Referência de parâmetros

#### `accordeon(label, expanded, key, icon_color)`
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| `label` | `str` | — | Título do expander (suporta `:material/icon:`) |
| `expanded` | `bool` | `False` | Se inicia aberto |
| `key` | `str` | `""` | Chave única (necessária para usar `icon_color`) |
| `icon_color` | `str` | `""` | Cor do ícone Material no header (ex: `"#6A9B53"`) |

#### `button_ds(title_button, bg_color, enabled_icon, icon, key, icon_width, icon_height)`
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| `title_button` | `str` | `"Buscar"` | Texto do botão |
| `bg_color` | `str` | `ACURACIA_HIGH_EMPHASIS` | Cor de fundo e borda |
| `enabled_icon` | `bool` | `False` | Exibe ícone SVG |
| `icon` | `str` | SVG de lupa | SVG bruto do ícone |
| `key` | `str` | `""` | Chave única |
| `icon_width` | `str` | `"14px"` | Largura do ícone |
| `icon_height` | `str` | `"14px"` | Altura do ícone |

#### `card_caption_ds(title, subtitle, icon, border, bg_color, border_radius)`
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| `title` | `str` | — | Texto em negrito centralizado |
| `subtitle` | `str` | `""` | Texto regular após o título |
| `icon` | `str` | `""` | Emoji exibido à esquerda |
| `border` | `str` | `""` | Valor CSS da borda (ex: `"1px solid #333"`) |
| `bg_color` | `str` | `"#fff"` | Cor de fundo |
| `border_radius` | `str` | `"15px"` | Arredondamento dos cantos |

#### `card_metric_ds(title, value, icon, enabled_icon, delta_visible, delta, delta_color, delta_bg_color, tooltip, key, category_type, size, footer_visible, footer_value)`
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| `title` | `str` | — | Label do metric |
| `value` | `str` | — | Valor principal |
| `delta_visible` | `bool` | `False` | Exibe o delta |
| `delta` | `str` | `""` | Texto do delta |
| `delta_color` | `str` | `ACURACIA_HIGH_DELTA` | Cor do texto do delta |
| `delta_bg_color` | `str` | `""` | Cor de fundo do delta |
| `category_type` | `CategoryType` | `None` | Cor da borda inferior (`HIGH`, `MEDIUM`, `LOW`) |
| `size` | `"sm"/"md"/"lg"` | `"sm"` | Tamanho do card |
| `footer_visible` | `bool` | `False` | Exibe texto de rodapé |
| `footer_value` | `str` | `""` | Texto do rodapé |

#### `fieldset_legend_ds(legend, fields, margin_bottom)`
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| `legend` | `str` | — | Texto sobreposto na borda (ex: `"Empresa"`) |
| `fields` | `list[dict]` | — | Lista de dicts `{"label": ..., "value": ...}` (1–4 itens) |
| `margin_bottom` | `str` | `"12px"` | Espaçamento abaixo do card |

#### `info_bar_ds(text, bg_color, border, border_radius, text_color, margin_bottom, icon_title, icon_visible, content_copy_visible)`
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| `text` | `str` | — | Texto da barra |
| `bg_color` | `str` | `INFO_BG` | Cor de fundo |
| `border` | `str` | `"1.5px solid INFO_BORDER"` | Borda CSS completa |
| `border_radius` | `str` | `"4px"` | Raio da borda |
| `text_color` | `str` | `""` | Cor do texto |
| `icon_title` | `str` | `"folder_copy"` | Nome do ícone Material Symbols (esquerda) |
| `icon_visible` | `bool` | `False` | Exibe ícone à esquerda |
| `content_copy_visible` | `bool` | `False` | Exibe botão de copiar à direita |

#### `loader_ds(title, status_text, duration_ms, steps, step_weights, manual, countdown_seconds)`
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| `title` | `str` | `"Carregando dados..."` | Título do card |
| `status_text` | `str` | `"Começando o teste"` | Texto estático (sem steps) |
| `duration_ms` | `int` | `5000` | Duração total em ms |
| `steps` | `list[str]` | `None` | Textos exibidos sequencialmente |
| `step_weights` | `list[float]` | `None` | Pesos proporcionais de cada step |
| `manual` | `bool` | `False` | Loop infinito até `placeholder.empty()` |
| `countdown_seconds` | `int` | `0` | Duração base do ciclo em segundos |

> Use `loader_ds_html(...)` com `st.empty().markdown(...)` para controle programático do ciclo de vida.

#### `record_ds(razao_social, cnpj, ie, gerfe, icon_visible, icon)`
| Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
| `razao_social` | `str` | — | Nome/razão social |
| `cnpj` | `str` | `""` | CNPJ do contribuinte |
| `ie` | `str` | `""` | Inscrição Estadual |
| `gerfe` | `str` | `""` | Nome do GERFE |
| `icon_visible` | `bool` | `False` | Exibe ícone Material Symbols |
| `icon` | `str` | `"storefront"` | Nome do ícone Material Symbols |

---

### Estrutura do pacote

```
sat_ds/
├── myproject.toml
└── src/
    ├── components/
    │   ├── __init__.py
    │   ├── accordeon_ds/
    │   ├── button_ds/
    │   ├── card_caption_ds/
    │   ├── card_dist_ds/
    │   ├── card_metric_ds/
    │   ├── fieldset_legend_ds/
    │   ├── identification_field_ds/
    │   ├── info_bar_ds/
    │   ├── loader_ds/
    │   ├── panel_ds/
    │   ├── record_ds/
    │   └── tabs_ds/
    └── theme/
        ├── __init__.py
        └── colors.py
```

Cada componente segue a estrutura:
```
component_name/
├── __init__.py          # exporta a função principal
├── component_name.py    # implementação Python
└── css/
    └── component_name.css  # estilos do componente
```

---

### Dependências externas

Os componentes fazem uso de constantes de cores e variáveis CSS provenientes do pacote `theme`:

```python
from theme import inject_theme_css          # injeta variáveis CSS no app
from theme.colors import ACURACIA_HIGH, BORDER, INFO_BG, ...  # constantes Python
```

Certifique-se de que o pacote de tema do SAT esteja instalado junto ao `sat-ds`.

---

### Licença

MIT © lpozza

---
---

## 🇺🇸 English

### About the project

**SAT Design System** (`sat-ds`) is a Python component library built on top of [Streamlit](https://streamlit.io), created to standardize the visual interface of applications embedded in the **SAT** system via MainFrame.

The library was born from the need to reuse UI components with a consistent visual identity across subsequent applications that are embedded inside the main platform. Instead of recreating styles and UI logic in each individual project, `sat-ds` centralizes these elements into a single pip-installable package.

Each component was carefully redesigned following the exclusive SAT Design System guidelines, ensuring visual cohesion and a uniform user experience across all platform applications.

---

### Installation

#### Requirements

- Python >= 3.9
- Streamlit installed in the consuming project

#### Via pip (internal / local registry)

```bash
pip install sat-ds
```

#### Via pip pointing to a Git repository

```bash
pip install git+https://github.com/your-org/sat-ds.git
```

#### Via local file (during development)

Clone the repository and install in editable mode:

```bash
git clone https://github.com/your-org/sat-ds.git
cd sat-ds
pip install -e .
```

---

### Theme and CSS variables

Before using any component, inject the theme CSS variables **once** at the top of your app. This ensures all color tokens (`var(--color-xxx)`) are available on the page:

```python
from theme import inject_theme_css
inject_theme_css()
```

---

### Available components

| Component | Main function | Description |
|---|---|---|
| `accordeon_ds` | `with accordeon(label, expanded, key, icon_color)` | Styled collapsible section with icon color support |
| `button_ds` | `button_ds(title, bg_color, icon_width, icon_height, ...)` | Pill-shaped styled button with optional SVG icon |
| `card_caption_ds` | `card_caption_ds(title, subtitle, icon, ...)` | Simple card with optional icon, bold title and subtitle |
| `card_dist_ds` | `card_dist_ds(title, value, percent, itens, companys, ...)` | Distribution card with monetary values, percentages and meta labels |
| `card_metric_ds` | `card_metric_ds(title, value, delta_visible, footer_visible, ...)` | Metric card with delta, tooltip, footer and size variation |
| `fieldset_legend_ds` | `fieldset_legend_ds(legend, fields, ...)` | Fieldset card with overlapping legend and dynamic label/value fields |
| `identification_field_ds` | `identification_field_ds(label, placeholder, ...)` | Styled text input for identifier entry |
| `info_bar_ds` | `info_bar_ds(text, icon_visible, content_copy_visible, ...)` | Info bar with optional icon, colors and copy button |
| `loader_ds` | `loader_ds(title, steps, duration_ms, manual, ...)` | Animated loading overlay with steps and manual mode support |
| `panel_ds` | `with panel_ds(key, ...)` | Styled border container, used as a context manager |
| `record_ds` | `record_ds(razao_social, cnpj, ie, gerfe, ...)` | Taxpayer identification card |
| `tabs_ds` | `tabs_ds(["Tab A", "Tab B"])` | Styled wrapper over `st.tabs()` |

---

### Basic usage

```python
import streamlit as st
from theme import inject_theme_css
from components import (
    accordeon,
    button_ds,
    card_caption_ds,
    card_metric_ds,
    CategoryType,
    fieldset_legend_ds,
    info_bar_ds,
    loader_ds, loader_ds_html,
    panel_ds,
    record_ds,
    tabs_ds,
)

# Inject theme CSS variables (required, once per app)
inject_theme_css()

# Button
if button_ds("Search", bg_color="#375C38", enabled_icon=True, key="btn_1"):
    st.write("Clicked!")

# Metric card with delta and footer
card_metric_ds(
    title="Total Collected",
    value="R$ 1,250,000.00",
    delta_visible=True,
    delta="▲ 12.5%",
    delta_color="#6A9B53",
    footer_visible=True,
    footer_value="Fiscal Year 2024",
    category_type=CategoryType.HIGH,
    size="md",
    key="metric_1",
)

# Caption card
card_caption_ds(
    title="HIGH",
    subtitle=" - AI Consensus",
    icon="✅",
    border="1px solid #6A9B53",
    bg_color="#F0F7EE",
)

# Fieldset with dynamic fields
fieldset_legend_ds(
    legend="Company",
    fields=[
        {"label": "Name", "value": "Example Corp"},
        {"label": "Tax ID", "value": "00.000.000/0001-00"},
    ],
)

# Taxpayer record card
record_ds(
    razao_social="Example Corp LTDA",
    cnpj="00.000.000/0001-00",
    ie="123.456.789",
    gerfe="GERFE 01",
    icon_visible=True,
)

# Info bar with icon and copy button
info_bar_ds(
    "Data refers to the current fiscal year.",
    icon_visible=True,
    icon_title="info",
    content_copy_visible=True,
)

# Loader overlay (programmatic lifecycle)
placeholder = st.empty()
placeholder.markdown(
    loader_ds_html(
        title="Processing...",
        steps=["Loading data", "Calculating", "Finishing"],
        duration_ms=6000,
    ),
    unsafe_allow_html=True,
)
# ... processing ...
placeholder.empty()  # removes the overlay

# Panel (bordered container)
with panel_ds(key="main_panel"):
    st.write("Content inside the panel")

# Tabs
tab_a, tab_b = tabs_ds(["Summary", "Details"])
with tab_a:
    st.write("Summary tab content")

# Accordion with icon color
with accordeon(":material/bar_chart: Distribution by Year", expanded=False, key="acc_1", icon_color="#6A9B53"):
    st.write("Expandable content")
```

---

### Package structure

```
sat_ds/
├── myproject.toml
└── src/
    ├── components/
    │   ├── __init__.py
    │   ├── accordeon_ds/
    │   ├── button_ds/
    │   ├── card_caption_ds/
    │   ├── card_dist_ds/
    │   ├── card_metric_ds/
    │   ├── fieldset_legend_ds/
    │   ├── identification_field_ds/
    │   ├── info_bar_ds/
    │   ├── loader_ds/
    │   ├── panel_ds/
    │   ├── record_ds/
    │   └── tabs_ds/
    └── theme/
        ├── __init__.py
        └── colors.py
```

Each component follows this structure:
```
component_name/
├── __init__.py          # exports the main function
├── component_name.py    # Python implementation
└── css/
    └── component_name.css  # component styles
```

---

### External dependencies

Components rely on color constants and CSS variables from the `theme` package:

```python
from theme import inject_theme_css           # injects CSS variables into the app
from theme.colors import ACURACIA_HIGH, BORDER, INFO_BG, ...  # Python constants
```

Make sure the SAT theme package is installed alongside `sat-ds`.

---

### License

MIT © lpozza
