dars-framework 1.0.1__tar.gz → 1.0.3__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 (75) hide show
  1. {dars_framework-1.0.1/dars_framework.egg-info → dars_framework-1.0.3}/PKG-INFO +7 -3
  2. {dars_framework-1.0.1 → dars_framework-1.0.3}/README.md +117 -113
  3. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/all.py +1 -0
  4. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/cli/main.py +5 -5
  5. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/container.py +10 -5
  6. dars_framework-1.0.3/dars/core/component.py +140 -0
  7. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/exporters/web/html_css_js.py +1 -1
  8. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/examples/basic/pwa_custom_icons.py +2 -4
  9. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/examples/basic/simple_form.py +2 -0
  10. {dars_framework-1.0.1 → dars_framework-1.0.3/dars_framework.egg-info}/PKG-INFO +7 -3
  11. {dars_framework-1.0.1 → dars_framework-1.0.3}/pyproject.toml +1 -1
  12. dars_framework-1.0.1/dars/core/component.py +0 -25
  13. {dars_framework-1.0.1 → dars_framework-1.0.3}/LICENSE +0 -0
  14. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/__init__.py +0 -0
  15. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/cli/__init__.py +0 -0
  16. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/cli/hot_reload.py +0 -0
  17. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/cli/preview.py +0 -0
  18. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/cli/translations.py +0 -0
  19. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/__init__.py +0 -0
  20. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/advanced/__init__.py +0 -0
  21. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/advanced/accordion.py +0 -0
  22. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/advanced/card.py +0 -0
  23. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/advanced/modal.py +0 -0
  24. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/advanced/navbar.py +0 -0
  25. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/advanced/table.py +0 -0
  26. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/advanced/tabs.py +0 -0
  27. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/__init__.py +0 -0
  28. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/button.py +0 -0
  29. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/checkbox.py +0 -0
  30. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/datepicker.py +0 -0
  31. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/image.py +0 -0
  32. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/input.py +0 -0
  33. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/link.py +0 -0
  34. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/page.py +0 -0
  35. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/progressbar.py +0 -0
  36. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/radiobutton.py +0 -0
  37. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/select.py +0 -0
  38. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/slider.py +0 -0
  39. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/spinner.py +0 -0
  40. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/text.py +0 -0
  41. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/textarea.py +0 -0
  42. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/basic/tooltip.py +0 -0
  43. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/layout/__init__.py +0 -0
  44. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/layout/anchor.py +0 -0
  45. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/layout/flex.py +0 -0
  46. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/components/layout/grid.py +0 -0
  47. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/core/__init__.py +0 -0
  48. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/core/app.py +0 -0
  49. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/core/events.py +0 -0
  50. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/core/properties.py +0 -0
  51. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/docs/__init__.py +0 -0
  52. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/exporters/__init__.py +0 -0
  53. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/exporters/base.py +0 -0
  54. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/exporters/web/__init__.py +0 -0
  55. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/exporters/web/html_css_js_old.py +0 -0
  56. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/scripts/__init__.py +0 -0
  57. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/scripts/script.py +0 -0
  58. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/__init__.py +0 -0
  59. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/examples/advanced/all_components_demo.py +0 -0
  60. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/examples/advanced/dashboard.py +0 -0
  61. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/examples/advanced/modern_web_app.py +0 -0
  62. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/examples/basic/flex_layout_responsive.py +0 -0
  63. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/examples/basic/form_components.py +0 -0
  64. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/examples/basic/grid_layout_responsive.py +0 -0
  65. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/examples/basic/hello_world.py +0 -0
  66. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/examples/basic/layout_multipage_demo.py +0 -0
  67. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/examples/basic/multipage_example.py +0 -0
  68. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/examples/demo/complete_app.py +0 -0
  69. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars/templates/html/__init__.py +0 -0
  70. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars_framework.egg-info/SOURCES.txt +0 -0
  71. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars_framework.egg-info/dependency_links.txt +0 -0
  72. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars_framework.egg-info/entry_points.txt +0 -0
  73. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars_framework.egg-info/requires.txt +0 -0
  74. {dars_framework-1.0.1 → dars_framework-1.0.3}/dars_framework.egg-info/top_level.txt +0 -0
  75. {dars_framework-1.0.1 → dars_framework-1.0.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dars-framework
3
- Version: 1.0.1
3
+ Version: 1.0.3
4
4
  Summary: Dars Framework build applications with Python and export to web
5
5
  Author-email: ztamdev <zondax2009@gmail.com>
6
6
  License: MIT License
@@ -33,7 +33,11 @@ Dynamic: license-file
33
33
 
34
34
  # Dars Framework
35
35
 
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—no Javascript or frontend stack required.
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.
37
+
38
+ ```bash
39
+ pip install dars-framework
40
+ ```
37
41
 
38
42
  ## How It Works
39
43
  - Build your UI using Python classes and components (like Text, Button, Container, Page, etc).
@@ -105,7 +109,7 @@ if __name__ == "__main__":
105
109
  ## More
106
110
  - [Project Roadmap](ROADMAP.md)
107
111
  - [Getting Started](dars/docs/getting_started.md)
108
- - [Components Reference](dars/docs/components.md)
112
+ - [Components Documentation](dars/docs/components.md)
109
113
  - [Exporters](dars/docs/exporters.md)
110
114
  - [Scripts System](dars/docs/scripts.md)
111
115
  - [CLI usage and commands](dars/docs/cli.md)
@@ -1,113 +1,117 @@
1
- # Dars Framework
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—no Javascript or frontend stack required.
4
-
5
- ## How It Works
6
- - Build your UI using Python classes and components (like Text, Button, Container, Page, etc).
7
- - Preview instantly with hot-reload using `app.rTimeCompile()`.
8
- - Export your app to static web files with a single CLI command.
9
- - Use multipage, layouts, scripts, and more—see docs for advanced features.
10
-
11
- ## Quick Example: Your First App
12
-
13
- ```python
14
- #!/usr/bin/env python3
15
- from dars.core.app import App
16
- from dars.components.basic.text import Text
17
- from dars.components.basic.button import Button
18
- from dars.components.basic.container import Container
19
- from dars.scripts.script import InlineScript
20
-
21
- # Crear aplicación
22
- app = App(title="Mi Primera App")
23
-
24
- # Crear componentes
25
- container = Container(style={
26
- 'display': 'flex',
27
- 'flex-direction': 'column',
28
- 'align-items': 'center',
29
- 'padding': '40px'
30
- })
31
-
32
- titulo = Text(
33
- text="Hola Dars",
34
- style={'font-size': '32px', 'color': '#333'}
35
- )
36
-
37
- boton = Button(
38
- text="Hacer clic",
39
- style={'background-color': '#007bff', 'color': 'white'}
40
- )
41
-
42
- # Script para interactividad
43
- script = InlineScript("""
44
- document.addEventListener('DOMContentLoaded', function() {
45
- const boton = document.querySelector('button');
46
- boton.addEventListener('click', function() {
47
- alert('Hola desde Dars.');
48
- });
49
- });
50
- """)
51
-
52
- # Ensamblar aplicación
53
- container.add_child(titulo)
54
- container.add_child(boton)
55
- app.set_root(container)
56
- app.add_script(script)
57
-
58
- if __name__ == "__main__":
59
- app.rTimeCompile() # Live preview at http://localhost:8000
60
- ```
61
-
62
- ## CLI Usage
63
- | Command | What it does |
64
- |-----------------------------------------|--------------------------------------------|
65
- | `dars export my_app.py --format html` | Export app to HTML/CSS/JS in `./my_app_web` |
66
- | `dars preview ./my_app_web` | Preview exported app locally |
67
- | `dars init my_project` | Create a new Dars project |
68
- | `dars info my_app.py` | Show info about your app |
69
- | `dars formats` | List supported export formats |
70
- | `dars --help` | Show help and all CLI options |
71
-
72
- ## More
73
- - [Project Roadmap](ROADMAP.md)
74
- - [Getting Started](dars/docs/getting_started.md)
75
- - [Components Reference](dars/docs/components.md)
76
- - [Exporters](dars/docs/exporters.md)
77
- - [Scripts System](dars/docs/scripts.md)
78
- - [CLI usage and commands](dars/docs/cli.md)
79
- - [Project Structure](STRUCTURE.md)
80
- - [Architecture](DARS_ARCHITECTURE.md)
81
- - [Installation Guide](INSTALL.md)
82
-
83
- ## Local Execution and Live Preview
84
-
85
- To test your app locally before exporting, use the hot-reload preview from any Python file that defines your app:
86
-
87
- ```python
88
- if __name__ == "__main__":
89
- app.rTimeCompile()
90
- ```
91
-
92
- Then run your file directly:
93
-
94
- ```bash
95
- python my_app.py
96
- ```
97
-
98
- This will start a local server at http://localhost:8000 so you can view your app in the browser—no manual export needed. You can change the port with:
99
-
100
- ```bash
101
- python my_app.py --port 8088
102
- ```
103
-
104
- ---
105
-
106
- You can also use the CLI preview command on an exported app:
107
-
108
- ```bash
109
- dars preview ./my_exported_app
110
- ```
111
-
112
- This will start a local server at http://localhost:8000 to view your exported app in the browser.
113
-
1
+ # Dars Framework
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.
4
+
5
+ ```bash
6
+ pip install dars-framework
7
+ ```
8
+
9
+ ## How It Works
10
+ - Build your UI using Python classes and components (like Text, Button, Container, Page, etc).
11
+ - Preview instantly with hot-reload using `app.rTimeCompile()`.
12
+ - Export your app to static web files with a single CLI command.
13
+ - Use multipage, layouts, scripts, and more—see docs for advanced features.
14
+
15
+ ## Quick Example: Your First App
16
+
17
+ ```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'}
44
+ )
45
+
46
+ # Script para interactividad
47
+ script = InlineScript("""
48
+ document.addEventListener('DOMContentLoaded', function() {
49
+ const boton = document.querySelector('button');
50
+ boton.addEventListener('click', function() {
51
+ alert('Hola desde Dars.');
52
+ });
53
+ });
54
+ """)
55
+
56
+ # Ensamblar aplicación
57
+ container.add_child(titulo)
58
+ container.add_child(boton)
59
+ app.set_root(container)
60
+ app.add_script(script)
61
+
62
+ if __name__ == "__main__":
63
+ app.rTimeCompile() # Live preview at http://localhost:8000
64
+ ```
65
+
66
+ ## CLI Usage
67
+ | Command | What it does |
68
+ |-----------------------------------------|--------------------------------------------|
69
+ | `dars export my_app.py --format html` | Export app to HTML/CSS/JS in `./my_app_web` |
70
+ | `dars preview ./my_app_web` | Preview exported app locally |
71
+ | `dars init my_project` | Create a new Dars project |
72
+ | `dars info my_app.py` | Show info about your app |
73
+ | `dars formats` | List supported export formats |
74
+ | `dars --help` | Show help and all CLI options |
75
+
76
+ ## More
77
+ - [Project Roadmap](ROADMAP.md)
78
+ - [Getting Started](dars/docs/getting_started.md)
79
+ - [Components Documentation](dars/docs/components.md)
80
+ - [Exporters](dars/docs/exporters.md)
81
+ - [Scripts System](dars/docs/scripts.md)
82
+ - [CLI usage and commands](dars/docs/cli.md)
83
+ - [Project Structure](STRUCTURE.md)
84
+ - [Architecture](DARS_ARCHITECTURE.md)
85
+ - [Installation Guide](INSTALL.md)
86
+
87
+ ## Local Execution and Live Preview
88
+
89
+ To test your app locally before exporting, use the hot-reload preview from any Python file that defines your app:
90
+
91
+ ```python
92
+ if __name__ == "__main__":
93
+ app.rTimeCompile()
94
+ ```
95
+
96
+ Then run your file directly:
97
+
98
+ ```bash
99
+ python my_app.py
100
+ ```
101
+
102
+ This will start a local server at http://localhost:8000 so you can view your app in the browser—no manual export needed. You can change the port with:
103
+
104
+ ```bash
105
+ python my_app.py --port 8088
106
+ ```
107
+
108
+ ---
109
+
110
+ You can also use the CLI preview command on an exported app:
111
+
112
+ ```bash
113
+ dars preview ./my_exported_app
114
+ ```
115
+
116
+ This will start a local server at http://localhost:8000 to view your exported app in the browser.
117
+
@@ -5,6 +5,7 @@
5
5
  from dars.core.app import App
6
6
  from dars.core.component import Component
7
7
  from dars.core.events import EventManager
8
+ from dars.core.properties import *
8
9
 
9
10
  # Basic Components
10
11
  from dars.components.basic.button import Button
@@ -215,6 +215,11 @@ class DarsExporter:
215
215
  console.print(f"[red]{translator.get('error_file_not_exists')} {file_path}[/red]")
216
216
  return None
217
217
 
218
+ # Add the application's root directory to sys.path
219
+ file_dir = os.path.dirname(os.path.abspath(file_path))
220
+ if file_dir not in sys.path:
221
+ sys.path.insert(0, file_dir)
222
+
218
223
  # Load the module dynamically
219
224
  spec = importlib.util.spec_from_file_location("user_app", file_path)
220
225
  if spec is None or spec.loader is None:
@@ -222,11 +227,6 @@ class DarsExporter:
222
227
  return None
223
228
 
224
229
  module = importlib.util.module_from_spec(spec)
225
-
226
- # Add the file directory to the path for relative imports
227
- file_dir = os.path.dirname(os.path.abspath(file_path))
228
-
229
-
230
230
  spec.loader.exec_module(module)
231
231
 
232
232
  # Look for the 'app' variable in the module
@@ -4,17 +4,22 @@ from typing import Optional, Union, Dict, Any, List
4
4
 
5
5
  class Container(Component):
6
6
  def __init__(
7
- self,
7
+ self,
8
+ *children: Component,
8
9
  id: Optional[str] = None,
9
10
  class_name: Optional[str] = None,
10
11
  style: Optional[Dict[str, Any]] = None,
11
- children: Optional[List[Component]] = None
12
+ additional_children: Optional[List[Component]] = None
12
13
  ):
13
14
  super().__init__(id=id, class_name=class_name, style=style)
14
15
 
15
- # Agregar hijos si se proporcionan
16
- if children:
17
- for child in children:
16
+ # Agregar hijos pasados como argumentos posicionales
17
+ for child in children:
18
+ self.add_child(child)
19
+
20
+ # Agregar hijos adicionales si se proporcionan
21
+ if additional_children:
22
+ for child in additional_children:
18
23
  self.add_child(child)
19
24
 
20
25
  def render(self, exporter: Any) -> str:
@@ -0,0 +1,140 @@
1
+ from typing import Dict, Any, List, Optional, Callable, Union, Type
2
+ from abc import ABC, abstractmethod
3
+
4
+ class ComponentQuery:
5
+ def __init__(self, components: List['Component']):
6
+ self.components = components
7
+
8
+ def find(self,
9
+ id: Optional[str] = None,
10
+ class_name: Optional[str] = None,
11
+ type: Optional[Union[Type['Component'], str]] = None,
12
+ predicate: Optional[Callable[['Component'], bool]] = None) -> 'ComponentQuery':
13
+ """
14
+ Busca componentes dentro de los componentes actualmente seleccionados
15
+ """
16
+ results: List['Component'] = []
17
+
18
+ def match_component(comp: Component) -> bool:
19
+ if id is not None and comp.id != id:
20
+ return False
21
+ if class_name is not None and comp.class_name != class_name:
22
+ return False
23
+ if type is not None:
24
+ if isinstance(type, str):
25
+ if comp.__class__.__name__ != type:
26
+ return False
27
+ elif not isinstance(comp, type):
28
+ return False
29
+ if predicate is not None and not predicate(comp):
30
+ return False
31
+ return True
32
+
33
+ # Buscar en los hijos de todos los componentes actuales
34
+ for component in self.components:
35
+ for child in component.children:
36
+ if match_component(child):
37
+ results.append(child)
38
+ # Buscar recursivamente en los hijos del hijo
39
+ for descendant in ComponentQuery([child]).find().get():
40
+ if match_component(descendant):
41
+ results.append(descendant)
42
+
43
+ return ComponentQuery(results)
44
+
45
+ def attr(self, **attrs) -> 'ComponentQuery':
46
+ """Modifica los atributos de todos los componentes encontrados"""
47
+ for component in self.components:
48
+ for key, value in attrs.items():
49
+ # Manejo especial para atributos comunes
50
+ if key == 'style':
51
+ component.style.update(value)
52
+ continue
53
+ elif key == 'class_name':
54
+ component.class_name = value
55
+ continue
56
+ elif key == 'events':
57
+ component.events.update(value)
58
+ continue
59
+
60
+ # Intenta establecer el atributo directamente si existe
61
+ if hasattr(component, key):
62
+ setattr(component, key, value)
63
+ # Si no existe como atributo directo, guárdalo en props
64
+ else:
65
+ component.props[key] = value
66
+ return self
67
+
68
+ def get(self) -> List['Component']:
69
+ """Devuelve la lista de componentes encontrados"""
70
+ return self.components
71
+
72
+ def first(self) -> Optional['Component']:
73
+ """Devuelve el primer componente encontrado o None si no hay ninguno"""
74
+ return self.components[0] if self.components else None
75
+
76
+ class Component(ABC):
77
+ def __init__(self, **props):
78
+ self.props = props
79
+ self.children: List[Component] = []
80
+ self.parent: Optional[Component] = None
81
+ self.id: Optional[str] = props.get('id')
82
+ self.class_name: Optional[str] = props.get('class_name')
83
+ self.style: Dict[str, Any] = props.get('style', {})
84
+ self.events: Dict[str, Callable] = {}
85
+
86
+ def add_child(self, child: 'Component'):
87
+ child.parent = self
88
+ self.children.append(child)
89
+
90
+ def set_event(self, event_name: str, handler: Callable):
91
+ self.events[event_name] = handler
92
+
93
+ def find(self,
94
+ id: Optional[str] = None,
95
+ class_name: Optional[str] = None,
96
+ type: Optional[Union[Type['Component'], str]] = None,
97
+ predicate: Optional[Callable[['Component'], bool]] = None) -> ComponentQuery:
98
+ """
99
+ Busca componentes que coincidan con los criterios especificados.
100
+
101
+ Args:
102
+ id: Buscar por ID del componente
103
+ class_name: Buscar por nombre de clase CSS
104
+ type: Buscar por tipo de componente (clase o nombre de clase)
105
+ predicate: Función personalizada de filtrado que toma un componente y devuelve bool
106
+
107
+ Returns:
108
+ ComponentQuery que permite encadenar operaciones y modificar atributos
109
+ """
110
+ results: List[Component] = []
111
+
112
+ def match_component(comp: Component) -> bool:
113
+ if id is not None and comp.id != id:
114
+ return False
115
+ if class_name is not None and comp.class_name != class_name:
116
+ return False
117
+ if type is not None:
118
+ if isinstance(type, str):
119
+ if comp.__class__.__name__ != type:
120
+ return False
121
+ elif not isinstance(comp, type):
122
+ return False
123
+ if predicate is not None and not predicate(comp):
124
+ return False
125
+ return True
126
+
127
+ def search_recursive(component: Component):
128
+ if match_component(component):
129
+ results.append(component)
130
+ for child in component.children:
131
+ search_recursive(child)
132
+
133
+ search_recursive(self)
134
+ return ComponentQuery(results)
135
+
136
+ @abstractmethod
137
+ def render(self, exporter: 'Exporter') -> str:
138
+ pass
139
+
140
+
@@ -279,7 +279,7 @@ self.addEventListener('fetch', event => {
279
279
  root_component = app.root
280
280
  # Protección: si root es lista, envolver en Container correctamente
281
281
  if isinstance(root_component, list):
282
- root_component = Container(children=root_component)
282
+ root_component = Container(*root_component)
283
283
  if root_component:
284
284
  body_content = self.render_component(root_component)
285
285
 
@@ -24,8 +24,6 @@ app = App(
24
24
  )
25
25
 
26
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
- ]
27
+ Text(text="¡Bienvenido a la PWA con iconos personalizados!"),
28
+ Button(text="Haz clic aquí", on_click=lambda: print("¡Botón de ejemplo!")),
31
29
  )
@@ -375,3 +375,5 @@ app.add_script(script)
375
375
  # Para exportar esta aplicación, ejecuta:
376
376
  # ./dars_exporter export examples/basic/simple_form.py --format html --output ./simple_form_output
377
377
 
378
+ if __name__ == '__main__':
379
+ app.rTimeCompile()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dars-framework
3
- Version: 1.0.1
3
+ Version: 1.0.3
4
4
  Summary: Dars Framework build applications with Python and export to web
5
5
  Author-email: ztamdev <zondax2009@gmail.com>
6
6
  License: MIT License
@@ -33,7 +33,11 @@ Dynamic: license-file
33
33
 
34
34
  # Dars Framework
35
35
 
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—no Javascript or frontend stack required.
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.
37
+
38
+ ```bash
39
+ pip install dars-framework
40
+ ```
37
41
 
38
42
  ## How It Works
39
43
  - Build your UI using Python classes and components (like Text, Button, Container, Page, etc).
@@ -105,7 +109,7 @@ if __name__ == "__main__":
105
109
  ## More
106
110
  - [Project Roadmap](ROADMAP.md)
107
111
  - [Getting Started](dars/docs/getting_started.md)
108
- - [Components Reference](dars/docs/components.md)
112
+ - [Components Documentation](dars/docs/components.md)
109
113
  - [Exporters](dars/docs/exporters.md)
110
114
  - [Scripts System](dars/docs/scripts.md)
111
115
  - [CLI usage and commands](dars/docs/cli.md)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dars-framework"
3
- version = "1.0.1"
3
+ version = "1.0.3"
4
4
  description = "Dars Framework build applications with Python and export to web"
5
5
  authors = [
6
6
  { name="ztamdev", email="zondax2009@gmail.com" }
@@ -1,25 +0,0 @@
1
- from typing import Dict, Any, List, Optional, Callable
2
- from abc import ABC, abstractmethod
3
-
4
- class Component(ABC):
5
- def __init__(self, **props):
6
- self.props = props
7
- self.children: List[Component] = []
8
- self.parent: Optional[Component] = None
9
- self.id: Optional[str] = props.get('id')
10
- self.class_name: Optional[str] = props.get('class_name')
11
- self.style: Dict[str, Any] = props.get('style', {})
12
- self.events: Dict[str, Callable] = {}
13
-
14
- def add_child(self, child: 'Component'):
15
- child.parent = self
16
- self.children.append(child)
17
-
18
- def set_event(self, event_name: str, handler: Callable):
19
- self.events[event_name] = handler
20
-
21
- @abstractmethod
22
- def render(self, exporter: 'Exporter') -> str:
23
- pass
24
-
25
-
File without changes
File without changes