dars-framework 1.0.0__py3-none-any.whl

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.
Files changed (68) hide show
  1. dars/__init__.py +0 -0
  2. dars/all.py +52 -0
  3. dars/cli/__init__.py +0 -0
  4. dars/cli/hot_reload.py +33 -0
  5. dars/cli/main.py +637 -0
  6. dars/cli/preview.py +419 -0
  7. dars/cli/translations.py +389 -0
  8. dars/components/__init__.py +0 -0
  9. dars/components/advanced/__init__.py +8 -0
  10. dars/components/advanced/accordion.py +21 -0
  11. dars/components/advanced/card.py +28 -0
  12. dars/components/advanced/modal.py +40 -0
  13. dars/components/advanced/navbar.py +31 -0
  14. dars/components/advanced/table.py +24 -0
  15. dars/components/advanced/tabs.py +26 -0
  16. dars/components/basic/__init__.py +34 -0
  17. dars/components/basic/button.py +29 -0
  18. dars/components/basic/checkbox.py +34 -0
  19. dars/components/basic/container.py +23 -0
  20. dars/components/basic/datepicker.py +139 -0
  21. dars/components/basic/image.py +36 -0
  22. dars/components/basic/input.py +50 -0
  23. dars/components/basic/link.py +31 -0
  24. dars/components/basic/page.py +20 -0
  25. dars/components/basic/progressbar.py +17 -0
  26. dars/components/basic/radiobutton.py +34 -0
  27. dars/components/basic/select.py +81 -0
  28. dars/components/basic/slider.py +63 -0
  29. dars/components/basic/spinner.py +11 -0
  30. dars/components/basic/text.py +22 -0
  31. dars/components/basic/textarea.py +46 -0
  32. dars/components/basic/tooltip.py +18 -0
  33. dars/components/layout/__init__.py +0 -0
  34. dars/components/layout/anchor.py +13 -0
  35. dars/components/layout/flex.py +26 -0
  36. dars/components/layout/grid.py +45 -0
  37. dars/core/__init__.py +0 -0
  38. dars/core/app.py +630 -0
  39. dars/core/component.py +25 -0
  40. dars/core/events.py +101 -0
  41. dars/core/properties.py +127 -0
  42. dars/docs/__init__.py +0 -0
  43. dars/exporters/__init__.py +0 -0
  44. dars/exporters/base.py +69 -0
  45. dars/exporters/web/__init__.py +0 -0
  46. dars/exporters/web/html_css_js.py +1406 -0
  47. dars/scripts/__init__.py +0 -0
  48. dars/scripts/script.py +38 -0
  49. dars/templates/__init__.py +0 -0
  50. dars/templates/examples/advanced/all_components_demo.py +87 -0
  51. dars/templates/examples/advanced/dashboard.py +440 -0
  52. dars/templates/examples/advanced/modern_web_app.py +452 -0
  53. dars/templates/examples/basic/flex_layout_responsive.py +13 -0
  54. dars/templates/examples/basic/form_components.py +516 -0
  55. dars/templates/examples/basic/grid_layout_responsive.py +13 -0
  56. dars/templates/examples/basic/hello_world.py +104 -0
  57. dars/templates/examples/basic/layout_multipage_demo.py +23 -0
  58. dars/templates/examples/basic/multipage_example.py +70 -0
  59. dars/templates/examples/basic/pwa_custom_icons.py +31 -0
  60. dars/templates/examples/basic/simple_form.py +377 -0
  61. dars/templates/examples/demo/complete_app.py +720 -0
  62. dars/templates/html/__init__.py +0 -0
  63. dars_framework-1.0.0.dist-info/METADATA +146 -0
  64. dars_framework-1.0.0.dist-info/RECORD +68 -0
  65. dars_framework-1.0.0.dist-info/WHEEL +5 -0
  66. dars_framework-1.0.0.dist-info/entry_points.txt +2 -0
  67. dars_framework-1.0.0.dist-info/licenses/LICENSE +21 -0
  68. dars_framework-1.0.0.dist-info/top_level.txt +1 -0
File without changes
dars/scripts/script.py ADDED
@@ -0,0 +1,38 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Optional
3
+
4
+ class Script(ABC):
5
+ """Clase base para la definición de scripts"""
6
+ def __init__(self, target_language: str = "javascript"):
7
+ if target_language not in ["javascript", "typescript"]:
8
+ raise ValueError("El lenguaje objetivo debe ser 'javascript' o 'typescript'")
9
+ self.target_language = target_language
10
+
11
+ @abstractmethod
12
+ def get_code(self) -> str:
13
+ """Retorna el código del script en el lenguaje objetivo"""
14
+ pass
15
+
16
+ class InlineScript(Script):
17
+ """Script definido directamente en el código Python"""
18
+ def __init__(self, code: str, target_language: str = "javascript"):
19
+ super().__init__(target_language)
20
+ self.code = code
21
+
22
+ def get_code(self) -> str:
23
+ return self.code
24
+
25
+ class FileScript(Script):
26
+ """Script cargado desde un archivo externo"""
27
+ def __init__(self, file_path: str, target_language: str = "javascript"):
28
+ super().__init__(target_language)
29
+ self.file_path = file_path
30
+
31
+ def get_code(self) -> str:
32
+ try:
33
+ with open(self.file_path, 'r') as f:
34
+ return f.read()
35
+ except FileNotFoundError:
36
+ raise FileNotFoundError(f"El archivo de script no se encontró: {self.file_path}")
37
+
38
+
File without changes
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Plantilla: Todos los Componentes Dars - Básicos y Avanzados
4
+ Demuestra el uso completo e integrado de todos los componentes básicos y avanzados:
5
+ Text, Button, Input, Container, Image, Link, Textarea, Checkbox, RadioButton, Select, Slider, DatePicker,
6
+ Table, Tabs, Accordion, ProgressBar, Spinner, Tooltip
7
+
8
+ Uso:
9
+ dars init mi_proyecto -t advanced/all_components_demo
10
+ """
11
+
12
+ from dars.core.app import App
13
+ from dars.components.basic.container import Container
14
+ from dars.components.basic.text import Text
15
+ from dars.components.basic.button import Button
16
+ from dars.components.basic.input import Input
17
+ from dars.components.basic.image import Image
18
+ from dars.components.basic.link import Link
19
+ from dars.components.basic.textarea import Textarea
20
+ from dars.components.basic.checkbox import Checkbox
21
+ from dars.components.basic.radiobutton import RadioButton
22
+ from dars.components.basic.select import Select, SelectOption
23
+ from dars.components.basic.slider import Slider
24
+ from dars.components.basic.datepicker import DatePicker
25
+ from dars.components.advanced.table import Table
26
+ from dars.components.advanced.tabs import Tabs
27
+ from dars.components.advanced.accordion import Accordion
28
+ from dars.components.basic.progressbar import ProgressBar
29
+ from dars.components.basic.spinner import Spinner
30
+ from dars.components.basic.tooltip import Tooltip
31
+
32
+ # App principal
33
+ app = App(title="Dars - Todos los Componentes Básicos y Avanzados")
34
+
35
+ main = Container(style={
36
+ 'max-width': '900px',
37
+ 'margin': '40px auto',
38
+ 'padding': '32px',
39
+ 'background': 'white',
40
+ 'border-radius': '12px',
41
+ 'box-shadow': '0 2px 12px rgba(0,0,0,0.08)'
42
+ })
43
+
44
+ main.children += [
45
+ Text("Demostración de TODOS los componentes de Dars", style={"font-size": "2rem", "font-weight": "bold", "margin-bottom": "24px"}),
46
+ # Básicos
47
+ Text("Componentes Básicos", style={"font-size": "1.3rem", "margin": "24px 0 12px 0", "color": "#007bff"}),
48
+ Text("Texto de ejemplo", style={"margin-bottom": "8px"}),
49
+ Button("Botón primario"),
50
+ Input(placeholder="Campo de texto"),
51
+ Image(src="https://via.placeholder.com/120x60.png?text=Logo", alt="Logo Demo", style={"margin": "10px 0"}),
52
+ Link("Ir a Dars Framework", href="https://github.com/zondahuman/Dars-Framework", target="_blank"),
53
+ Textarea(value="Texto multilinea de ejemplo", rows=3),
54
+ Checkbox(label="Acepto términos y condiciones", checked=True),
55
+ RadioButton(label="Opción A", name="grupo1", checked=True),
56
+ RadioButton(label="Opción B", name="grupo1"),
57
+ Select(options=[SelectOption("uno", "Uno"), SelectOption("dos", "Dos")], value="uno", placeholder="Selecciona una opción"),
58
+ Slider(min_value=0, max_value=100, value=50, label="Volumen", show_value=True),
59
+ DatePicker(value="2025-08-06"),
60
+ # Avanzados
61
+ Text("Componentes Avanzados", style={"font-size": "1.3rem", "margin": "32px 0 12px 0", "color": "#4a90e2"}),
62
+ Table(
63
+ columns=[{"title": "Nombre", "field": "nombre"}, {"title": "Edad", "field": "edad"}],
64
+ data=[{"nombre": "Ana", "edad": 28}, {"nombre": "Luis", "edad": 34}],
65
+ page_size=10
66
+ ),
67
+ Tabs(
68
+ tabs=["Tab 1", "Tab 2"],
69
+ panels=[Text("Contenido de la pestaña 1"), Text("Contenido de la pestaña 2")],
70
+ selected=0
71
+ ),
72
+ Accordion(
73
+ sections=[
74
+ ("Sección 1", Text("Contenido de la sección 1")),
75
+ ("Sección 2", Text("Contenido de la sección 2"))
76
+ ],
77
+ open_indices=[0]
78
+ ),
79
+ ProgressBar(value=70, max_value=100),
80
+ Spinner(),
81
+ Tooltip(child=Button("Pasa el mouse"), text="¡Tooltip de ejemplo!", position="top")
82
+ ]
83
+
84
+ app.root = main
85
+
86
+ if __name__ == "__main__":
87
+ app.rTimeCompile()
@@ -0,0 +1,440 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Dars - Ejemplo Avanzado: Dashboard
4
+ Demuestra layouts complejos, múltiples componentes y funcionalidad avanzada
5
+ """
6
+
7
+ import sys
8
+ import os
9
+
10
+ from dars.core.app import App
11
+ from dars.components.basic.text import Text
12
+ from dars.components.basic.button import Button
13
+ from dars.components.basic.input import Input
14
+ from dars.components.basic.container import Container
15
+ from dars.scripts.script import InlineScript
16
+
17
+ # Crear la aplicación
18
+ app = App(title="Dashboard Empresarial - Dars")
19
+
20
+ # Contenedor principal
21
+ main_container = Container(
22
+ style={
23
+ 'display': 'flex',
24
+ 'min-height': '100vh',
25
+ 'background-color': '#f8f9fa',
26
+ 'font-family': 'Arial, sans-serif'
27
+ }
28
+ )
29
+
30
+ # Sidebar
31
+ sidebar = Container(
32
+ id="sidebar",
33
+ style={
34
+ 'width': '250px',
35
+ 'background-color': '#2c3e50',
36
+ 'color': 'white',
37
+ 'padding': '20px',
38
+ 'box-shadow': '2px 0 5px rgba(0,0,0,0.1)'
39
+ }
40
+ )
41
+
42
+ # Logo/Título del sidebar
43
+ logo = Text(
44
+ text="📊 Dashboard",
45
+ style={
46
+ 'font-size': '24px',
47
+ 'font-weight': 'bold',
48
+ 'margin-bottom': '30px',
49
+ 'text-align': 'center',
50
+ 'color': '#ecf0f1'
51
+ }
52
+ )
53
+
54
+ # Menú de navegación
55
+ menu_items = [
56
+ ("🏠 Inicio", "inicio"),
57
+ ("📈 Ventas", "ventas"),
58
+ ("👥 Usuarios", "usuarios"),
59
+ ("⚙️ Configuración", "config")
60
+ ]
61
+
62
+ menu_container = Container(style={'margin-bottom': '30px'})
63
+
64
+ for texto, id_item in menu_items:
65
+ menu_item = Button(
66
+ id=f"menu-{id_item}",
67
+ text=texto,
68
+ style={
69
+ 'width': '100%',
70
+ 'background-color': 'transparent',
71
+ 'color': '#ecf0f1',
72
+ 'border': 'none',
73
+ 'padding': '12px 16px',
74
+ 'text-align': 'left',
75
+ 'cursor': 'pointer',
76
+ 'border-radius': '6px',
77
+ 'margin-bottom': '8px',
78
+ 'font-size': '16px'
79
+ }
80
+ )
81
+ menu_container.add_child(menu_item)
82
+
83
+ # Área de contenido principal
84
+ content_area = Container(
85
+ id="content-area",
86
+ style={
87
+ 'flex': '1',
88
+ 'padding': '30px',
89
+ 'overflow-y': 'auto'
90
+ }
91
+ )
92
+
93
+ # Header del contenido
94
+ header = Container(
95
+ style={
96
+ 'display': 'flex',
97
+ 'justify-content': 'space-between',
98
+ 'align-items': 'center',
99
+ 'margin-bottom': '30px',
100
+ 'padding-bottom': '20px',
101
+ 'border-bottom': '2px solid #dee2e6'
102
+ }
103
+ )
104
+
105
+ titulo_pagina = Text(
106
+ id="titulo-pagina",
107
+ text="Panel de Control",
108
+ style={
109
+ 'font-size': '32px',
110
+ 'color': '#2c3e50',
111
+ 'font-weight': 'bold'
112
+ }
113
+ )
114
+
115
+ usuario_info = Text(
116
+ text="👤 Admin Usuario",
117
+ style={
118
+ 'font-size': '16px',
119
+ 'color': '#6c757d'
120
+ }
121
+ )
122
+
123
+ # Tarjetas de estadísticas
124
+ stats_container = Container(
125
+ id="stats-container",
126
+ style={
127
+ 'display': 'grid',
128
+ 'grid-template-columns': 'repeat(auto-fit, minmax(250px, 1fr))',
129
+ 'gap': '20px',
130
+ 'margin-bottom': '30px'
131
+ }
132
+ )
133
+
134
+ # Función para crear tarjetas de estadísticas
135
+ def crear_stat_card(titulo, valor, icono, color):
136
+ card = Container(
137
+ style={
138
+ 'background-color': 'white',
139
+ 'padding': '24px',
140
+ 'border-radius': '12px',
141
+ 'box-shadow': '0 2px 10px rgba(0,0,0,0.1)',
142
+ 'border-left': f'4px solid {color}'
143
+ }
144
+ )
145
+
146
+ card_header = Container(
147
+ style={
148
+ 'display': 'flex',
149
+ 'justify-content': 'space-between',
150
+ 'align-items': 'center',
151
+ 'margin-bottom': '10px'
152
+ }
153
+ )
154
+
155
+ card_title = Text(
156
+ text=titulo,
157
+ style={
158
+ 'font-size': '14px',
159
+ 'color': '#6c757d',
160
+ 'font-weight': '500'
161
+ }
162
+ )
163
+
164
+ card_icon = Text(
165
+ text=icono,
166
+ style={
167
+ 'font-size': '24px'
168
+ }
169
+ )
170
+
171
+ card_value = Text(
172
+ text=valor,
173
+ style={
174
+ 'font-size': '28px',
175
+ 'color': '#2c3e50',
176
+ 'font-weight': 'bold'
177
+ }
178
+ )
179
+
180
+ card_header.add_child(card_title)
181
+ card_header.add_child(card_icon)
182
+ card.add_child(card_header)
183
+ card.add_child(card_value)
184
+
185
+ return card
186
+
187
+ # Crear tarjetas de estadísticas
188
+ stats_data = [
189
+ ("Ventas Totales", "$125,430", "💰", "#28a745"),
190
+ ("Usuarios Activos", "1,234", "👥", "#007bff"),
191
+ ("Pedidos Hoy", "89", "📦", "#ffc107"),
192
+ ("Ingresos Mes", "$45,210", "📈", "#dc3545")
193
+ ]
194
+
195
+ for titulo, valor, icono, color in stats_data:
196
+ stats_container.add_child(crear_stat_card(titulo, valor, icono, color))
197
+
198
+ # Área de contenido dinámico
199
+ dynamic_content = Container(
200
+ id="dynamic-content",
201
+ style={
202
+ 'background-color': 'white',
203
+ 'padding': '30px',
204
+ 'border-radius': '12px',
205
+ 'box-shadow': '0 2px 10px rgba(0,0,0,0.1)'
206
+ }
207
+ )
208
+
209
+ # Contenido inicial
210
+ contenido_inicial = Text(
211
+ id="contenido-texto",
212
+ text="Bienvenido al Dashboard. Selecciona una opción del menú para ver más información.",
213
+ style={
214
+ 'font-size': '18px',
215
+ 'color': '#6c757d',
216
+ 'text-align': 'center',
217
+ 'line-height': '1.6'
218
+ }
219
+ )
220
+
221
+ # Script para funcionalidad del dashboard
222
+ script = InlineScript("""
223
+ // Estado de la aplicación
224
+ let currentPage = 'inicio';
225
+
226
+ // Contenido de las páginas
227
+ const pageContent = {
228
+ inicio: {
229
+ titulo: 'Panel de Control',
230
+ contenido: 'Bienvenido al Dashboard. Aquí puedes ver un resumen de todas las métricas importantes de tu negocio.'
231
+ },
232
+ ventas: {
233
+ titulo: 'Gestión de Ventas',
234
+ contenido: 'Aquí puedes ver todas las ventas realizadas, generar reportes y analizar tendencias de ventas.'
235
+ },
236
+ usuarios: {
237
+ titulo: 'Gestión de Usuarios',
238
+ contenido: 'Administra los usuarios del sistema, sus permisos y actividad reciente.'
239
+ },
240
+ config: {
241
+ titulo: 'Configuración',
242
+ contenido: 'Configura los parámetros del sistema, notificaciones y preferencias generales.'
243
+ }
244
+ };
245
+
246
+ // Función para cambiar de página
247
+ function cambiarPagina(pagina) {
248
+ if (currentPage === pagina) return;
249
+
250
+ currentPage = pagina;
251
+
252
+ // Actualizar título
253
+ const titulo = document.getElementById('titulo-pagina');
254
+ if (titulo) {
255
+ titulo.textContent = pageContent[pagina].titulo;
256
+ }
257
+
258
+ // Actualizar contenido
259
+ const contenido = document.getElementById('contenido-texto');
260
+ if (contenido) {
261
+ contenido.textContent = pageContent[pagina].contenido;
262
+ }
263
+
264
+ // Actualizar estilos del menú
265
+ actualizarMenuActivo(pagina);
266
+
267
+ // Animación de entrada
268
+ const dynamicContent = document.getElementById('dynamic-content');
269
+ if (dynamicContent) {
270
+ dynamicContent.style.opacity = '0';
271
+ setTimeout(() => {
272
+ dynamicContent.style.opacity = '1';
273
+ }, 150);
274
+ }
275
+ }
276
+
277
+ // Actualizar elemento activo del menú
278
+ function actualizarMenuActivo(paginaActiva) {
279
+ const menuItems = ['inicio', 'ventas', 'usuarios', 'config'];
280
+
281
+ menuItems.forEach(item => {
282
+ const elemento = document.getElementById(`menu-${item}`);
283
+ if (elemento) {
284
+ if (item === paginaActiva) {
285
+ elemento.style.backgroundColor = '#34495e';
286
+ elemento.style.color = '#3498db';
287
+ } else {
288
+ elemento.style.backgroundColor = 'transparent';
289
+ elemento.style.color = '#ecf0f1';
290
+ }
291
+ }
292
+ });
293
+ }
294
+
295
+ // Animación de las tarjetas de estadísticas
296
+ function animarEstadisticas() {
297
+ const statsContainer = document.getElementById('stats-container');
298
+ if (!statsContainer) return;
299
+
300
+ const cards = statsContainer.children;
301
+
302
+ Array.from(cards).forEach((card, index) => {
303
+ card.style.opacity = '0';
304
+ card.style.transform = 'translateY(20px)';
305
+
306
+ setTimeout(() => {
307
+ card.style.transition = 'all 0.5s ease';
308
+ card.style.opacity = '1';
309
+ card.style.transform = 'translateY(0)';
310
+ }, index * 100);
311
+ });
312
+ }
313
+
314
+ // Efecto de hover en las tarjetas
315
+ function configurarEfectosHover() {
316
+ const statsContainer = document.getElementById('stats-container');
317
+ if (!statsContainer) return;
318
+
319
+ const cards = statsContainer.children;
320
+
321
+ Array.from(cards).forEach(card => {
322
+ card.addEventListener('mouseenter', function() {
323
+ this.style.transform = 'translateY(-5px)';
324
+ this.style.boxShadow = '0 4px 20px rgba(0,0,0,0.15)';
325
+ this.style.transition = 'all 0.3s ease';
326
+ });
327
+
328
+ card.addEventListener('mouseleave', function() {
329
+ this.style.transform = 'translateY(0)';
330
+ this.style.boxShadow = '0 2px 10px rgba(0,0,0,0.1)';
331
+ });
332
+ });
333
+ }
334
+
335
+ // Simulación de datos en tiempo real
336
+ function actualizarDatosEnTiempoReal() {
337
+ const valores = [
338
+ { selector: 'Ventas Totales', base: 125430, variacion: 1000 },
339
+ { selector: 'Usuarios Activos', base: 1234, variacion: 10 },
340
+ { selector: 'Pedidos Hoy', base: 89, variacion: 5 },
341
+ { selector: 'Ingresos Mes', base: 45210, variacion: 500 }
342
+ ];
343
+
344
+ valores.forEach(item => {
345
+ const elementos = Array.from(document.querySelectorAll('span')).filter(el =>
346
+ el.parentElement && el.parentElement.textContent.includes(item.selector)
347
+ );
348
+
349
+ if (elementos.length > 0) {
350
+ const elemento = elementos[elementos.length - 1]; // Último elemento (el valor)
351
+ const variacion = Math.floor(Math.random() * item.variacion * 2) - item.variacion;
352
+ const nuevoValor = item.base + variacion;
353
+
354
+ if (item.selector.includes('$')) {
355
+ elemento.textContent = `$${nuevoValor.toLocaleString()}`;
356
+ } else {
357
+ elemento.textContent = nuevoValor.toLocaleString();
358
+ }
359
+ }
360
+ });
361
+ }
362
+
363
+ // Configurar sidebar responsive
364
+ function configurarSidebarResponsive() {
365
+ const sidebar = document.getElementById('sidebar');
366
+ const contentArea = document.getElementById('content-area');
367
+
368
+ function checkScreenSize() {
369
+ if (window.innerWidth < 768) {
370
+ sidebar.style.position = 'fixed';
371
+ sidebar.style.left = '-250px';
372
+ sidebar.style.zIndex = '1000';
373
+ sidebar.style.transition = 'left 0.3s ease';
374
+ contentArea.style.marginLeft = '0';
375
+ } else {
376
+ sidebar.style.position = 'static';
377
+ sidebar.style.left = '0';
378
+ contentArea.style.marginLeft = '0';
379
+ }
380
+ }
381
+
382
+ window.addEventListener('resize', checkScreenSize);
383
+ checkScreenSize();
384
+ }
385
+
386
+ // Inicialización
387
+ document.addEventListener('DOMContentLoaded', function() {
388
+ // Configurar eventos del menú
389
+ const menuItems = ['inicio', 'ventas', 'usuarios', 'config'];
390
+ menuItems.forEach(item => {
391
+ const elemento = document.getElementById(`menu-${item}`);
392
+ if (elemento) {
393
+ elemento.addEventListener('click', () => cambiarPagina(item));
394
+ }
395
+ });
396
+
397
+ // Configurar página inicial
398
+ cambiarPagina('inicio');
399
+
400
+ // Configurar animaciones y efectos
401
+ setTimeout(() => {
402
+ animarEstadisticas();
403
+ configurarEfectosHover();
404
+ }, 100);
405
+
406
+ // Configurar responsive
407
+ configurarSidebarResponsive();
408
+
409
+ // Actualizar datos cada 30 segundos
410
+ setInterval(actualizarDatosEnTiempoReal, 30000);
411
+
412
+ console.log('Dashboard Dars cargado correctamente');
413
+ });
414
+ """)
415
+
416
+ # Ensamblar la aplicación
417
+ sidebar.add_child(logo)
418
+ sidebar.add_child(menu_container)
419
+
420
+ header.add_child(titulo_pagina)
421
+ header.add_child(usuario_info)
422
+
423
+ dynamic_content.add_child(contenido_inicial)
424
+
425
+ content_area.add_child(header)
426
+ content_area.add_child(stats_container)
427
+ content_area.add_child(dynamic_content)
428
+
429
+ main_container.add_child(sidebar)
430
+ main_container.add_child(content_area)
431
+
432
+ app.set_root(main_container)
433
+ app.add_script(script)
434
+
435
+ # Para exportar esta aplicación, ejecuta:
436
+ # ./dars_exporter export examples/advanced/dashboard.py --format html --output ./dashboard_output
437
+
438
+ if __name__ == "__main__":
439
+ app.rTimeCompile() # Preview/compilación rápida
440
+