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.
Files changed (81) hide show
  1. {dars_framework-1.0.4/dars_framework.egg-info → dars_framework-1.0.6}/PKG-INFO +30 -33
  2. {dars_framework-1.0.4 → dars_framework-1.0.6}/README.md +26 -31
  3. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/all.py +4 -0
  4. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/cli/main.py +22 -0
  5. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/cli/preview.py +13 -5
  6. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/accordion.py +5 -1
  7. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/card.py +6 -1
  8. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/modal.py +6 -1
  9. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/navbar.py +15 -2
  10. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/tabs.py +5 -1
  11. dars_framework-1.0.6/dars/components/basic/button.py +55 -0
  12. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/input.py +8 -2
  13. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/core/app.py +219 -199
  14. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/core/component.py +32 -0
  15. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/exporters/web/html_css_js.py +179 -28
  16. dars_framework-1.0.6/dars/scripts/dscript.py +26 -0
  17. dars_framework-1.0.6/dars/templates/examples/advanced/advanced_modal_demo.py +275 -0
  18. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/advanced/all_components_demo.py +1 -1
  19. dars_framework-1.0.6/dars/version.py +2 -0
  20. {dars_framework-1.0.4 → dars_framework-1.0.6/dars_framework.egg-info}/PKG-INFO +30 -33
  21. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars_framework.egg-info/SOURCES.txt +5 -2
  22. dars_framework-1.0.6/dars_framework.egg-info/requires.txt +4 -0
  23. dars_framework-1.0.6/pyproject.toml +24 -0
  24. dars_framework-1.0.4/dars/components/basic/button.py +0 -29
  25. dars_framework-1.0.4/dars_framework.egg-info/requires.txt +0 -2
  26. dars_framework-1.0.4/pyproject.toml +0 -20
  27. {dars_framework-1.0.4 → dars_framework-1.0.6}/LICENSE +0 -0
  28. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/__init__.py +0 -0
  29. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/cli/__init__.py +0 -0
  30. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/cli/hot_reload.py +0 -0
  31. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/cli/translations.py +0 -0
  32. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/__init__.py +0 -0
  33. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/__init__.py +0 -0
  34. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/advanced/table.py +0 -0
  35. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/__init__.py +0 -0
  36. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/checkbox.py +0 -0
  37. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/container.py +0 -0
  38. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/datepicker.py +0 -0
  39. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/image.py +0 -0
  40. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/link.py +0 -0
  41. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/page.py +0 -0
  42. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/progressbar.py +0 -0
  43. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/radiobutton.py +0 -0
  44. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/select.py +0 -0
  45. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/slider.py +0 -0
  46. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/spinner.py +0 -0
  47. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/text.py +0 -0
  48. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/textarea.py +0 -0
  49. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/basic/tooltip.py +0 -0
  50. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/layout/__init__.py +0 -0
  51. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/layout/anchor.py +0 -0
  52. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/layout/flex.py +0 -0
  53. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/components/layout/grid.py +0 -0
  54. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/core/__init__.py +0 -0
  55. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/core/events.py +0 -0
  56. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/core/properties.py +0 -0
  57. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/docs/__init__.py +0 -0
  58. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/exporters/__init__.py +0 -0
  59. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/exporters/base.py +0 -0
  60. {dars_framework-1.0.4/dars/exporters/web → dars_framework-1.0.6/dars/exporters/web/OLD}/html_css_js_old.py +0 -0
  61. {dars_framework-1.0.4/dars/exporters/web → dars_framework-1.0.6/dars/exporters/web/OLD}/html_css_js_old2.py +0 -0
  62. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/exporters/web/__init__.py +0 -0
  63. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/scripts/__init__.py +0 -0
  64. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/scripts/script.py +0 -0
  65. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/__init__.py +0 -0
  66. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/advanced/dashboard.py +0 -0
  67. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/advanced/modern_web_app.py +0 -0
  68. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/flex_layout_responsive.py +0 -0
  69. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/form_components.py +0 -0
  70. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/grid_layout_responsive.py +0 -0
  71. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/hello_world.py +0 -0
  72. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/layout_multipage_demo.py +0 -0
  73. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/multipage_example.py +0 -0
  74. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/pwa_custom_icons.py +0 -0
  75. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/basic/simple_form.py +0 -0
  76. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/examples/demo/complete_app.py +0 -0
  77. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars/templates/html/__init__.py +0 -0
  78. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars_framework.egg-info/dependency_links.txt +0 -0
  79. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars_framework.egg-info/entry_points.txt +0 -0
  80. {dars_framework-1.0.4 → dars_framework-1.0.6}/dars_framework.egg-info/top_level.txt +0 -0
  81. {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
4
- Summary: Dars Framework build applications with Python and export to web
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 Framework
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 some Javascript or frontend stack required.
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
- #!/usr/bin/env python3
52
- from dars.core.app import App
53
- from dars.components.basic.text import Text
54
- from dars.components.basic.button import Button
55
- from dars.components.basic.container import Container
56
- from dars.scripts.script import InlineScript
57
-
58
- # Crear aplicación
59
- app = App(title="Mi Primera App")
60
-
61
- # Crear componentes
62
- container = Container(style={
63
- 'display': 'flex',
64
- 'flex-direction': 'column',
65
- 'align-items': 'center',
66
- 'padding': '40px'
67
- })
68
-
69
- titulo = Text(
70
- text="Hola Dars",
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() # Live preview at http://localhost:8000
92
+ app.rTimeCompile() # Live preview at http://localhost:8000
93
+
97
94
  ```
98
95
 
99
96
  ## CLI Usage
@@ -1,6 +1,8 @@
1
- # Dars Framework
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 some Javascript or frontend stack required.
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
- #!/usr/bin/env python3
19
- from dars.core.app import App
20
- from dars.components.basic.text import Text
21
- from dars.components.basic.button import Button
22
- from dars.components.basic.container import Container
23
- from dars.scripts.script import InlineScript
24
-
25
- # Crear aplicación
26
- app = App(title="Mi Primera App")
27
-
28
- # Crear componentes
29
- container = Container(style={
30
- 'display': 'flex',
31
- 'flex-direction': 'column',
32
- 'align-items': 'center',
33
- 'padding': '40px'
34
- })
35
-
36
- titulo = Text(
37
- text="Hola Dars",
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() # Live preview at http://localhost:8000
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
- # Keep the server running
116
- while True:
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__(children=children, class_name=class_name, style=style, **kwargs)
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__(children=children, class_name=class_name, style=style, **kwargs)
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: Optional[List[Component]] = None,
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
- super().__init__(children=children, class_name=class_name, style=style, **kwargs)
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
- # Registrar eventos si se proporcionan
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