dars-framework 1.0.4__tar.gz → 1.0.6__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.
- {dars_framework-1.0.4/dars_framework.egg-info → dars_framework-1.0.6}/PKG-INFO +30 -33
- {dars_framework-1.0.4 → dars_framework-1.0.6}/README.md +26 -31
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/all.py +4 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/cli/main.py +22 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/cli/preview.py +13 -5
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/accordion.py +5 -1
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/card.py +6 -1
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/modal.py +6 -1
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/navbar.py +15 -2
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/tabs.py +5 -1
- dars_framework-1.0.6/dars/components/basic/button.py +55 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/input.py +8 -2
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/core/app.py +219 -199
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/core/component.py +32 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/exporters/web/html_css_js.py +179 -28
- dars_framework-1.0.6/dars/scripts/dscript.py +26 -0
- dars_framework-1.0.6/dars/templates/examples/advanced/advanced_modal_demo.py +275 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/advanced/all_components_demo.py +1 -1
- dars_framework-1.0.6/dars/version.py +2 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6/dars_framework.egg-info}/PKG-INFO +30 -33
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars_framework.egg-info/SOURCES.txt +5 -2
- dars_framework-1.0.6/dars_framework.egg-info/requires.txt +4 -0
- dars_framework-1.0.6/pyproject.toml +24 -0
- dars_framework-1.0.4/dars/components/basic/button.py +0 -29
- dars_framework-1.0.4/dars_framework.egg-info/requires.txt +0 -2
- dars_framework-1.0.4/pyproject.toml +0 -20
- {dars_framework-1.0.4 → dars_framework-1.0.6}/LICENSE +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/cli/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/cli/hot_reload.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/cli/translations.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/table.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/checkbox.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/container.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/datepicker.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/image.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/link.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/page.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/progressbar.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/radiobutton.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/select.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/slider.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/spinner.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/text.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/textarea.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/tooltip.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/layout/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/layout/anchor.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/layout/flex.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/layout/grid.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/core/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/core/events.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/core/properties.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/docs/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/exporters/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/exporters/base.py +0 -0
- {dars_framework-1.0.4/dars/exporters/web → dars_framework-1.0.6/dars/exporters/web/OLD}/html_css_js_old.py +0 -0
- {dars_framework-1.0.4/dars/exporters/web → dars_framework-1.0.6/dars/exporters/web/OLD}/html_css_js_old2.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/exporters/web/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/scripts/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/scripts/script.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/advanced/dashboard.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/advanced/modern_web_app.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/flex_layout_responsive.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/form_components.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/grid_layout_responsive.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/hello_world.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/layout_multipage_demo.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/multipage_example.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/pwa_custom_icons.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/simple_form.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/demo/complete_app.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/html/__init__.py +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars_framework.egg-info/dependency_links.txt +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars_framework.egg-info/entry_points.txt +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/dars_framework.egg-info/top_level.txt +0 -0
- {dars_framework-1.0.4 → dars_framework-1.0.6}/setup.cfg +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dars-framework
|
|
3
|
-
Version: 1.0.
|
|
4
|
-
Summary: Dars
|
|
3
|
+
Version: 1.0.6
|
|
4
|
+
Summary: Dars is a Python UI framework for building modern, interactive web apps with only Python code. Write your interface in Python, export it to static HTML/CSS/JS, and deploy anywhere.
|
|
5
5
|
Author-email: ztamdev <zondax2009@gmail.com>
|
|
6
6
|
License: MIT License
|
|
7
7
|
|
|
@@ -29,11 +29,15 @@ Description-Content-Type: text/markdown
|
|
|
29
29
|
License-File: LICENSE
|
|
30
30
|
Requires-Dist: rich
|
|
31
31
|
Requires-Dist: bs4
|
|
32
|
+
Requires-Dist: fastapi
|
|
33
|
+
Requires-Dist: uvicorn[standard]
|
|
32
34
|
Dynamic: license-file
|
|
33
35
|
|
|
34
|
-
# Dars
|
|
36
|
+
# Dars-Framework
|
|
35
37
|
|
|
36
|
-
Dars is a Python UI framework for building modern, interactive web apps with only Python code. Write your interface in Python, export it to static HTML/CSS/JS, and deploy anywhere
|
|
38
|
+
Dars is a Python UI framework for building modern, interactive web apps with only Python code. Write your interface in Python, export it to static HTML/CSS/JS, and deploy anywhere.
|
|
39
|
+
|
|
40
|
+
> Some Javascript or frontend stack required.
|
|
37
41
|
|
|
38
42
|
```bash
|
|
39
43
|
pip install dars-framework
|
|
@@ -48,32 +52,26 @@ pip install dars-framework
|
|
|
48
52
|
## Quick Example: Your First App
|
|
49
53
|
|
|
50
54
|
```python
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
style={'font-size': '32px', 'color': '#333'}
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
boton = Button(
|
|
75
|
-
text="Hacer clic",
|
|
76
|
-
style={'background-color': '#007bff', 'color': 'white'}
|
|
55
|
+
from dars import App, Container, Text, Button, InlineScript
|
|
56
|
+
|
|
57
|
+
app = App()
|
|
58
|
+
|
|
59
|
+
# Crear aplicación con sintaxis nueva (v1.0.3)
|
|
60
|
+
container = Container(
|
|
61
|
+
Text(
|
|
62
|
+
"Hola Dars",
|
|
63
|
+
style={'font-size': '32px', 'color': '#333'}
|
|
64
|
+
),
|
|
65
|
+
Button(
|
|
66
|
+
"Hacer clic",
|
|
67
|
+
style={'background-color': '#007bff', 'color': 'white'}
|
|
68
|
+
),
|
|
69
|
+
style={
|
|
70
|
+
'display': 'flex',
|
|
71
|
+
'flex-direction': 'column',
|
|
72
|
+
'align-items': 'center',
|
|
73
|
+
'padding': '40px'
|
|
74
|
+
}
|
|
77
75
|
)
|
|
78
76
|
|
|
79
77
|
# Script para interactividad
|
|
@@ -87,13 +85,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
87
85
|
""")
|
|
88
86
|
|
|
89
87
|
# Ensamblar aplicación
|
|
90
|
-
container.add_child(titulo)
|
|
91
|
-
container.add_child(boton)
|
|
92
88
|
app.set_root(container)
|
|
93
89
|
app.add_script(script)
|
|
94
90
|
|
|
95
91
|
if __name__ == "__main__":
|
|
96
|
-
app.rTimeCompile()
|
|
92
|
+
app.rTimeCompile() # Live preview at http://localhost:8000
|
|
93
|
+
|
|
97
94
|
```
|
|
98
95
|
|
|
99
96
|
## CLI Usage
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
# Dars
|
|
1
|
+
# Dars-Framework
|
|
2
2
|
|
|
3
|
-
Dars is a Python UI framework for building modern, interactive web apps with only Python code. Write your interface in Python, export it to static HTML/CSS/JS, and deploy anywhere
|
|
3
|
+
Dars is a Python UI framework for building modern, interactive web apps with only Python code. Write your interface in Python, export it to static HTML/CSS/JS, and deploy anywhere.
|
|
4
|
+
|
|
5
|
+
> Some Javascript or frontend stack required.
|
|
4
6
|
|
|
5
7
|
```bash
|
|
6
8
|
pip install dars-framework
|
|
@@ -15,32 +17,26 @@ pip install dars-framework
|
|
|
15
17
|
## Quick Example: Your First App
|
|
16
18
|
|
|
17
19
|
```python
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
style={'font-size': '32px', 'color': '#333'}
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
boton = Button(
|
|
42
|
-
text="Hacer clic",
|
|
43
|
-
style={'background-color': '#007bff', 'color': 'white'}
|
|
20
|
+
from dars import App, Container, Text, Button, InlineScript
|
|
21
|
+
|
|
22
|
+
app = App()
|
|
23
|
+
|
|
24
|
+
# Crear aplicación con sintaxis nueva (v1.0.3)
|
|
25
|
+
container = Container(
|
|
26
|
+
Text(
|
|
27
|
+
"Hola Dars",
|
|
28
|
+
style={'font-size': '32px', 'color': '#333'}
|
|
29
|
+
),
|
|
30
|
+
Button(
|
|
31
|
+
"Hacer clic",
|
|
32
|
+
style={'background-color': '#007bff', 'color': 'white'}
|
|
33
|
+
),
|
|
34
|
+
style={
|
|
35
|
+
'display': 'flex',
|
|
36
|
+
'flex-direction': 'column',
|
|
37
|
+
'align-items': 'center',
|
|
38
|
+
'padding': '40px'
|
|
39
|
+
}
|
|
44
40
|
)
|
|
45
41
|
|
|
46
42
|
# Script para interactividad
|
|
@@ -54,13 +50,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
54
50
|
""")
|
|
55
51
|
|
|
56
52
|
# Ensamblar aplicación
|
|
57
|
-
container.add_child(titulo)
|
|
58
|
-
container.add_child(boton)
|
|
59
53
|
app.set_root(container)
|
|
60
54
|
app.add_script(script)
|
|
61
55
|
|
|
62
56
|
if __name__ == "__main__":
|
|
63
|
-
app.rTimeCompile()
|
|
57
|
+
app.rTimeCompile() # Live preview at http://localhost:8000
|
|
58
|
+
|
|
64
59
|
```
|
|
65
60
|
|
|
66
61
|
## CLI Usage
|
|
@@ -38,6 +38,9 @@ from dars.components.layout.grid import GridLayout, LayoutBase
|
|
|
38
38
|
from dars.components.layout.flex import FlexLayout
|
|
39
39
|
from dars.components.layout.anchor import AnchorPoint
|
|
40
40
|
|
|
41
|
+
from dars.scripts.script import *
|
|
42
|
+
from dars.scripts.dscript import dScript
|
|
43
|
+
|
|
41
44
|
# Exporters (optional, for direct use)
|
|
42
45
|
# from dars.exporters.web.html_css_js import HTMLCSSJSExporter
|
|
43
46
|
|
|
@@ -50,4 +53,5 @@ __all__ = [
|
|
|
50
53
|
'RadioButton', 'Select', 'Slider', 'Spinner', 'Text', 'Textarea', 'Tooltip',
|
|
51
54
|
'Accordion', 'Card', 'Modal', 'Navbar', 'Table', 'Tabs',
|
|
52
55
|
'GridLayout', 'FlexLayout', 'LayoutBase', 'AnchorPoint',
|
|
56
|
+
'InlineScript', 'FileScript', 'dScript',
|
|
53
57
|
]
|
|
@@ -336,6 +336,7 @@ class DarsExporter:
|
|
|
336
336
|
|
|
337
337
|
[bold]{translator.get('statistics')}:[/bold]
|
|
338
338
|
• {translator.get('total_components')}: {stats['total_components']}
|
|
339
|
+
• {translator.get('total_pages')}: {stats.get('total_pages', 1)}
|
|
339
340
|
• {translator.get('max_depth')}: {stats['max_depth']}
|
|
340
341
|
• {translator.get('scripts')}: {stats['scripts_count']}
|
|
341
342
|
• {translator.get('global_styles')}: {stats['global_styles_count']}
|
|
@@ -456,6 +457,21 @@ app.add_script(script)
|
|
|
456
457
|
console.print(Syntax(f"dars preview build", "bash"))
|
|
457
458
|
|
|
458
459
|
|
|
460
|
+
def print_version_info():
|
|
461
|
+
import importlib.util
|
|
462
|
+
import os
|
|
463
|
+
from rich.panel import Panel
|
|
464
|
+
from rich.console import Console
|
|
465
|
+
console = Console()
|
|
466
|
+
version_path = os.path.join(os.path.dirname(__file__), '../version.py')
|
|
467
|
+
spec = importlib.util.spec_from_file_location("dars.version", version_path)
|
|
468
|
+
version_mod = importlib.util.module_from_spec(spec)
|
|
469
|
+
spec.loader.exec_module(version_mod)
|
|
470
|
+
version = getattr(version_mod, "__version__", "unknown")
|
|
471
|
+
release_url = getattr(version_mod, "__release_url__", "https://github.com/ZtaMDev/Dars-Framework/releases")
|
|
472
|
+
panel_content = f"[bold cyan]Dars Framework[/bold cyan]\n\n[green]Version:[/green] {version}\n[green]Release notes:[/green] [link={release_url}]{release_url}[/link]"
|
|
473
|
+
console.print(Panel(panel_content, title="Dars Version", border_style="cyan"))
|
|
474
|
+
|
|
459
475
|
def create_parser() -> argparse.ArgumentParser:
|
|
460
476
|
"""Creates the command line argument parser"""
|
|
461
477
|
parser = argparse.ArgumentParser(
|
|
@@ -463,6 +479,7 @@ def create_parser() -> argparse.ArgumentParser:
|
|
|
463
479
|
formatter_class=RichHelpFormatter,
|
|
464
480
|
epilog="" # Remove epilog to avoid duplication
|
|
465
481
|
)
|
|
482
|
+
parser.add_argument('-v', '--version', action='store_true', help='Show Dars version and release link')
|
|
466
483
|
|
|
467
484
|
# Add language parameter to the main parser
|
|
468
485
|
parser.add_argument('--lang', '-l', choices=['en', 'es'], default='en',
|
|
@@ -567,6 +584,11 @@ def main():
|
|
|
567
584
|
# This is already handled in the pre-parsing step above, so we don't need to do it again
|
|
568
585
|
# The translator will already have the correct language set
|
|
569
586
|
|
|
587
|
+
# Show version and exit if -v/--version is passed
|
|
588
|
+
if getattr(args, 'version', False):
|
|
589
|
+
print_version_info()
|
|
590
|
+
sys.exit(0)
|
|
591
|
+
|
|
570
592
|
# Show banner for normal commands
|
|
571
593
|
console.print(Panel(
|
|
572
594
|
Text("Dars Exporter", style="bold cyan", justify="center"),
|
|
@@ -75,6 +75,8 @@ class PreviewServer:
|
|
|
75
75
|
def preview_html_app(directory: str, auto_open: bool = True, port: int = 8000):
|
|
76
76
|
"""Previews an exported HTML application"""
|
|
77
77
|
|
|
78
|
+
import signal
|
|
79
|
+
|
|
78
80
|
# Verify that index.html exists
|
|
79
81
|
index_path = os.path.join(directory, "index.html")
|
|
80
82
|
if not os.path.exists(index_path):
|
|
@@ -110,16 +112,22 @@ def preview_html_app(directory: str, auto_open: bool = True, port: int = 8000):
|
|
|
110
112
|
except Exception as e:
|
|
111
113
|
console.print(f"[yellow]{translator.get('browser_open_error')}: {e}[/yellow]")
|
|
112
114
|
console.print(f"[cyan]{translator.get('open_manually')}: {url}[/cyan]")
|
|
113
|
-
|
|
115
|
+
|
|
116
|
+
import threading
|
|
117
|
+
import signal
|
|
118
|
+
|
|
119
|
+
shutdown_event = threading.Event()
|
|
120
|
+
|
|
114
121
|
try:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
time.sleep(1)
|
|
122
|
+
while not shutdown_event.is_set():
|
|
123
|
+
shutdown_event.wait(timeout=1) # Espera hasta que se pida cerrar, sin consumir CPU
|
|
118
124
|
except KeyboardInterrupt:
|
|
125
|
+
shutdown_event.set()
|
|
126
|
+
finally:
|
|
119
127
|
console.print(f"\n[yellow]{translator.get('stopping_server')}[/yellow]")
|
|
120
128
|
server.stop()
|
|
121
129
|
console.print(f"[green]{translator.get('server_stopped')}[/green]")
|
|
122
|
-
|
|
130
|
+
|
|
123
131
|
return True
|
|
124
132
|
|
|
125
133
|
def preview_react_app(directory: str):
|
|
@@ -7,10 +7,14 @@ class Accordion(Component):
|
|
|
7
7
|
sections: Lista de tuplas (título, contenido)
|
|
8
8
|
open_indices: Lista de índices abiertos (opcional)
|
|
9
9
|
"""
|
|
10
|
-
def __init__(self, sections: List[tuple], open_indices: Optional[List[int]]=None, **props):
|
|
10
|
+
def __init__(self, sections: List[tuple], open_indices: Optional[List[int]]=None, minimum_logic: bool = True, **props):
|
|
11
11
|
super().__init__(**props)
|
|
12
12
|
self.sections = sections
|
|
13
13
|
self.open_indices = open_indices or []
|
|
14
|
+
self.minimum_logic = minimum_logic
|
|
15
|
+
for _, content in sections:
|
|
16
|
+
if hasattr(content, 'render'):
|
|
17
|
+
self.add_child(content)
|
|
14
18
|
|
|
15
19
|
def render(self) -> str:
|
|
16
20
|
html = '<div class="dars-accordion">'
|
|
@@ -9,10 +9,15 @@ class Card(Component):
|
|
|
9
9
|
title: Optional[str] = None,
|
|
10
10
|
class_name: Optional[str] = None,
|
|
11
11
|
style: Optional[Dict[str, Any]] = None,
|
|
12
|
+
minimum_logic: bool = True,
|
|
12
13
|
**kwargs
|
|
13
14
|
):
|
|
14
|
-
super().__init__(
|
|
15
|
+
super().__init__(class_name=class_name, style=style, **kwargs)
|
|
15
16
|
self.title = title
|
|
17
|
+
self.minimum_logic = minimum_logic
|
|
18
|
+
if children:
|
|
19
|
+
for child in children:
|
|
20
|
+
self.add_child(child)
|
|
16
21
|
|
|
17
22
|
def render(self) -> str:
|
|
18
23
|
title_html = f'<h2>{self.title}</h2>' if self.title else ''
|
|
@@ -10,11 +10,16 @@ class Modal(Component):
|
|
|
10
10
|
is_open: bool = False,
|
|
11
11
|
class_name: Optional[str] = None,
|
|
12
12
|
style: Optional[Dict[str, Any]] = None,
|
|
13
|
+
minimum_logic: bool = True,
|
|
13
14
|
**kwargs
|
|
14
15
|
):
|
|
15
|
-
super().__init__(
|
|
16
|
+
super().__init__(class_name=class_name, style=style, **kwargs)
|
|
16
17
|
self.title = title
|
|
17
18
|
self.is_open = is_open
|
|
19
|
+
self.minimum_logic = minimum_logic
|
|
20
|
+
if children:
|
|
21
|
+
for child in children:
|
|
22
|
+
self.add_child(child)
|
|
18
23
|
|
|
19
24
|
def render(self) -> str:
|
|
20
25
|
title_html = f'<h2>{self.title}</h2>' if self.title else ''
|
|
@@ -5,14 +5,27 @@ class Navbar(Component):
|
|
|
5
5
|
"""Componente para crear barras de navegación."""
|
|
6
6
|
def __init__(
|
|
7
7
|
self,
|
|
8
|
-
children
|
|
8
|
+
*children,
|
|
9
9
|
brand: Optional[str] = None,
|
|
10
10
|
class_name: Optional[str] = None,
|
|
11
11
|
style: Optional[Dict[str, Any]] = None,
|
|
12
12
|
**kwargs
|
|
13
13
|
):
|
|
14
|
-
|
|
14
|
+
# Compatibilidad retro: si 'children' está en kwargs, lo usamos; si no, usamos los posicionales
|
|
15
|
+
children_kwarg = kwargs.pop('children', None)
|
|
16
|
+
from dars.core.component import Component
|
|
17
|
+
if children_kwarg is not None:
|
|
18
|
+
children_final = children_kwarg
|
|
19
|
+
elif len(children) == 1 and isinstance(children[0], list):
|
|
20
|
+
children_final = children[0]
|
|
21
|
+
else:
|
|
22
|
+
children_final = list(children)
|
|
23
|
+
# Filtro: solo instancias válidas de Component
|
|
24
|
+
children_final = [c for c in children_final if isinstance(c, Component)]
|
|
25
|
+
super().__init__(class_name=class_name, style=style, **kwargs)
|
|
15
26
|
self.brand = brand
|
|
27
|
+
for child in children_final:
|
|
28
|
+
self.add_child(child)
|
|
16
29
|
|
|
17
30
|
def render(self) -> str:
|
|
18
31
|
brand_html = f'<div class="dars-navbar-brand">{self.brand}</div>' if self.brand else ''
|
|
@@ -8,11 +8,15 @@ class Tabs(Component):
|
|
|
8
8
|
panels: Lista de componentes o strings (contenido de cada pestaña)
|
|
9
9
|
selected: Índice de la pestaña activa (opcional)
|
|
10
10
|
"""
|
|
11
|
-
def __init__(self, tabs: List[str], panels: List[Component], selected: Optional[int]=0, **props):
|
|
11
|
+
def __init__(self, tabs: List[str], panels: List[Component], selected: Optional[int]=0, minimum_logic: bool = True, **props):
|
|
12
12
|
super().__init__(**props)
|
|
13
13
|
self.tabs = tabs
|
|
14
14
|
self.panels = panels
|
|
15
15
|
self.selected = selected or 0
|
|
16
|
+
self.minimum_logic = minimum_logic
|
|
17
|
+
for panel in panels:
|
|
18
|
+
if hasattr(panel, 'render'):
|
|
19
|
+
self.add_child(panel)
|
|
16
20
|
|
|
17
21
|
def render(self) -> str:
|
|
18
22
|
tab_headers = ''.join(
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from dars.core.component import Component
|
|
2
|
+
from dars.core.properties import StyleProps
|
|
3
|
+
from dars.core.events import EventTypes
|
|
4
|
+
from dars.scripts.script import Script
|
|
5
|
+
from typing import Optional, Union, Dict, Any, Callable
|
|
6
|
+
|
|
7
|
+
class Button(Component):
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
text: str = "Button",
|
|
11
|
+
id: Optional[str] = None,
|
|
12
|
+
class_name: Optional[str] = None,
|
|
13
|
+
style: Optional[Dict[str, Any]] = None,
|
|
14
|
+
disabled: bool = False,
|
|
15
|
+
button_type: str = "button", # "button", "submit", "reset"
|
|
16
|
+
on_click: Optional[Callable] = None,
|
|
17
|
+
on_double_click: Optional[Callable] = None,
|
|
18
|
+
on_mouse_enter: Optional[Callable] = None,
|
|
19
|
+
on_mouse_leave: Optional[Callable] = None,
|
|
20
|
+
on_mouse_down: Optional[Callable] = None,
|
|
21
|
+
on_mouse_up: Optional[Callable] = None,
|
|
22
|
+
on_key_down: Optional[Callable] = None,
|
|
23
|
+
on_key_up: Optional[Callable] = None
|
|
24
|
+
):
|
|
25
|
+
super().__init__(id=id, class_name=class_name, style=style)
|
|
26
|
+
self.text = text
|
|
27
|
+
self.disabled = disabled
|
|
28
|
+
self.button_type = button_type
|
|
29
|
+
|
|
30
|
+
# Soporte para presets JS editables con dScript u otros Script
|
|
31
|
+
if on_click:
|
|
32
|
+
# Convertir a Script si es necesario
|
|
33
|
+
if not isinstance(on_click, Script) and callable(on_click):
|
|
34
|
+
from dars.scripts.dscript import dScript
|
|
35
|
+
on_click = dScript(on_click.__code__)
|
|
36
|
+
self.set_event(EventTypes.CLICK, on_click)
|
|
37
|
+
if on_double_click:
|
|
38
|
+
self.set_event(EventTypes.DOUBLE_CLICK, on_double_click)
|
|
39
|
+
if on_mouse_enter:
|
|
40
|
+
self.set_event(EventTypes.MOUSE_ENTER, on_mouse_enter)
|
|
41
|
+
if on_mouse_leave:
|
|
42
|
+
self.set_event(EventTypes.MOUSE_LEAVE, on_mouse_leave)
|
|
43
|
+
if on_mouse_down:
|
|
44
|
+
self.set_event(EventTypes.MOUSE_DOWN, on_mouse_down)
|
|
45
|
+
if on_mouse_up:
|
|
46
|
+
self.set_event(EventTypes.MOUSE_UP, on_mouse_up)
|
|
47
|
+
if on_key_down:
|
|
48
|
+
self.set_event(EventTypes.KEY_DOWN, on_key_down)
|
|
49
|
+
if on_key_up:
|
|
50
|
+
self.set_event(EventTypes.KEY_UP, on_key_up)
|
|
51
|
+
|
|
52
|
+
def render(self, exporter: Any) -> str:
|
|
53
|
+
# El método render será implementado por cada exportador
|
|
54
|
+
raise NotImplementedError("El método render debe ser implementado por el exportador")
|
|
55
|
+
|
|
@@ -21,7 +21,9 @@ class Input(Component):
|
|
|
21
21
|
on_change: Optional[Callable] = None,
|
|
22
22
|
on_input: Optional[Callable] = None,
|
|
23
23
|
on_focus: Optional[Callable] = None,
|
|
24
|
-
on_blur: Optional[Callable] = None
|
|
24
|
+
on_blur: Optional[Callable] = None,
|
|
25
|
+
on_key_down: Optional[Callable] = None,
|
|
26
|
+
on_key_up: Optional[Callable] = None
|
|
25
27
|
):
|
|
26
28
|
super().__init__(id=id, class_name=class_name, style=style)
|
|
27
29
|
self.value = value
|
|
@@ -34,7 +36,7 @@ class Input(Component):
|
|
|
34
36
|
self.min_length = min_length
|
|
35
37
|
self.pattern = pattern
|
|
36
38
|
|
|
37
|
-
#
|
|
39
|
+
# Soporte para presets JS editables con dScript u otros Script
|
|
38
40
|
if on_change:
|
|
39
41
|
self.set_event(EventTypes.CHANGE, on_change)
|
|
40
42
|
if on_input:
|
|
@@ -43,6 +45,10 @@ class Input(Component):
|
|
|
43
45
|
self.set_event(EventTypes.FOCUS, on_focus)
|
|
44
46
|
if on_blur:
|
|
45
47
|
self.set_event(EventTypes.BLUR, on_blur)
|
|
48
|
+
if on_key_down:
|
|
49
|
+
self.set_event(EventTypes.KEY_DOWN, on_key_down)
|
|
50
|
+
if on_key_up:
|
|
51
|
+
self.set_event(EventTypes.KEY_UP, on_key_up)
|
|
46
52
|
|
|
47
53
|
def render(self, exporter: Any) -> str:
|
|
48
54
|
# El método render será implementado por cada exportador
|