Metadata-Version: 2.4
Name: clorui
Version: 1.0.1
Summary: Declarative Python GUI framework with HTML/CSS syntax and React Hooks for CustomTkinter
Author: CloroDev
License: MIT
Project-URL: Homepage, https://github.com/CloroFramework/clorui
Project-URL: Repository, https://github.com/CloroFramework/clorui
Keywords: gui,tkinter,customtkinter,html,css,react,hooks,desktop,ui
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: Desktop Environment
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: customtkinter>=5.2.0
Requires-Dist: Pillow>=9.0.0
Requires-Dist: darkdetect>=0.8.0
Provides-Extra: build
Requires-Dist: pyinstaller>=6.0.0; extra == "build"
Dynamic: license-file
Dynamic: requires-python

# 🧪 ClorUI Framework

**ClorUI** es un framework moderno, ligero y elegante para Python que te permite crear ventanas de escritorio con **Tkinter / CustomTkinter** utilizando sintaxis declarativa de **HTML (con etiquetas `<tag> </tag>`) y estilos CSS**.

---

## ✨ Características Principales

- 🏷️ **Sintaxis HTML Declarativa**: Diseña tus ventanas con etiquetas familiares como `<window>`, `<div>`, `<row>`, `<card>`, `<h1>`, `<button>`, `<input>`, `<switch>`, `<select>`, `<tabview>`, etc.
- ⚛️ **React Hooks (`useState`, `useEffect`, `useRef`, `useMemo`)**: Manejo de estado reactivo e interpolaciones automáticas `{{ variable }}` al estilo React en Python.
- 🎨 **Estilos CSS Completos**: Usa clases (`.mi-clase`), IDs (`#mi-id`), selectores de etiquetas, inline `style="..."` y soporte para hover (`:hover`).
- ⚡ **Fácil e Intuitivo en Python**: Obtén y actualiza valores con `app.get_value("id")`, `app.set_text("id", "nuevo texto")`, o vincula eventos con `@app.handler()`.
- 🌙 **Modo Oscuro/Claro y Estética Moderna**: Basado en CustomTkinter para ofrecer bordes redondeados, sombras, colores vibrantes y soporte nativo para temas oscuros y claros.
- 📁 **Modular**: Escribe tu HTML y CSS dentro del mismo código Python o en archivos `.html` y `.css` independientes.

---

## 🚀 Inicio Rápido (En 5 líneas)

```python
from clorui import ClorUIApp

app = ClorUIApp()

HTML = """
<window title="Mi Primera App con ClorUI" width="480" height="340" theme="dark">
    <style>
        .box { padding: 24px; gap: 12px; }
        .title { font-size: 24px; font-weight: bold; color: #38bdf8; }
        .btn { background: #3b82f6; hover-color: #2563eb; color: white; border-radius: 8px; }
    </style>
    <div class="box">
        <h1 class="title">¡Hola Mundo desde ClorUI! 🧪</h1>
        <input id="nombre" placeholder="Escribe tu nombre..." />
        <select id="genero" options="Masculino, Femenino, Otro" />
        <button class="btn" onclick="saludar">Saludar 🎉</button>
        <label id="saludo" text="" />
    </div>
</window>
"""

@app.handler()
def saludar():
    nombre = app.get_value("nombre")
    genero = app.get_value("genero")
    if nombre:
        app.set_text("saludo", f"¡Bienvenido/a {nombre}! Género: {genero}")
    else:
        app.set_text("saludo", "¡Por favor escribe tu nombre!")

app.load_html(HTML)
app.run()
```

---

## 🏷️ Catálogo de Etiquetas Soportadas

| Etiqueta | Descripción | Atributos Principales |
| :--- | :--- | :--- |
| `<window>` | Ventana principal de la app | `title`, `width`, `height`, `theme` ("dark"/"light"), `color-theme`, `resizable` |
| `<div>` / `<container>` / `<box>` | Contenedor vertical estándar | `class`, `style`, `id`, `scrollable="true"` |
| `<row>` / `<flex-row>` | Contenedor horizontal | `class`, `style`, `gap` |
| `<col>` / `<flex-col>` | Contenedor vertical | `class`, `style`, `gap` |
| `<card>` | Tarjeta con fondo y bordes redondeados | `class`, `style`, `corner-radius` |
| `<h1>` .. `<h6>` | Títulos y subtítulos con jerarquía tipográfica | `text`, `class`, `style` |
| `<p>`, `<span>`, `<label>` | Texto de párrafo / etiquetas | `text`, `class`, `style` |
| `<button>`, `<a>`, `<btn>` | Botones interactivos con hover | `text`, `onclick`, `class`, `style` |
| `<input>` | Entradas de texto, contraseñas, etc. | `type` ("text", "password", "checkbox", "switch", "slider"), `placeholder`, `value`, `onenter` |
| `<textarea>` | Área de texto multilinea | `value`, `placeholder`, `rows` |
| `<checkbox>` | Casilla de verificación | `text`, `checked="true"`, `onchange` |
| `<switch>` | Interruptor moderno | `text`, `checked="true"`, `onchange` |
| `<slider>` / `<range>` | Deslizador de rango numérico | `min`, `max`, `step`, `value`, `onchange` |
| `<progressbar>` | Barra de progreso | `value` (0.0 a 1.0 o 0 a 100) |
| `<select>` / `<dropdown>` | Menú desplegable / Selección | `options="Opción 1, Opción 2"` o hijos `<option>` |
| `<segmented>` | Selector de segmentos horizontal | `values="Op1, Op2, Op3"`, `onchange` |
| `<tabview>` | Contenedor de pestañas modernas | Hijos `<tab title="...">` |
| `<img>` / `<image>` | Imágenes (con Pillow) | `src="ruta.png"`, `width`, `height` |
| `<hr>` | Línea divisoria horizontal | `size`, `class`, `style` |
| `<spacer>` | Espacio vacío de separación | `size="20"` |

---

## 🎨 Propiedades CSS Soportadas

Puedes usar hojas `<style>`, archivos `.css` o `style="..."` inline:

- **Colores**: `background`, `background-color`, `color`, `text-color`, `hover-color`
- **Bordes**: `border-radius` / `corner-radius`, `border-width`, `border-color`
- **Dimensiones**: `width`, `height`
- **Tipografía**: `font-size`, `font-family`, `font-weight` (`bold`, `normal`), `font-style` (`italic`)
- **Espaciados**: `padding` (`10px 20px`), `padding-x`, `padding-y`, `margin`, `margin-x`, `margin-y`, `gap`
- **Alineación**: `align` / `text-align` (`left`, `center`, `right`)
- **Pseudo-clases**: `:hover` (ejemplo: `.btn:hover { background: #1d4ed8; }`)

---

## 🕹️ Métodos de la Aplicación (`ClorUIApp`)

- `app.load_html(html_str, stylesheet=None, handlers=None)`: Carga una plantilla HTML.
- `app.load_file(html_path, css_path=None, handlers=None)`: Carga desde archivos externos.
- `app.create_subwindow(html_str, title, width, height)`: Abre una subventana modal/toplevel emergente renderizando HTML/CSS.
- `app.get_value("id")`: Obtiene el valor de un elemento (texto en input, valor de select, bool en switch/checkbox, float en slider).
- `app.set_value("id", nuevo_valor)`: Modifica el valor de un elemento.
- `app.set_text("id", "nuevo texto")`: Modifica el texto de una etiqueta o botón.
- `app.get_element("id")`: Retorna el objeto `Element` con métodos `.hide()`, `.show()`, `.toggle()`, `.clear()`, `.focus()`, `.add_class()`, `.remove_class()`.
- `@app.handler()`: Decorador para registrar funciones de eventos (`onclick`, `onchange`, etc.).
- `app.run()`: Inicia la ventana.

---

## ⚛️ React Context & Hooks API (`createContext`, `useContext`)

ClorUI ofrece soporte completo para el patrón de Contextos globales de React:

```python
from clorui import ClorUIApp, createContext, useContext, useState

# 1. Definir contexto global
TitleContext = createContext("🗄️ Mi Cajonera", name="app_title")

app = ClorUIApp()

@app.handler()
def cambiar_titulo():
    # 2. Acceder y mutar mediante useContext
    titulo_state, set_titulo = useContext(TitleContext)
    set_titulo("Nuevo Título Mágico ✨")

HTML = """
<window>
    <!-- Se actualiza reactivamente al cambiar el contexto -->
    <h1>{{ app_title }}</h1>
    <button onclick="cambiar_titulo">Cambiar Título</button>
</window>
"""
app.load_html(HTML)
app.run()
```

---

## 🔥 Hot Reloading y Modo Desarrollo

ClorUI incluye soporte nativo para **Hot Reloading** y **Live Reloading** sin librerías externas adicionales. Al guardar cualquier cambio en tu código (`Ctrl + S`), la aplicación se actualiza de inmediato.

### 1. Desde Python (`hot_reload=True`)
```python
if __name__ == "__main__":
    app.run(hot_reload=True)
```

### 2. Desde la Terminal / CLI (`clorui dev`)
```bash
python -m clorui dev mi_app.py
# o si está instalado vía pip:
clorui dev mi_app.py
```

### 3. Live Reloading de HTML y CSS externos
Si cargas tus plantillas desde archivos separados, los cambios en HTML y CSS se refrescan en caliente en la misma ventana:
```python
app.load_file("index.html", "styles.css", live_reload=True)
```

---

## 🚀 Compilación a Ejecutables (.exe y Linux)

ClorUI incluye un sistema de empaquetado integrado (`PyInstaller`) que crea una carpeta con el nombre de tu archivo (ej: `08_cajonera_poetica/`) y coloca el ejecutable dentro de su subcarpeta `dist/`:

### 1. Compilar para Windows (.exe)
```python
# En tu archivo Python:
app.run(build_win=True)
# O mediante el método build():
app.build(build_win=True)
```
Genera:
```text
08_cajonera_poetica/
  ├── dist/
  │    └── 08_cajonera_poetica.exe   <-- Ejecutable independiente
  ├── build/
  └── 08_cajonera_poetica.spec
```

### 2. Compilar para Linux
```python
app.run(build_lin=True)
```
Si estás en Linux compila el binario directamente, y si estás en Windows genera el script de compilación `build_linux.sh` / compatible con Docker y WSL.

### 3. Opciones adicionales de empaquetado:
```python
app.run(
    build_win=True,
    onefile=True,          # Empaqueta en un único archivo
    noconsole=True,        # Oculta la consola negra de comandos
    icon="mi_icono.ico"    # Asigna un icono personalizado
)
```

---

## 📁 Ejemplos Disponibles en `/examples`

- `01_hola_mundo.py`: Hola mundo con inputs, selects y eventos.
- `02_formulario.py`: Formulario completo con validación y componentes visuales.
- `03_dashboard.py`: Dashboard con gráficos, estadísticas y múltiples tarjetas.
- `04_html_css_separados/`: Separación de lógica en `.html`, `.css` y `.py`.
- `05_iconos.py`: Soporte para imágenes e iconos en botones y etiquetas.
- `06_react_hooks.py`: Uso de `useState`, `useEffect`, `useRef`, `useMemo`.
- `07_hot_reload.py`: Demostración del motor de recarga en caliente instantánea.
- `08_cajonera_poetica.py`: Cajonera con items, subventanas con poemas, cambio total de vista con retorno y mutación de `useContext` del título.

---

## 📦 Instalación

Para instalarlo en tu entorno:
```bash
pip install -e .
```
o simplemente importa `clorui`:
```python
from clorui import ClorUIApp
```


