fletplus 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Adolfo González
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the “Software”), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,100 @@
1
+ Metadata-Version: 2.4
2
+ Name: fletplus
3
+ Version: 0.1.0
4
+ Summary: Componentes visuales avanzados para Flet en Python
5
+ Home-page: https://github.com/tu_usuario/fletplus
6
+ Author: Adolfo González Hernández
7
+ Author-email: Adolfo González <adolfogonzal@gmail.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://github.com/Alphonsus411/fletplus
10
+ Project-URL: Repository, https://github.com/Alphonsus411/fletplus
11
+ Project-URL: Documentation, https://github.com/Alphonsus411/fletplus#readme
12
+ Requires-Python: >=3.8
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE.md
15
+ Requires-Dist: flet>=0.27.0
16
+ Dynamic: author
17
+ Dynamic: home-page
18
+ Dynamic: license-file
19
+ Dynamic: requires-python
20
+
21
+ # 🚀 FletPlus
22
+
23
+ **FletPlus** es una librería de componentes visuales y utilidades para acelerar el desarrollo de interfaces modernas en Python usando [Flet](https://flet.dev).
24
+ Proporciona un conjunto de controles personalizables como tablas inteligentes, grillas responsivas, barras laterales, gestores de tema y estructura modular de apps.
25
+
26
+ ---
27
+
28
+ ## 📦 Instalación
29
+
30
+ ```bash
31
+ pip install fletplus
32
+ ```
33
+ - **Requiere Python 3.9+ y flet>=0.27.0**
34
+
35
+ ## 🧩 Componentes incluidos
36
+
37
+ | Componente | Descripción |
38
+ |----------------|---------------------------------------------------|
39
+ | `SmartTable` | Tabla con paginación y ordenamiento integrados |
40
+ | `SidebarAdmin` | Menú lateral dinámico con ítems y selección |
41
+ | `ResponsiveGrid` | Distribución de contenido adaptable a pantalla |
42
+ | `ThemeManager` | Gestión centralizada de modo claro/oscuro |
43
+ | `FletPlusApp` | Estructura base para apps con navegación y tema |
44
+
45
+ # 🧪 Ejemplo rápido
46
+
47
+ ```python
48
+ import flet as ft
49
+ from fletplus.components.smart_table import SmartTable
50
+
51
+ def main(page: ft.Page):
52
+ rows = [
53
+ ft.DataRow(cells=[ft.DataCell(ft.Text("1")), ft.DataCell(ft.Text("Alice"))]),
54
+ ft.DataRow(cells=[ft.DataCell(ft.Text("2")), ft.DataCell(ft.Text("Bob"))]),
55
+ ]
56
+ table = SmartTable(["ID", "Nombre"], rows)
57
+ page.add(table.build())
58
+
59
+ ft.app(target=main)
60
+ ```
61
+ # 🔧 Estructura del proyecto
62
+
63
+ fletplus/
64
+ ├── components/
65
+ │ ├── smart_table.py
66
+ │ ├── sidebar_admin.py
67
+ │ └── responsive_grid.py
68
+ ├── themes/
69
+ │ └── theme_manager.py
70
+ ├── core.py ← Clase FletPlusApp
71
+
72
+ # 📋 Tests
73
+
74
+ Todos los componentes están cubiertos por tests unitarios (ver carpeta tests/).
75
+
76
+ ```bash
77
+ pytest --cov=fletplus
78
+ ```
79
+
80
+ # 🛠️ Contribuir
81
+
82
+ Las contribuciones son bienvenidas:
83
+
84
+ 1. **Haz un fork**
85
+
86
+ 2. **Crea tu rama**: git checkout -b feature/nueva-funcionalidad
87
+
88
+ 3. **Abre un PR** explicando el cambio
89
+
90
+ # 📄 Licencia
91
+
92
+ MIT License
93
+
94
+ Copyright (c) 2025 Adolfo González
95
+
96
+ # 💬 Contacto
97
+
98
+ Desarrollado por Adolfo González Hernández.
99
+
100
+ **email**: adolfogonzal@gmail.com
@@ -0,0 +1,80 @@
1
+ # 🚀 FletPlus
2
+
3
+ **FletPlus** es una librería de componentes visuales y utilidades para acelerar el desarrollo de interfaces modernas en Python usando [Flet](https://flet.dev).
4
+ Proporciona un conjunto de controles personalizables como tablas inteligentes, grillas responsivas, barras laterales, gestores de tema y estructura modular de apps.
5
+
6
+ ---
7
+
8
+ ## 📦 Instalación
9
+
10
+ ```bash
11
+ pip install fletplus
12
+ ```
13
+ - **Requiere Python 3.9+ y flet>=0.27.0**
14
+
15
+ ## 🧩 Componentes incluidos
16
+
17
+ | Componente | Descripción |
18
+ |----------------|---------------------------------------------------|
19
+ | `SmartTable` | Tabla con paginación y ordenamiento integrados |
20
+ | `SidebarAdmin` | Menú lateral dinámico con ítems y selección |
21
+ | `ResponsiveGrid` | Distribución de contenido adaptable a pantalla |
22
+ | `ThemeManager` | Gestión centralizada de modo claro/oscuro |
23
+ | `FletPlusApp` | Estructura base para apps con navegación y tema |
24
+
25
+ # 🧪 Ejemplo rápido
26
+
27
+ ```python
28
+ import flet as ft
29
+ from fletplus.components.smart_table import SmartTable
30
+
31
+ def main(page: ft.Page):
32
+ rows = [
33
+ ft.DataRow(cells=[ft.DataCell(ft.Text("1")), ft.DataCell(ft.Text("Alice"))]),
34
+ ft.DataRow(cells=[ft.DataCell(ft.Text("2")), ft.DataCell(ft.Text("Bob"))]),
35
+ ]
36
+ table = SmartTable(["ID", "Nombre"], rows)
37
+ page.add(table.build())
38
+
39
+ ft.app(target=main)
40
+ ```
41
+ # 🔧 Estructura del proyecto
42
+
43
+ fletplus/
44
+ ├── components/
45
+ │ ├── smart_table.py
46
+ │ ├── sidebar_admin.py
47
+ │ └── responsive_grid.py
48
+ ├── themes/
49
+ │ └── theme_manager.py
50
+ ├── core.py ← Clase FletPlusApp
51
+
52
+ # 📋 Tests
53
+
54
+ Todos los componentes están cubiertos por tests unitarios (ver carpeta tests/).
55
+
56
+ ```bash
57
+ pytest --cov=fletplus
58
+ ```
59
+
60
+ # 🛠️ Contribuir
61
+
62
+ Las contribuciones son bienvenidas:
63
+
64
+ 1. **Haz un fork**
65
+
66
+ 2. **Crea tu rama**: git checkout -b feature/nueva-funcionalidad
67
+
68
+ 3. **Abre un PR** explicando el cambio
69
+
70
+ # 📄 Licencia
71
+
72
+ MIT License
73
+
74
+ Copyright (c) 2025 Adolfo González
75
+
76
+ # 💬 Contacto
77
+
78
+ Desarrollado por Adolfo González Hernández.
79
+
80
+ **email**: adolfogonzal@gmail.com
File without changes
File without changes
@@ -0,0 +1,37 @@
1
+ import flet as ft
2
+
3
+ class ResponsiveGrid:
4
+ def __init__(self, children: list[ft.Control], breakpoints=None, spacing=10):
5
+ """
6
+ :param children: Lista de widgets (flet.Control) a distribuir en la grilla.
7
+ :param breakpoints: Diccionario {ancho_px: columnas}, por ejemplo {0: 1, 600: 2, 900: 3}
8
+ :param spacing: Espaciado entre elementos
9
+ """
10
+ self.children = children
11
+ self.spacing = spacing
12
+ self.breakpoints = breakpoints or {
13
+ 0: 1,
14
+ 600: 2,
15
+ 900: 3,
16
+ 1200: 4
17
+ }
18
+
19
+ def build(self, page_width: int):
20
+ # Determinar cuántas columnas según el ancho de página
21
+ columns = 1
22
+ for bp, cols in sorted(self.breakpoints.items()):
23
+ if page_width >= bp:
24
+ columns = cols
25
+
26
+ col_span = max(1, int(12 / columns)) # Sistema de 12 columnas de Flet
27
+
28
+ return ft.ResponsiveRow(
29
+ controls=[
30
+ ft.Container(
31
+ content=child,
32
+ col=col_span,
33
+ padding=self.spacing
34
+ ) for child in self.children
35
+ ],
36
+ alignment=ft.MainAxisAlignment.START
37
+ )
@@ -0,0 +1,52 @@
1
+ # fletplus/components/sidebar_admin.py
2
+
3
+ import flet as ft
4
+
5
+ class SidebarAdmin:
6
+ def __init__(self, menu_items, on_select=None, header="Menú", width=250):
7
+ """
8
+ :param menu_items: Lista de dicts con {"title": str, "icon": ft.IconName}
9
+ :param on_select: Función callback cuando se selecciona un ítem
10
+ :param header: Título de la barra lateral
11
+ :param width: Anchura del sidebar
12
+ """
13
+ self.menu_items = menu_items
14
+ self.on_select = on_select
15
+ self.header = header
16
+ self.width = width
17
+ self.selected_index = 0
18
+ self.tiles = [] # Para actualizar visualmente los seleccionados
19
+
20
+ def build(self):
21
+ self.tiles = []
22
+
23
+ for i, item in enumerate(self.menu_items):
24
+ tile = ft.ListTile(
25
+ title=ft.Text(item["title"]),
26
+ leading=ft.Icon(item.get("icon", ft.icons.CIRCLE)),
27
+ selected=(i == self.selected_index),
28
+ on_click=lambda e, idx=i: self._select_item(idx, e),
29
+ )
30
+ self.tiles.append(tile)
31
+
32
+ return ft.Container(
33
+ width=self.width,
34
+ bgcolor=ft.colors.SURFACE_VARIANT,
35
+ padding=10,
36
+ content=ft.Column([
37
+ ft.Text(self.header, size=20, weight="bold"),
38
+ ft.Divider(),
39
+ ft.Column(self.tiles, expand=True),
40
+ ])
41
+ )
42
+
43
+ def _select_item(self, index, e):
44
+ self.selected_index = index
45
+
46
+ for i, tile in enumerate(self.tiles):
47
+ tile.selected = (i == index)
48
+
49
+ if self.on_select:
50
+ self.on_select(index)
51
+
52
+ e.control.page.update()
@@ -0,0 +1,70 @@
1
+ import flet as ft
2
+
3
+ class SmartTable:
4
+ def __init__(self, columns, rows, sortable=True, page_size=10):
5
+ self.columns = columns
6
+ self.rows = rows
7
+ self.sortable = sortable
8
+ self.page_size = page_size
9
+ self.current_page = 0
10
+ self.sorted_column = None
11
+ self.sort_ascending = True
12
+
13
+ def build(self):
14
+ return ft.Column([
15
+ ft.DataTable(
16
+ columns=[
17
+ ft.DataColumn(
18
+ label=ft.Text(col),
19
+ on_sort=self._on_sort(index) if self.sortable else None
20
+ ) for index, col in enumerate(self.columns)
21
+ ],
22
+ rows=self._get_page_rows()
23
+ ),
24
+ ft.Row([
25
+ ft.ElevatedButton("Anterior", on_click=self._previous_page),
26
+ ft.ElevatedButton("Siguiente", on_click=self._next_page),
27
+ ])
28
+ ])
29
+
30
+ def _on_sort(self, col_index):
31
+ def handler(e):
32
+ if self.sorted_column == col_index:
33
+ self.sort_ascending = not self.sort_ascending
34
+ else:
35
+ self.sorted_column = col_index
36
+ self.sort_ascending = True
37
+
38
+ self.rows.sort(
39
+ key=lambda x: x.cells[col_index].content.value,
40
+ reverse=not self.sort_ascending
41
+ )
42
+
43
+ # Intentar actualizar la página si existe
44
+ try:
45
+ e.control.page.update()
46
+ except AttributeError:
47
+ pass # Permite testear sin page real
48
+
49
+ return handler
50
+
51
+ def _get_page_rows(self):
52
+ start = self.current_page * self.page_size
53
+ end = start + self.page_size
54
+ return self.rows[start:end]
55
+
56
+ def _next_page(self, e):
57
+ if (self.current_page + 1) * self.page_size < len(self.rows):
58
+ self.current_page += 1
59
+ try:
60
+ e.control.page.update()
61
+ except AttributeError:
62
+ pass
63
+
64
+ def _previous_page(self, e):
65
+ if self.current_page > 0:
66
+ self.current_page -= 1
67
+ try:
68
+ e.control.page.update()
69
+ except AttributeError:
70
+ pass
@@ -0,0 +1,54 @@
1
+ import flet as ft
2
+ from fletplus.themes.theme_manager import ThemeManager
3
+ from fletplus.components.sidebar_admin import SidebarAdmin
4
+
5
+ class FletPlusApp:
6
+ def __init__(self, page: ft.Page, routes: dict, sidebar_items=None, title="FletPlus App", theme_config=None):
7
+ """
8
+ :param page: Página Flet actual
9
+ :param routes: Diccionario de rutas {str: Callable}
10
+ :param sidebar_items: Lista de ítems del sidebar [{title, icon}]
11
+ :param title: Título de la app
12
+ :param theme_config: Diccionario de configuración inicial del tema
13
+ """
14
+ self.page = page
15
+ self.routes = routes
16
+ self.sidebar_items = sidebar_items or []
17
+ self.theme = ThemeManager(page, **(theme_config or {}))
18
+ self.title = title
19
+
20
+ self.content_container = ft.Container(expand=True, bgcolor=ft.colors.BACKGROUND)
21
+ self.sidebar = SidebarAdmin(self.sidebar_items, on_select=self._on_nav)
22
+
23
+ def build(self):
24
+ self.page.title = self.title
25
+ self.page.horizontal_alignment = ft.CrossAxisAlignment.START
26
+ self.page.scroll = "auto"
27
+
28
+ self.theme.apply_theme()
29
+
30
+ # Mostrar primer contenido
31
+ self._load_route(0)
32
+
33
+ self.page.add(
34
+ ft.Row([
35
+ self.sidebar.build(),
36
+ self.content_container
37
+ ])
38
+ )
39
+
40
+ def _on_nav(self, index):
41
+ self._load_route(index)
42
+
43
+ def _load_route(self, index):
44
+ route_key = list(self.routes.keys())[index]
45
+ builder = self.routes[route_key]
46
+ self.content_container.content = builder()
47
+ self.page.update()
48
+
49
+ @classmethod
50
+ def start(cls, routes, sidebar_items=None, title="FletPlus App", theme_config=None):
51
+ def main(page: ft.Page):
52
+ app = cls(page, routes, sidebar_items, title, theme_config)
53
+ app.build()
54
+ ft.app(target=main)
File without changes
@@ -0,0 +1,25 @@
1
+ # fletplus/themes/theme_manager.py
2
+
3
+ import flet as ft
4
+
5
+ class ThemeManager:
6
+ def __init__(self, page: ft.Page, primary_color=ft.colors.BLUE):
7
+ self.page = page
8
+ self.primary_color = primary_color
9
+ self.dark_mode = False
10
+
11
+ def apply_theme(self):
12
+ self.page.theme = ft.Theme(
13
+ color_scheme_seed=self.primary_color
14
+ )
15
+ self.page.theme_mode = ft.ThemeMode.DARK if self.dark_mode else ft.ThemeMode.LIGHT
16
+ self.page.update()
17
+
18
+ def toggle_dark_mode(self):
19
+ self.dark_mode = not self.dark_mode
20
+ self.apply_theme()
21
+
22
+ def set_primary_color(self, color):
23
+ self.primary_color = color
24
+ self.apply_theme()
25
+
File without changes
File without changes
@@ -0,0 +1,100 @@
1
+ Metadata-Version: 2.4
2
+ Name: fletplus
3
+ Version: 0.1.0
4
+ Summary: Componentes visuales avanzados para Flet en Python
5
+ Home-page: https://github.com/tu_usuario/fletplus
6
+ Author: Adolfo González Hernández
7
+ Author-email: Adolfo González <adolfogonzal@gmail.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://github.com/Alphonsus411/fletplus
10
+ Project-URL: Repository, https://github.com/Alphonsus411/fletplus
11
+ Project-URL: Documentation, https://github.com/Alphonsus411/fletplus#readme
12
+ Requires-Python: >=3.8
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE.md
15
+ Requires-Dist: flet>=0.27.0
16
+ Dynamic: author
17
+ Dynamic: home-page
18
+ Dynamic: license-file
19
+ Dynamic: requires-python
20
+
21
+ # 🚀 FletPlus
22
+
23
+ **FletPlus** es una librería de componentes visuales y utilidades para acelerar el desarrollo de interfaces modernas en Python usando [Flet](https://flet.dev).
24
+ Proporciona un conjunto de controles personalizables como tablas inteligentes, grillas responsivas, barras laterales, gestores de tema y estructura modular de apps.
25
+
26
+ ---
27
+
28
+ ## 📦 Instalación
29
+
30
+ ```bash
31
+ pip install fletplus
32
+ ```
33
+ - **Requiere Python 3.9+ y flet>=0.27.0**
34
+
35
+ ## 🧩 Componentes incluidos
36
+
37
+ | Componente | Descripción |
38
+ |----------------|---------------------------------------------------|
39
+ | `SmartTable` | Tabla con paginación y ordenamiento integrados |
40
+ | `SidebarAdmin` | Menú lateral dinámico con ítems y selección |
41
+ | `ResponsiveGrid` | Distribución de contenido adaptable a pantalla |
42
+ | `ThemeManager` | Gestión centralizada de modo claro/oscuro |
43
+ | `FletPlusApp` | Estructura base para apps con navegación y tema |
44
+
45
+ # 🧪 Ejemplo rápido
46
+
47
+ ```python
48
+ import flet as ft
49
+ from fletplus.components.smart_table import SmartTable
50
+
51
+ def main(page: ft.Page):
52
+ rows = [
53
+ ft.DataRow(cells=[ft.DataCell(ft.Text("1")), ft.DataCell(ft.Text("Alice"))]),
54
+ ft.DataRow(cells=[ft.DataCell(ft.Text("2")), ft.DataCell(ft.Text("Bob"))]),
55
+ ]
56
+ table = SmartTable(["ID", "Nombre"], rows)
57
+ page.add(table.build())
58
+
59
+ ft.app(target=main)
60
+ ```
61
+ # 🔧 Estructura del proyecto
62
+
63
+ fletplus/
64
+ ├── components/
65
+ │ ├── smart_table.py
66
+ │ ├── sidebar_admin.py
67
+ │ └── responsive_grid.py
68
+ ├── themes/
69
+ │ └── theme_manager.py
70
+ ├── core.py ← Clase FletPlusApp
71
+
72
+ # 📋 Tests
73
+
74
+ Todos los componentes están cubiertos por tests unitarios (ver carpeta tests/).
75
+
76
+ ```bash
77
+ pytest --cov=fletplus
78
+ ```
79
+
80
+ # 🛠️ Contribuir
81
+
82
+ Las contribuciones son bienvenidas:
83
+
84
+ 1. **Haz un fork**
85
+
86
+ 2. **Crea tu rama**: git checkout -b feature/nueva-funcionalidad
87
+
88
+ 3. **Abre un PR** explicando el cambio
89
+
90
+ # 📄 Licencia
91
+
92
+ MIT License
93
+
94
+ Copyright (c) 2025 Adolfo González
95
+
96
+ # 💬 Contacto
97
+
98
+ Desarrollado por Adolfo González Hernández.
99
+
100
+ **email**: adolfogonzal@gmail.com
@@ -0,0 +1,25 @@
1
+ LICENSE.md
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ fletplus/__init__.py
6
+ fletplus/core.py
7
+ fletplus.egg-info/PKG-INFO
8
+ fletplus.egg-info/SOURCES.txt
9
+ fletplus.egg-info/dependency_links.txt
10
+ fletplus.egg-info/requires.txt
11
+ fletplus.egg-info/top_level.txt
12
+ fletplus/components/__init__.py
13
+ fletplus/components/responsive_grid.py
14
+ fletplus/components/sidebar_admin.py
15
+ fletplus/components/smart_table.py
16
+ fletplus/themes/__init__.py
17
+ fletplus/themes/theme_manager.py
18
+ fletplus/utils/__init__.py
19
+ fletplus/utils/responsive_manager.py
20
+ tests/test_all.py
21
+ tests/test_fletplus_app.py
22
+ tests/test_responsive_grid.py
23
+ tests/test_sidebar_admin.py
24
+ tests/test_smart_table.py
25
+ tests/test_theme_manager.py
@@ -0,0 +1 @@
1
+ flet>=0.27.0
@@ -0,0 +1 @@
1
+ fletplus
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "fletplus"
7
+ version = "0.1.0"
8
+ description = "Componentes visuales avanzados para Flet en Python"
9
+ authors = [
10
+ { name="Adolfo González", email="adolfogonzal@gmail.com" }
11
+ ]
12
+ license = { text = "MIT" }
13
+ readme = "README.md"
14
+ requires-python = ">=3.9"
15
+
16
+ dependencies = [
17
+ "flet>=0.27.0"
18
+ ]
19
+
20
+ [project.urls]
21
+ Homepage = "https://github.com/Alphonsus411/fletplus"
22
+ Repository = "https://github.com/Alphonsus411/fletplus"
23
+ Documentation = "https://github.com/Alphonsus411/fletplus#readme"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,30 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="fletplus",
5
+ version="0.1.0",
6
+ author="Adolfo González Hernández",
7
+ author_email="adolfogonzal@gmail.com",
8
+ description="Componentes avanzados y utilidades para apps Flet en Python",
9
+ long_description=open("README.md", encoding="utf-8").read(),
10
+ long_description_content_type="text/markdown",
11
+ url="https://github.com/tu_usuario/fletplus", # Cambia esto si lo subes a GitHub
12
+ project_urls={
13
+ "Bug Tracker": "https://github.com/Alphonsus411/fletplus/issues",
14
+ },
15
+ license="MIT",
16
+ packages=find_packages(),
17
+ include_package_data=True,
18
+ install_requires=[
19
+ "flet>=0.8.0", # Ajusta según versión actual de Flet
20
+ ],
21
+ classifiers=[
22
+ "Development Status :: 3 - Alpha",
23
+ "Intended Audience :: Developers",
24
+ "Topic :: Software Development :: User Interfaces",
25
+ "License :: OSI Approved :: MIT License",
26
+ "Programming Language :: Python :: 3",
27
+ "Operating System :: OS Independent",
28
+ ],
29
+ python_requires='>=3.8',
30
+ )
@@ -0,0 +1,14 @@
1
+ # tests/test_all.py
2
+
3
+ from tests.test_smart_table import test_smart_table_full_behavior
4
+ from tests.test_sidebar_admin import test_sidebar_admin_build_and_selection
5
+ from tests.test_responsive_grid import test_responsive_grid_builds_correctly
6
+ from tests.test_theme_manager import test_theme_manager_initialization_and_toggle
7
+ from tests.test_fletplus_app import test_fletplus_app_initialization_and_routing
8
+
9
+ def test_all_components():
10
+ test_smart_table_full_behavior()
11
+ test_sidebar_admin_build_and_selection()
12
+ test_responsive_grid_builds_correctly()
13
+ test_theme_manager_initialization_and_toggle()
14
+ test_fletplus_app_initialization_and_routing()
@@ -0,0 +1,58 @@
1
+ import flet as ft
2
+
3
+ from fletplus.core import FletPlusApp
4
+
5
+
6
+ class DummyPage:
7
+ def __init__(self):
8
+ self.title = ""
9
+ self.controls = []
10
+ self.theme = None
11
+ self.theme_mode = None
12
+ self.scroll = None
13
+ self.horizontal_alignment = None
14
+ self.updated = False
15
+
16
+ def add(self, *controls):
17
+ self.controls.extend(controls)
18
+
19
+ def update(self):
20
+ self.updated = True
21
+
22
+ def test_fletplus_app_initialization_and_routing():
23
+ # Definir dos pantallas de prueba
24
+ def home_view():
25
+ return ft.Text("Inicio")
26
+
27
+ def users_view():
28
+ return ft.Text("Usuarios")
29
+
30
+ routes = {
31
+ "Inicio": home_view,
32
+ "Usuarios": users_view
33
+ }
34
+
35
+ sidebar_items = [
36
+ {"title": "Inicio", "icon": ft.icons.HOME},
37
+ {"title": "Usuarios", "icon": ft.icons.PEOPLE}
38
+ ]
39
+
40
+ # Crear instancia falsa de la página
41
+ page = DummyPage()
42
+
43
+ # Crear la app sin iniciar Flet
44
+ app = FletPlusApp(page, routes, sidebar_items, title="TestApp")
45
+
46
+ # Simular construcción
47
+ app.build()
48
+
49
+ # Verificaciones básicas
50
+ assert page.title == "TestApp"
51
+ assert len(page.controls) == 1 # Un solo ft.Row
52
+ assert app.content_container.content is not None
53
+ assert isinstance(app.content_container.content, ft.Text)
54
+ assert app.content_container.content.value == "Inicio"
55
+
56
+ # Simular navegación a la segunda página
57
+ app._on_nav(1)
58
+ assert app.content_container.content.value == "Usuarios"
@@ -0,0 +1,29 @@
1
+ import flet as ft
2
+ from fletplus.components.responsive_grid import ResponsiveGrid
3
+
4
+ def test_responsive_grid_builds_correctly():
5
+ # Crear una lista de widgets dummy
6
+ items = [
7
+ ft.Text(f"Elemento {i}") for i in range(4)
8
+ ]
9
+
10
+ # Breakpoints definidos manualmente
11
+ breakpoints = {
12
+ 0: 1,
13
+ 600: 2,
14
+ 900: 4
15
+ }
16
+
17
+ grid = ResponsiveGrid(children=items, breakpoints=breakpoints, spacing=5)
18
+
19
+ # Simular un ancho de 900px (esperamos 4 columnas)
20
+ layout = grid.build(page_width=900)
21
+
22
+ # Validaciones
23
+ assert isinstance(layout, ft.ResponsiveRow)
24
+ assert len(layout.controls) == len(items)
25
+
26
+ # Cada contenedor debe tener col=3 (12/4 columnas)
27
+ for container in layout.controls:
28
+ assert isinstance(container, ft.Container)
29
+ assert container.col == 3
@@ -0,0 +1,38 @@
1
+ import flet as ft
2
+ from fletplus.components.sidebar_admin import SidebarAdmin
3
+
4
+ def test_sidebar_admin_build_and_selection():
5
+ selected = []
6
+
7
+ def on_select(index):
8
+ selected.append(index)
9
+
10
+ menu_items = [
11
+ {"title": "Inicio", "icon": ft.icons.HOME},
12
+ {"title": "Usuarios", "icon": ft.icons.PEOPLE},
13
+ ]
14
+
15
+ sidebar = SidebarAdmin(menu_items=menu_items, on_select=on_select)
16
+ control = sidebar.build()
17
+
18
+ # Comprobar que se construye un Container con Column interna
19
+ assert isinstance(control, ft.Container)
20
+ assert isinstance(control.content, ft.Column)
21
+ assert len(sidebar.tiles) == 2 # Se crearon dos ListTile
22
+
23
+ # Simular evento con un objeto dummy que tiene e.control.page.update()
24
+ class DummyPage:
25
+ def update(self): pass
26
+
27
+ class DummyControl:
28
+ page = DummyPage()
29
+
30
+ class DummyEvent:
31
+ control = DummyControl()
32
+
33
+ # Ejecutar selección
34
+ sidebar._select_item(1, DummyEvent())
35
+
36
+ assert sidebar.selected_index == 1
37
+ assert selected == [1]
38
+ assert sidebar.tiles[1].selected is True
@@ -0,0 +1,48 @@
1
+ import flet as ft
2
+ from fletplus.components.smart_table import SmartTable
3
+
4
+ class DummyPage:
5
+ def update(self): pass
6
+
7
+ class DummyControl:
8
+ page = DummyPage()
9
+
10
+ class DummyEvent:
11
+ def __init__(self, column_index):
12
+ self.column_index = column_index
13
+ self.control = DummyControl()
14
+
15
+ def test_smart_table_full_behavior():
16
+ columns = ["ID", "Nombre"]
17
+ rows = [
18
+ ft.DataRow(cells=[ft.DataCell(ft.Text("2")), ft.DataCell(ft.Text("Bob"))]),
19
+ ft.DataRow(cells=[ft.DataCell(ft.Text("1")), ft.DataCell(ft.Text("Alice"))]),
20
+ ft.DataRow(cells=[ft.DataCell(ft.Text("3")), ft.DataCell(ft.Text("Charlie"))]),
21
+ ]
22
+
23
+ table = SmartTable(columns, rows, page_size=2)
24
+
25
+ assert table.current_page == 0
26
+ assert table.page_size == 2
27
+ assert table.sort_ascending is True
28
+ assert table.sorted_column is None
29
+
30
+ built = table.build()
31
+ assert isinstance(built, ft.Column)
32
+ assert any(isinstance(c, ft.DataTable) for c in built.controls)
33
+
34
+ sort_handler = table._on_sort(0)
35
+ sort_handler(DummyEvent(0))
36
+ assert table.sorted_column == 0
37
+ assert table.sort_ascending is True
38
+ assert table.rows[0].cells[0].content.value == "1"
39
+
40
+ sort_handler(DummyEvent(0))
41
+ assert table.sort_ascending is False
42
+ assert table.rows[0].cells[0].content.value == "3"
43
+
44
+ table._next_page(DummyEvent(0))
45
+ assert table.current_page == 1
46
+
47
+ table._previous_page(DummyEvent(0))
48
+ assert table.current_page == 0
@@ -0,0 +1,33 @@
1
+ import flet as ft
2
+ from fletplus.themes.theme_manager import ThemeManager
3
+
4
+ class DummyPage:
5
+ def __init__(self):
6
+ self.theme = None
7
+ self.theme_mode = None
8
+ self.updated = False
9
+
10
+ def update(self):
11
+ self.updated = True
12
+
13
+ def test_theme_manager_initialization_and_toggle():
14
+ page = DummyPage()
15
+ theme = ThemeManager(
16
+ page=page,
17
+ primary_color=ft.colors.RED
18
+ )
19
+
20
+ theme.apply_theme()
21
+ assert page.theme.color_scheme_seed == ft.colors.RED
22
+ assert page.theme_mode == ft.ThemeMode.LIGHT
23
+ assert page.updated
24
+
25
+ page.updated = False
26
+ theme.toggle_dark_mode()
27
+ assert page.theme_mode == ft.ThemeMode.DARK
28
+ assert page.updated
29
+
30
+ page.updated = False
31
+ theme.set_primary_color(ft.colors.GREEN)
32
+ assert page.theme.color_scheme_seed == ft.colors.GREEN
33
+ assert page.updated