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.
- dars/__init__.py +0 -0
- dars/all.py +52 -0
- dars/cli/__init__.py +0 -0
- dars/cli/hot_reload.py +33 -0
- dars/cli/main.py +637 -0
- dars/cli/preview.py +419 -0
- dars/cli/translations.py +389 -0
- dars/components/__init__.py +0 -0
- dars/components/advanced/__init__.py +8 -0
- dars/components/advanced/accordion.py +21 -0
- dars/components/advanced/card.py +28 -0
- dars/components/advanced/modal.py +40 -0
- dars/components/advanced/navbar.py +31 -0
- dars/components/advanced/table.py +24 -0
- dars/components/advanced/tabs.py +26 -0
- dars/components/basic/__init__.py +34 -0
- dars/components/basic/button.py +29 -0
- dars/components/basic/checkbox.py +34 -0
- dars/components/basic/container.py +23 -0
- dars/components/basic/datepicker.py +139 -0
- dars/components/basic/image.py +36 -0
- dars/components/basic/input.py +50 -0
- dars/components/basic/link.py +31 -0
- dars/components/basic/page.py +20 -0
- dars/components/basic/progressbar.py +17 -0
- dars/components/basic/radiobutton.py +34 -0
- dars/components/basic/select.py +81 -0
- dars/components/basic/slider.py +63 -0
- dars/components/basic/spinner.py +11 -0
- dars/components/basic/text.py +22 -0
- dars/components/basic/textarea.py +46 -0
- dars/components/basic/tooltip.py +18 -0
- dars/components/layout/__init__.py +0 -0
- dars/components/layout/anchor.py +13 -0
- dars/components/layout/flex.py +26 -0
- dars/components/layout/grid.py +45 -0
- dars/core/__init__.py +0 -0
- dars/core/app.py +630 -0
- dars/core/component.py +25 -0
- dars/core/events.py +101 -0
- dars/core/properties.py +127 -0
- dars/docs/__init__.py +0 -0
- dars/exporters/__init__.py +0 -0
- dars/exporters/base.py +69 -0
- dars/exporters/web/__init__.py +0 -0
- dars/exporters/web/html_css_js.py +1406 -0
- dars/scripts/__init__.py +0 -0
- dars/scripts/script.py +38 -0
- dars/templates/__init__.py +0 -0
- dars/templates/examples/advanced/all_components_demo.py +87 -0
- dars/templates/examples/advanced/dashboard.py +440 -0
- dars/templates/examples/advanced/modern_web_app.py +452 -0
- dars/templates/examples/basic/flex_layout_responsive.py +13 -0
- dars/templates/examples/basic/form_components.py +516 -0
- dars/templates/examples/basic/grid_layout_responsive.py +13 -0
- dars/templates/examples/basic/hello_world.py +104 -0
- dars/templates/examples/basic/layout_multipage_demo.py +23 -0
- dars/templates/examples/basic/multipage_example.py +70 -0
- dars/templates/examples/basic/pwa_custom_icons.py +31 -0
- dars/templates/examples/basic/simple_form.py +377 -0
- dars/templates/examples/demo/complete_app.py +720 -0
- dars/templates/html/__init__.py +0 -0
- dars_framework-1.0.0.dist-info/METADATA +146 -0
- dars_framework-1.0.0.dist-info/RECORD +68 -0
- dars_framework-1.0.0.dist-info/WHEEL +5 -0
- dars_framework-1.0.0.dist-info/entry_points.txt +2 -0
- dars_framework-1.0.0.dist-info/licenses/LICENSE +21 -0
- dars_framework-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Ejemplo de uso del sistema multipágina de Dars
|
|
2
|
+
from dars.core.app import App
|
|
3
|
+
from dars.components.basic.page import Page
|
|
4
|
+
from dars.components.basic.text import Text
|
|
5
|
+
from dars.components.basic.button import Button
|
|
6
|
+
from dars.scripts.script import InlineScript
|
|
7
|
+
|
|
8
|
+
# Instancia de la app
|
|
9
|
+
app = App(title="Demo Multipágina Dars", description="Ejemplo de múltiples páginas con Dars")
|
|
10
|
+
|
|
11
|
+
# Página principal
|
|
12
|
+
home = Page(
|
|
13
|
+
Text("Bienvenido a la página principal de Dars!"),
|
|
14
|
+
Button("Ir a Sobre Nosotros", id="btn-about", class_name="dars-btn-link", style={"margin": "16px"})
|
|
15
|
+
)
|
|
16
|
+
# Script solo para la home
|
|
17
|
+
home.add_script(InlineScript("""
|
|
18
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
19
|
+
var btn = document.getElementById('btn-about');
|
|
20
|
+
if (btn) {
|
|
21
|
+
btn.addEventListener('click', function() {
|
|
22
|
+
window.location.href = 'about.html';
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
"""))
|
|
27
|
+
|
|
28
|
+
about = Page(
|
|
29
|
+
Text("Sobre Nosotros: Dars es un framework Python para la web."),
|
|
30
|
+
Button("Volver al inicio", id="btn-home", class_name="dars-btn-link", style={"margin": "16px"})
|
|
31
|
+
)
|
|
32
|
+
about.add_script(InlineScript("""
|
|
33
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
34
|
+
var btn = document.getElementById('btn-home');
|
|
35
|
+
if (btn) {
|
|
36
|
+
btn.addEventListener('click', function() {
|
|
37
|
+
window.location.href = 'index.html';
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
"""))
|
|
42
|
+
|
|
43
|
+
contact = Page(
|
|
44
|
+
Text("Contacto: Escríbenos a contacto@dars.dev"),
|
|
45
|
+
Button("Volver al inicio", id="btn-home2", class_name="dars-btn-link", style={"margin": "16px"})
|
|
46
|
+
)
|
|
47
|
+
contact.add_script(InlineScript("""
|
|
48
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
49
|
+
var btn = document.getElementById('btn-home2');
|
|
50
|
+
if (btn) {
|
|
51
|
+
btn.addEventListener('click', function() {
|
|
52
|
+
window.location.href = 'index.html';
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
"""))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# Registro multipágina
|
|
60
|
+
# ¡IMPORTANTE! Nunca pases una lista como root, siempre un solo componente (Container, etc)
|
|
61
|
+
# El exporter ahora también protege automáticamente y envuelve listas en un Container.
|
|
62
|
+
app.add_page("home", home, title="Inicio", index=True)
|
|
63
|
+
app.add_page("about", about, title="Sobre Nosotros")
|
|
64
|
+
app.add_page("contact", contact, title="Contacto")
|
|
65
|
+
|
|
66
|
+
# También sigue funcionando el modo clásico (single-page):
|
|
67
|
+
#app.set_root(home)
|
|
68
|
+
|
|
69
|
+
if __name__ == "__main__":
|
|
70
|
+
app.rTimeCompile()
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from dars.core.app import App
|
|
2
|
+
from dars.components.basic import Container, Text, Button
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
# Usar los iconos generados por defecto del framework
|
|
6
|
+
ICON_192 = os.path.join(os.path.dirname(__file__), 'dars', 'exporters', 'web', 'icons', 'pwa', 'icon-192x192.png')
|
|
7
|
+
ICON_512 = os.path.join(os.path.dirname(__file__), 'dars', 'exporters', 'web', 'icons', 'pwa', 'icon-512x512.png')
|
|
8
|
+
|
|
9
|
+
app = App(
|
|
10
|
+
title="Dars PWA Custom Icons Template",
|
|
11
|
+
description="Template PWA Dars con iconos personalizados",
|
|
12
|
+
pwa_enabled=True,
|
|
13
|
+
pwa_name="Dars PWA Custom",
|
|
14
|
+
pwa_short_name="DarsPWA",
|
|
15
|
+
theme_color="#1976d2",
|
|
16
|
+
background_color="#fafafa",
|
|
17
|
+
pwa_display="standalone",
|
|
18
|
+
pwa_orientation="portrait",
|
|
19
|
+
service_worker_enabled=True,
|
|
20
|
+
icons=[
|
|
21
|
+
{"src": ICON_192, "sizes": "192x192", "type": "image/png", "purpose": "any maskable"},
|
|
22
|
+
{"src": ICON_512, "sizes": "512x512", "type": "image/png"}
|
|
23
|
+
]
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
app.root = Container(
|
|
27
|
+
children=[
|
|
28
|
+
Text(text="¡Bienvenido a la PWA con iconos personalizados!"),
|
|
29
|
+
Button(text="Haz clic aquí", on_click=lambda: print("¡Botón de ejemplo!")),
|
|
30
|
+
]
|
|
31
|
+
)
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Dars - Ejemplo Básico: Formulario Simple
|
|
4
|
+
Demuestra el uso de inputs, validación básica y manejo de eventos
|
|
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="Formulario Simple - Dars")
|
|
19
|
+
|
|
20
|
+
# Contenedor principal
|
|
21
|
+
main_container = Container(
|
|
22
|
+
style={
|
|
23
|
+
'display': 'flex',
|
|
24
|
+
'justify-content': 'center',
|
|
25
|
+
'align-items': 'center',
|
|
26
|
+
'min-height': '100vh',
|
|
27
|
+
'background-color': '#ecf0f1',
|
|
28
|
+
'font-family': 'Arial, sans-serif'
|
|
29
|
+
}
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Tarjeta del formulario
|
|
33
|
+
form_card = Container(
|
|
34
|
+
style={
|
|
35
|
+
'background-color': 'white',
|
|
36
|
+
'padding': '40px',
|
|
37
|
+
'border-radius': '12px',
|
|
38
|
+
'box-shadow': '0 4px 20px rgba(0,0,0,0.1)',
|
|
39
|
+
'max-width': '400px',
|
|
40
|
+
'width': '100%'
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Título del formulario
|
|
45
|
+
titulo = Text(
|
|
46
|
+
text="Formulario de Contacto",
|
|
47
|
+
style={
|
|
48
|
+
'font-size': '28px',
|
|
49
|
+
'color': '#2c3e50',
|
|
50
|
+
'margin-bottom': '30px',
|
|
51
|
+
'text-align': 'center',
|
|
52
|
+
'font-weight': 'bold'
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Campo nombre
|
|
57
|
+
label_nombre = Text(
|
|
58
|
+
text="Nombre:",
|
|
59
|
+
style={
|
|
60
|
+
'font-size': '16px',
|
|
61
|
+
'color': '#34495e',
|
|
62
|
+
'margin-bottom': '8px',
|
|
63
|
+
'font-weight': '500'
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
input_nombre = Input(
|
|
68
|
+
id="campo-nombre",
|
|
69
|
+
placeholder="Ingresa tu nombre completo",
|
|
70
|
+
required=True,
|
|
71
|
+
style={
|
|
72
|
+
'width': '100%',
|
|
73
|
+
'padding': '12px',
|
|
74
|
+
'border': '2px solid #bdc3c7',
|
|
75
|
+
'border-radius': '6px',
|
|
76
|
+
'font-size': '16px',
|
|
77
|
+
'margin-bottom': '20px'
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Campo email
|
|
82
|
+
label_email = Text(
|
|
83
|
+
text="Email:",
|
|
84
|
+
style={
|
|
85
|
+
'font-size': '16px',
|
|
86
|
+
'color': '#34495e',
|
|
87
|
+
'margin-bottom': '8px',
|
|
88
|
+
'font-weight': '500'
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
input_email = Input(
|
|
93
|
+
id="campo-email",
|
|
94
|
+
placeholder="tu@email.com",
|
|
95
|
+
input_type="email",
|
|
96
|
+
required=True,
|
|
97
|
+
style={
|
|
98
|
+
'width': '100%',
|
|
99
|
+
'padding': '12px',
|
|
100
|
+
'border': '2px solid #bdc3c7',
|
|
101
|
+
'border-radius': '6px',
|
|
102
|
+
'font-size': '16px',
|
|
103
|
+
'margin-bottom': '20px'
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# Campo mensaje
|
|
108
|
+
label_mensaje = Text(
|
|
109
|
+
text="Mensaje:",
|
|
110
|
+
style={
|
|
111
|
+
'font-size': '16px',
|
|
112
|
+
'color': '#34495e',
|
|
113
|
+
'margin-bottom': '8px',
|
|
114
|
+
'font-weight': '500'
|
|
115
|
+
}
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
input_mensaje = Input(
|
|
119
|
+
id="campo-mensaje",
|
|
120
|
+
placeholder="Escribe tu mensaje aquí...",
|
|
121
|
+
style={
|
|
122
|
+
'width': '100%',
|
|
123
|
+
'padding': '12px',
|
|
124
|
+
'border': '2px solid #bdc3c7',
|
|
125
|
+
'border-radius': '6px',
|
|
126
|
+
'font-size': '16px',
|
|
127
|
+
'margin-bottom': '30px',
|
|
128
|
+
'min-height': '100px'
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
# Botones
|
|
133
|
+
button_container = Container(
|
|
134
|
+
style={
|
|
135
|
+
'display': 'flex',
|
|
136
|
+
'gap': '15px',
|
|
137
|
+
'justify-content': 'center'
|
|
138
|
+
}
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
boton_enviar = Button(
|
|
142
|
+
id="boton-enviar",
|
|
143
|
+
text="Enviar",
|
|
144
|
+
style={
|
|
145
|
+
'background-color': '#27ae60',
|
|
146
|
+
'color': 'white',
|
|
147
|
+
'padding': '12px 24px',
|
|
148
|
+
'border': 'none',
|
|
149
|
+
'border-radius': '6px',
|
|
150
|
+
'font-size': '16px',
|
|
151
|
+
'cursor': 'pointer',
|
|
152
|
+
'font-weight': '500'
|
|
153
|
+
}
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
boton_limpiar = Button(
|
|
157
|
+
id="boton-limpiar",
|
|
158
|
+
text="Limpiar",
|
|
159
|
+
style={
|
|
160
|
+
'background-color': '#95a5a6',
|
|
161
|
+
'color': 'white',
|
|
162
|
+
'padding': '12px 24px',
|
|
163
|
+
'border': 'none',
|
|
164
|
+
'border-radius': '6px',
|
|
165
|
+
'font-size': '16px',
|
|
166
|
+
'cursor': 'pointer',
|
|
167
|
+
'font-weight': '500'
|
|
168
|
+
}
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
# Script para funcionalidad
|
|
172
|
+
script = InlineScript("""
|
|
173
|
+
// Variables globales
|
|
174
|
+
let formularioValido = false;
|
|
175
|
+
|
|
176
|
+
// Funciones de validación
|
|
177
|
+
function validarNombre(nombre) {
|
|
178
|
+
return nombre.trim().length >= 2;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function validarEmail(email) {
|
|
182
|
+
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
183
|
+
return regex.test(email);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function validarMensaje(mensaje) {
|
|
187
|
+
return mensaje.trim().length >= 10;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Mostrar/ocultar mensajes de error
|
|
191
|
+
function mostrarError(campo, mensaje) {
|
|
192
|
+
limpiarError(campo);
|
|
193
|
+
|
|
194
|
+
const error = document.createElement('div');
|
|
195
|
+
error.className = 'error-mensaje';
|
|
196
|
+
error.textContent = mensaje;
|
|
197
|
+
error.style.color = '#e74c3c';
|
|
198
|
+
error.style.fontSize = '14px';
|
|
199
|
+
error.style.marginTop = '5px';
|
|
200
|
+
|
|
201
|
+
campo.parentNode.insertBefore(error, campo.nextSibling);
|
|
202
|
+
campo.style.borderColor = '#e74c3c';
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function limpiarError(campo) {
|
|
206
|
+
const error = campo.parentNode.querySelector('.error-mensaje');
|
|
207
|
+
if (error) {
|
|
208
|
+
error.remove();
|
|
209
|
+
}
|
|
210
|
+
campo.style.borderColor = '#bdc3c7';
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function mostrarExito(campo) {
|
|
214
|
+
limpiarError(campo);
|
|
215
|
+
campo.style.borderColor = '#27ae60';
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Validar formulario completo
|
|
219
|
+
function validarFormulario() {
|
|
220
|
+
const nombre = document.getElementById('campo-nombre').value;
|
|
221
|
+
const email = document.getElementById('campo-email').value;
|
|
222
|
+
const mensaje = document.getElementById('campo-mensaje').value;
|
|
223
|
+
|
|
224
|
+
let esValido = true;
|
|
225
|
+
|
|
226
|
+
// Validar nombre
|
|
227
|
+
if (!validarNombre(nombre)) {
|
|
228
|
+
mostrarError(document.getElementById('campo-nombre'), 'El nombre debe tener al menos 2 caracteres');
|
|
229
|
+
esValido = false;
|
|
230
|
+
} else {
|
|
231
|
+
mostrarExito(document.getElementById('campo-nombre'));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Validar email
|
|
235
|
+
if (!validarEmail(email)) {
|
|
236
|
+
mostrarError(document.getElementById('campo-email'), 'Ingresa un email válido');
|
|
237
|
+
esValido = false;
|
|
238
|
+
} else {
|
|
239
|
+
mostrarExito(document.getElementById('campo-email'));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Validar mensaje
|
|
243
|
+
if (!validarMensaje(mensaje)) {
|
|
244
|
+
mostrarError(document.getElementById('campo-mensaje'), 'El mensaje debe tener al menos 10 caracteres');
|
|
245
|
+
esValido = false;
|
|
246
|
+
} else {
|
|
247
|
+
mostrarExito(document.getElementById('campo-mensaje'));
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return esValido;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Enviar formulario
|
|
254
|
+
function enviarFormulario() {
|
|
255
|
+
if (validarFormulario()) {
|
|
256
|
+
const botonEnviar = document.getElementById('boton-enviar');
|
|
257
|
+
const textoOriginal = botonEnviar.textContent;
|
|
258
|
+
|
|
259
|
+
// Simular envío
|
|
260
|
+
botonEnviar.textContent = 'Enviando...';
|
|
261
|
+
botonEnviar.disabled = true;
|
|
262
|
+
botonEnviar.style.backgroundColor = '#95a5a6';
|
|
263
|
+
|
|
264
|
+
setTimeout(() => {
|
|
265
|
+
alert('¡Formulario enviado correctamente!\\n\\nGracias por contactarnos.');
|
|
266
|
+
limpiarFormulario();
|
|
267
|
+
|
|
268
|
+
botonEnviar.textContent = textoOriginal;
|
|
269
|
+
botonEnviar.disabled = false;
|
|
270
|
+
botonEnviar.style.backgroundColor = '#27ae60';
|
|
271
|
+
}, 2000);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Limpiar formulario
|
|
276
|
+
function limpiarFormulario() {
|
|
277
|
+
document.getElementById('campo-nombre').value = '';
|
|
278
|
+
document.getElementById('campo-email').value = '';
|
|
279
|
+
document.getElementById('campo-mensaje').value = '';
|
|
280
|
+
|
|
281
|
+
// Limpiar errores
|
|
282
|
+
const campos = ['campo-nombre', 'campo-email', 'campo-mensaje'];
|
|
283
|
+
campos.forEach(id => {
|
|
284
|
+
const campo = document.getElementById(id);
|
|
285
|
+
limpiarError(campo);
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Configurar eventos
|
|
290
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
291
|
+
// Eventos de botones
|
|
292
|
+
document.getElementById('boton-enviar').addEventListener('click', enviarFormulario);
|
|
293
|
+
document.getElementById('boton-limpiar').addEventListener('click', limpiarFormulario);
|
|
294
|
+
|
|
295
|
+
// Validación en tiempo real
|
|
296
|
+
document.getElementById('campo-nombre').addEventListener('blur', function() {
|
|
297
|
+
if (this.value.trim()) {
|
|
298
|
+
if (validarNombre(this.value)) {
|
|
299
|
+
mostrarExito(this);
|
|
300
|
+
} else {
|
|
301
|
+
mostrarError(this, 'El nombre debe tener al menos 2 caracteres');
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
document.getElementById('campo-email').addEventListener('blur', function() {
|
|
307
|
+
if (this.value.trim()) {
|
|
308
|
+
if (validarEmail(this.value)) {
|
|
309
|
+
mostrarExito(this);
|
|
310
|
+
} else {
|
|
311
|
+
mostrarError(this, 'Ingresa un email válido');
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
document.getElementById('campo-mensaje').addEventListener('blur', function() {
|
|
317
|
+
if (this.value.trim()) {
|
|
318
|
+
if (validarMensaje(this.value)) {
|
|
319
|
+
mostrarExito(this);
|
|
320
|
+
} else {
|
|
321
|
+
mostrarError(this, 'El mensaje debe tener al menos 10 caracteres');
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// Limpiar errores al escribir
|
|
327
|
+
const campos = ['campo-nombre', 'campo-email', 'campo-mensaje'];
|
|
328
|
+
campos.forEach(id => {
|
|
329
|
+
document.getElementById(id).addEventListener('input', function() {
|
|
330
|
+
if (this.style.borderColor === 'rgb(231, 76, 60)') { // Color de error
|
|
331
|
+
limpiarError(this);
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
// Efectos hover en botones
|
|
337
|
+
const botones = [document.getElementById('boton-enviar'), document.getElementById('boton-limpiar')];
|
|
338
|
+
|
|
339
|
+
document.getElementById('boton-enviar').addEventListener('mouseenter', function() {
|
|
340
|
+
if (!this.disabled) this.style.backgroundColor = '#229954';
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
document.getElementById('boton-enviar').addEventListener('mouseleave', function() {
|
|
344
|
+
if (!this.disabled) this.style.backgroundColor = '#27ae60';
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
document.getElementById('boton-limpiar').addEventListener('mouseenter', function() {
|
|
348
|
+
this.style.backgroundColor = '#7f8c8d';
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
document.getElementById('boton-limpiar').addEventListener('mouseleave', function() {
|
|
352
|
+
this.style.backgroundColor = '#95a5a6';
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
""")
|
|
356
|
+
|
|
357
|
+
# Ensamblar la aplicación
|
|
358
|
+
button_container.add_child(boton_enviar)
|
|
359
|
+
button_container.add_child(boton_limpiar)
|
|
360
|
+
|
|
361
|
+
form_card.add_child(titulo)
|
|
362
|
+
form_card.add_child(label_nombre)
|
|
363
|
+
form_card.add_child(input_nombre)
|
|
364
|
+
form_card.add_child(label_email)
|
|
365
|
+
form_card.add_child(input_email)
|
|
366
|
+
form_card.add_child(label_mensaje)
|
|
367
|
+
form_card.add_child(input_mensaje)
|
|
368
|
+
form_card.add_child(button_container)
|
|
369
|
+
|
|
370
|
+
main_container.add_child(form_card)
|
|
371
|
+
|
|
372
|
+
app.set_root(main_container)
|
|
373
|
+
app.add_script(script)
|
|
374
|
+
|
|
375
|
+
# Para exportar esta aplicación, ejecuta:
|
|
376
|
+
# ./dars_exporter export examples/basic/simple_form.py --format html --output ./simple_form_output
|
|
377
|
+
|