dars-framework 1.2.1__tar.gz → 1.2.2__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 (126) hide show
  1. {dars_framework-1.2.1/dars_framework.egg-info → dars_framework-1.2.2}/PKG-INFO +3 -3
  2. {dars_framework-1.2.1 → dars_framework-1.2.2}/README.md +223 -204
  3. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/core/state.py +54 -0
  4. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/web/html_css_js.py +24 -1
  5. dars_framework-1.2.2/dars/js_lib.py +206 -0
  6. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/version.py +2 -2
  7. {dars_framework-1.2.1 → dars_framework-1.2.2/dars_framework.egg-info}/PKG-INFO +3 -3
  8. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars_framework.egg-info/requires.txt +1 -1
  9. {dars_framework-1.2.1 → dars_framework-1.2.2}/pyproject.toml +3 -5
  10. dars_framework-1.2.1/dars/js_lib.py +0 -133
  11. {dars_framework-1.2.1 → dars_framework-1.2.2}/LICENSE +0 -0
  12. {dars_framework-1.2.1 → dars_framework-1.2.2}/MANIFEST.in +0 -0
  13. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/__init__.py +0 -0
  14. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/all.py +0 -0
  15. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/cli/__init__.py +0 -0
  16. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/cli/hot_reload.py +0 -0
  17. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/cli/main.py +0 -0
  18. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/cli/preview.py +0 -0
  19. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/cli/translations.py +0 -0
  20. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/__init__.py +0 -0
  21. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/__init__.py +0 -0
  22. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/accordion.py +0 -0
  23. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/card.py +0 -0
  24. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/modal.py +0 -0
  25. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/navbar.py +0 -0
  26. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/table.py +0 -0
  27. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/tabs.py +0 -0
  28. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/__init__.py +0 -0
  29. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/button.py +0 -0
  30. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/checkbox.py +0 -0
  31. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/container.py +0 -0
  32. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/datepicker.py +0 -0
  33. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/image.py +0 -0
  34. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/input.py +0 -0
  35. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/link.py +0 -0
  36. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/markdown.py +0 -0
  37. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/page.py +0 -0
  38. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/progressbar.py +0 -0
  39. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/radiobutton.py +0 -0
  40. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/select.py +0 -0
  41. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/slider.py +0 -0
  42. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/spinner.py +0 -0
  43. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/text.py +0 -0
  44. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/textarea.py +0 -0
  45. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/tooltip.py +0 -0
  46. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/layout/__init__.py +0 -0
  47. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/layout/anchor.py +0 -0
  48. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/layout/flex.py +0 -0
  49. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/layout/grid.py +0 -0
  50. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/config.py +0 -0
  51. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/core/__init__.py +0 -0
  52. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/core/app.py +0 -0
  53. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/core/component.py +0 -0
  54. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/core/events.py +0 -0
  55. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/core/properties.py +0 -0
  56. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/apps_test/health_check.py +0 -0
  57. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/run_tests.py +0 -0
  58. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/tests/test_advanced_components.py +0 -0
  59. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/tests/test_basic_components.py +0 -0
  60. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/tests/test_core_and_cli.py +0 -0
  61. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/tests/test_layout_components.py +0 -0
  62. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/tests/test_version_check.py +0 -0
  63. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/__init__.py +0 -0
  64. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/app.md +0 -0
  65. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/cli.md +0 -0
  66. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/components.md +0 -0
  67. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/custom_components.md +0 -0
  68. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/events.md +0 -0
  69. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/exporters.md +0 -0
  70. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/getting_started.md +0 -0
  71. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/index.md +0 -0
  72. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/scripts.md +0 -0
  73. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/state_management.md +0 -0
  74. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/__init__.py +0 -0
  75. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/base.py +0 -0
  76. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/web/OLD/html_css_js_OLD4.py +0 -0
  77. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/web/OLD/html_css_js_old.py +0 -0
  78. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/web/OLD/html_css_js_old2.py +0 -0
  79. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/web/__init__.py +0 -0
  80. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/web/vdom.py +0 -0
  81. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/scripts/__init__.py +0 -0
  82. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/scripts/dscript.py +0 -0
  83. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/scripts/script.py +0 -0
  84. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/security.py +0 -0
  85. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/__init__.py +0 -0
  86. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/__pycache__/__init__.cpython-311.pyc +0 -0
  87. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/README.md +0 -0
  88. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/__pycache__/dynamic_event_demo.cpython-311.pyc +0 -0
  89. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/Modal_Demo/advanced_modal_demo.py +0 -0
  90. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/SimpleDashboard/dashboard.py +0 -0
  91. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/SimpleModermWeb/modern_web_app.py +0 -0
  92. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/VariousComponents/all_components_demo.py +0 -0
  93. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/__init__.py +0 -0
  94. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/index.html +0 -0
  95. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/lib/dars.min.js +0 -0
  96. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/runtime_css.css +0 -0
  97. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/runtime_dars.js +0 -0
  98. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/script.js +0 -0
  99. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/snapshot.json +0 -0
  100. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/styles.css +0 -0
  101. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/vdom_tree.js +0 -0
  102. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/version.txt +0 -0
  103. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/state_mods_demo.py +0 -0
  104. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/Forms/form_components.py +0 -0
  105. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/Forms/simple_form.py +0 -0
  106. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/HelloWorld/hello_world.py +0 -0
  107. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/Layouts/flex_layout_responsive.py +0 -0
  108. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/Layouts/grid_layout_responsive.py +0 -0
  109. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/Layouts/layout_multipage_demo.py +0 -0
  110. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/Multipage/multipage_example.py +0 -0
  111. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/PWA/icon-192x192.png +0 -0
  112. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/PWA/icon-512x512.png +0 -0
  113. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/PWA/pwa_custom_icons.py +0 -0
  114. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/__init__.py +0 -0
  115. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/demo/__pycache__/complete_app.cpython-311.pyc +0 -0
  116. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/demo/complete_app.py +0 -0
  117. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/markdown/MarkdownTemplate/README.md +0 -0
  118. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/markdown/MarkdownTemplate/markdown_template.py +0 -0
  119. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/markdown/MarkdownTemplate/other_docs.md +0 -0
  120. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/markdown/__init__.py +0 -0
  121. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/html/__init__.py +0 -0
  122. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars_framework.egg-info/SOURCES.txt +0 -0
  123. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars_framework.egg-info/dependency_links.txt +0 -0
  124. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars_framework.egg-info/entry_points.txt +0 -0
  125. {dars_framework-1.2.1 → dars_framework-1.2.2}/dars_framework.egg-info/top_level.txt +0 -0
  126. {dars_framework-1.2.1 → dars_framework-1.2.2}/setup.cfg +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dars_framework
3
- Version: 1.2.1
3
+ Version: 1.2.2
4
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
- License: MIT
6
+ License-Expression: MIT
7
7
  License-File: LICENSE
8
- Requires-Dist: rich==14.0.0
8
+ Requires-Dist: rich==14.2.0
9
9
  Requires-Dist: bs4==0.0.2
10
10
  Requires-Dist: uvicorn==0.35.0
11
11
  Requires-Dist: fastapi==0.116.1
@@ -14,207 +14,226 @@ pip install dars-framework
14
14
 
15
15
  > Some Javascript or frontend stack required.
16
16
 
17
- Try dars without installing nothing just visit the [Dars Playground](https://dars-playground.vercel.app/)
18
-
19
- ## How It Works
20
- - Build your UI using Python classes and components (like Text, Button, Container, Page, etc).
21
- - Preview instantly with hot-reload using `app.rTimeCompile()`.
22
- - Export your app to static web files with a single CLI command.
23
- - Use multipage, layouts, scripts, and more—see docs for advanced features.
24
- - For mor information visit the [Documentation](https://ztamdev.github.io/Dars-Framework/documentation.html)
25
-
26
- ## Quick Example: Your First App
27
- ```python
28
- from dars.all import *
29
-
30
- app = App(title="Hello World", theme="dark")
31
- # Crear componentes
32
- index = Page(
33
- Text(
34
- text="Hello World",
35
- style={
36
- 'font-size': '48px',
37
- 'color': '#2c3e50',
38
- 'margin-bottom': '20px',
39
- 'font-weight': 'bold',
40
- 'text-align': 'center'
41
- }
42
- ),
43
- Text(
44
- text="Hello World",
45
- style={
46
- 'font-size': '20px',
47
- 'color': '#7f8c8d',
48
- 'margin-bottom': '40px',
49
- 'text-align': 'center'
50
- }
51
- ),
52
-
53
- Button(
54
- text="Click Me!",
55
- on_click= dScript("alert('Hello World')"),
56
- on_mouse_enter=dScript("this.style.backgroundColor = '#2980b9';"),
57
- on_mouse_leave=dScript("this.style.backgroundColor = '#3498db';"),
58
- style={
59
- 'background-color': '#3498db',
60
- 'color': 'white',
61
- 'padding': '15px 30px',
62
- 'border': 'none',
63
- 'border-radius': '8px',
64
- 'font-size': '18px',
65
- 'cursor': 'pointer',
66
- 'transition': 'background-color 0.3s'
67
- }
68
- ),
69
- style={
70
- 'display': 'flex',
71
- 'flex-direction': 'column',
72
- 'align-items': 'center',
73
- 'justify-content': 'center',
74
- 'min-height': '100vh',
75
- 'background-color': '#f0f2f5',
76
- 'font-family': 'Arial, sans-serif'
77
- }
78
- )
79
- index.attr()
80
- app.add_page("index", index, title="Hello World", index=True)
81
-
82
- if __name__ == "__main__":
83
- app.rTimeCompile()
84
-
85
- ```
86
-
87
- ---
88
-
89
- ## Reactivity and State System
90
-
91
- **Dars Framework** includes a built-in **reactive state system** (`dState` / `cState`) that allows dynamic and modular DOM updates directly from Python.
92
- It enables fully event-driven interfaces without requiring manual JavaScript.
93
-
94
- ### Key Concepts
95
-
96
- * **`dState(name, component, states)`**
97
- Creates a reactive state controller bound to a specific component and a list of possible states.
98
-
99
- * **`cState(idx, mods=[...])`**
100
- Defines rules (modifications) that are automatically applied when entering a specific state.
101
-
102
- * **`Mod` Helpers**
103
- A compact way to modify DOM elements on state changes: `inc`, `dec`, `set`, `toggle_class`, `append_text`, `prepend_text`, `goto`, and more.
104
-
105
- * **Deferred Mutations**
106
- Using `component.attr(..., defer=True)` or `component.mod(...)` inside a `cComp=True` state defers HTML updates until an event occurs, preventing authoring-time mutations.
107
-
108
- ### Example Template
109
-
110
- A complete example demonstrating `dState`, `cState`, `Mod`, and deferred updates is available [here](https://github.com/ZtaMDev/Dars-Framework/blob/CrystalMain/dars/templates/examples/advanced/dState/state_mods_demo.py)
111
-
112
- <img width="384" height="187" alt="imagen" src="https://github.com/user-attachments/assets/7750ee7f-768f-48da-94df-2fa00339a99c" /> <img width="361" height="215" alt="imagen" src="https://github.com/user-attachments/assets/9b8a3e67-2424-49b4-aee0-9f1c0f747d66" />
113
-
114
-
115
-
116
- ### Features
117
-
118
- * Reactive Mod system with compact `Mod` helpers
119
- * Unified event model — any component can use `on_*` props (`on_click`, `on_input`, `on_change`, etc.)
120
- * Deferred rendering for safer, predictable state transitions (`cComp=True`)
121
- * Navigation between states using `goto`, including relative moves (`'+1'`, `'-1'`)
122
- * Consistent, event-time mutation flow for reliable behavior
123
-
124
- ---
125
-
126
- ## CLI Usage
127
- | Command | What it does |
128
- |-----------------------------------------|--------------------------------------------|
129
- | `dars export my_app.py --format html` | Export app to HTML/CSS/JS in `./my_app_web` |
130
- | `dars preview ./my_app_web` | Preview exported app locally |
131
- | `dars init my_project` | Create a new Dars project (also creates dars.config.json) |
132
- | `dars init --update` | Create/Update dars.config.json in current dir |
133
- | `dars build` | Build using dars.config.json (entry/outdir/format) |
134
- | `dars config validate` | Validate dars.config.json and print report |
135
- | `dars info my_app.py` | Show info about your app |
136
- | `dars formats` | List supported export formats |
137
- | `dars --help` | Show help and all CLI options |
138
-
139
- ## More
140
-
141
- - Visit dars [official website](https://ztamdev.github.io/Dars-Framework/)
142
- - Visit the dars official [Documentation](https://ztamdev.github.io/Dars-Framework/documentation.html) now on separate website.
143
- - Try dars without installing nothing just visit the [Dars Playground](https://dars-playground.vercel.app/)
144
-
145
- ## Local Execution and Live Preview
146
-
147
- To test your app locally before exporting, use the hot-reload preview from any Python file that defines your app:
148
-
149
- ```python
150
- if __name__ == "__main__":
151
- app.rTimeCompile()
152
- ```
153
-
154
- Then run your file directly:
155
-
156
- ```bash
157
- python my_app.py
158
- ```
159
-
160
- 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:
161
-
162
- ```bash
163
- python my_app.py --port 8088
164
- ```
165
-
166
- ---
167
-
168
- You can also use the CLI preview command on an exported app:
169
-
170
- ```bash
171
- dars preview ./my_exported_app
172
- ```
173
-
174
- This will start a local server at http://localhost:8000 to view your exported app in the browser.
175
-
176
- ---
177
-
178
- ## Project Configuration (dars.config.json)
179
-
180
- Dars can read build/export settings from a `dars.config.json` at your project root. It is created automatically by `dars init`, and you can add it to existing projects with `dars init --update`.
181
-
182
- Example default:
183
-
184
- ```json
185
- {
186
- "entry": "main.py",
187
- "format": "html",
188
- "outdir": "dist",
189
- "publicDir": null,
190
- "include": [],
191
- "exclude": ["**/__pycache__", ".git", ".venv", "node_modules"],
192
- "bundle": false
193
- }
194
- ```
195
-
196
- - `entry`: Python entry file. Used by `dars build` and `dars export config`.
197
- - `format`: Export format. Currently only `html` is supported.
198
- - `outdir`: Output directory. Used by `dars build` and default for `dars export` when not overridden.
199
- - `publicDir`: Folder (e.g., `public/` or `assets/`) copied into the output. If null, it is autodetected.
200
- - `include`/`exclude`: Basic filters for copying from `publicDir`.
201
- - `bundle`: Reserved for future use. CLI exports and build already bundle appropriately.
202
-
203
- Validate your config:
204
-
205
- ```bash
206
- dars config validate
207
- ```
208
-
209
- Build using config:
210
-
211
- ```bash
212
- dars build
213
- ```
214
-
215
- Export using the config entry and outdir:
216
-
217
- ```bash
218
- dars export config --format html
219
- ```
220
-
17
+ Try dars without installing nothing just visit the [Dars Playground](https://dars-playground.vercel.app/)
18
+
19
+ ## How It Works
20
+ - Build your UI using Python classes and components (like Text, Button, Container, Page, etc).
21
+ - Preview instantly with hot-reload using `app.rTimeCompile()`.
22
+ - Export your app to static web files with a single CLI command.
23
+ - Use multipage, layouts, scripts, and more—see docs for advanced features.
24
+ - For mor information visit the [Documentation](https://ztamdev.github.io/Dars-Framework/documentation.html)
25
+
26
+ ## Quick Example: Your First App
27
+ ```python
28
+ from dars.all import *
29
+
30
+ app = App(title="Hello World", theme="dark")
31
+ # Crear componentes
32
+ index = Page(
33
+ Text(
34
+ text="Hello World",
35
+ style={
36
+ 'font-size': '48px',
37
+ 'color': '#2c3e50',
38
+ 'margin-bottom': '20px',
39
+ 'font-weight': 'bold',
40
+ 'text-align': 'center'
41
+ }
42
+ ),
43
+ Text(
44
+ text="Hello World",
45
+ style={
46
+ 'font-size': '20px',
47
+ 'color': '#7f8c8d',
48
+ 'margin-bottom': '40px',
49
+ 'text-align': 'center'
50
+ }
51
+ ),
52
+
53
+ Button(
54
+ text="Click Me!",
55
+ on_click= dScript("alert('Hello World')"),
56
+ on_mouse_enter=dScript("this.style.backgroundColor = '#2980b9';"),
57
+ on_mouse_leave=dScript("this.style.backgroundColor = '#3498db';"),
58
+ style={
59
+ 'background-color': '#3498db',
60
+ 'color': 'white',
61
+ 'padding': '15px 30px',
62
+ 'border': 'none',
63
+ 'border-radius': '8px',
64
+ 'font-size': '18px',
65
+ 'cursor': 'pointer',
66
+ 'transition': 'background-color 0.3s'
67
+ }
68
+ ),
69
+ style={
70
+ 'display': 'flex',
71
+ 'flex-direction': 'column',
72
+ 'align-items': 'center',
73
+ 'justify-content': 'center',
74
+ 'min-height': '100vh',
75
+ 'background-color': '#f0f2f5',
76
+ 'font-family': 'Arial, sans-serif'
77
+ }
78
+ )
79
+ index.attr()
80
+ app.add_page("index", index, title="Hello World", index=True)
81
+
82
+ if __name__ == "__main__":
83
+ app.rTimeCompile()
84
+
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Reactivity and State System
90
+
91
+ **Dars Framework** includes a built-in **reactive state system** (`dState` / `cState`) that allows dynamic and modular DOM updates directly from Python.
92
+ It enables fully event-driven interfaces without requiring manual JavaScript.
93
+
94
+ ### Key Concepts
95
+
96
+ * **`dState(name, component, states)`**
97
+ Creates a reactive state controller bound to a specific component and a list of possible states.
98
+
99
+ * **`cState(idx, mods=[...])`**
100
+ Defines rules (modifications) that are automatically applied when entering a specific state.
101
+
102
+ * **`Mod` Helpers**
103
+ A compact way to modify DOM elements on state changes: `inc`, `dec`, `set`, `toggle_class`, `append_text`, `prepend_text`, `goto`, and more.
104
+
105
+ * **Deferred Mutations**
106
+ Using `component.attr(..., defer=True)` or `component.mod(...)` inside a `cComp=True` state defers HTML updates until an event occurs, preventing authoring-time mutations.
107
+
108
+ ### Example Template
109
+
110
+ A complete example demonstrating `dState`, `cState`, `Mod`, and deferred updates is available [here](https://github.com/ZtaMDev/Dars-Framework/blob/CrystalMain/dars/templates/examples/advanced/dState/state_mods_demo.py)
111
+
112
+ <img width="384" height="187" alt="imagen" src="https://github.com/user-attachments/assets/7750ee7f-768f-48da-94df-2fa00339a99c" /> <img width="361" height="215" alt="imagen" src="https://github.com/user-attachments/assets/9b8a3e67-2424-49b4-aee0-9f1c0f747d66" />
113
+
114
+
115
+
116
+ ### Features
117
+
118
+ * Reactive Mod system with compact `Mod` helpers
119
+ * Unified event model — any component can use `on_*` props (`on_click`, `on_input`, `on_change`, etc.)
120
+ * Deferred rendering for safer, predictable state transitions (`cComp=True`)
121
+ * Navigation between states using `goto`, including relative moves (`'+1'`, `'-1'`)
122
+ * Consistent, event-time mutation flow for reliable behavior
123
+
124
+ ---
125
+
126
+ ## CLI Usage
127
+ | Command | What it does |
128
+ |-----------------------------------------|--------------------------------------------|
129
+ | `dars export my_app.py --format html` | Export app to HTML/CSS/JS in `./my_app_web` |
130
+ | `dars preview ./my_app_web` | Preview exported app locally |
131
+ | `dars init my_project` | Create a new Dars project (also creates dars.config.json) |
132
+ | `dars init --update` | Create/Update dars.config.json in current dir |
133
+ | `dars build` | Build using dars.config.json (entry/outdir/format) |
134
+ | `dars config validate` | Validate dars.config.json and print report |
135
+ | `dars info my_app.py` | Show info about your app |
136
+ | `dars formats` | List supported export formats |
137
+ | `dars --help` | Show help and all CLI options |
138
+
139
+ ## More
140
+
141
+ - Visit dars [official website](https://ztamdev.github.io/Dars-Framework/)
142
+ - Visit the dars official [Documentation](https://ztamdev.github.io/Dars-Framework/documentation.html) now on separate website.
143
+ - Try dars without installing nothing just visit the [Dars Playground](https://dars-playground.vercel.app/)
144
+
145
+ ## Local Execution and Live Preview
146
+
147
+ To test your app locally before exporting, use the hot-reload preview from any Python file that defines your app:
148
+
149
+ ```python
150
+ if __name__ == "__main__":
151
+ app.rTimeCompile()
152
+ ```
153
+
154
+ Then run your file directly:
155
+
156
+ ```bash
157
+ python my_app.py
158
+ ```
159
+
160
+ 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:
161
+
162
+ ```bash
163
+ python my_app.py --port 8088
164
+ ```
165
+
166
+ ---
167
+
168
+ You can also use the CLI preview command on an exported app:
169
+
170
+ ```bash
171
+ dars preview ./my_exported_app
172
+ ```
173
+
174
+ This will start a local server at http://localhost:8000 to view your exported app in the browser.
175
+
176
+ ---
177
+
178
+ ## Project Configuration (dars.config.json)
179
+
180
+ Dars can read build/export settings from a `dars.config.json` at your project root. It is created automatically by `dars init`, and you can add it to existing projects with `dars init --update`.
181
+
182
+ Example default:
183
+
184
+ ```json
185
+ {
186
+ "entry": "main.py",
187
+ "format": "html",
188
+ "outdir": "dist",
189
+ "publicDir": null,
190
+ "include": [],
191
+ "exclude": ["**/__pycache__", ".git", ".venv", "node_modules"],
192
+ "bundle": false
193
+ }
194
+ ```
195
+
196
+ - `entry`: Python entry file. Used by `dars build` and `dars export config`.
197
+ - `format`: Export format. Currently only `html` is supported.
198
+ - `outdir`: Output directory. Used by `dars build` and default for `dars export` when not overridden.
199
+ - `publicDir`: Folder (e.g., `public/` or `assets/`) copied into the output. If null, it is autodetected.
200
+ - `include`/`exclude`: Basic filters for copying from `publicDir`.
201
+ - `bundle`: Reserved for future use. CLI exports and build already bundle appropriately.
202
+
203
+ Validate your config:
204
+
205
+ ```bash
206
+ dars config validate
207
+ ```
208
+
209
+ Build using config:
210
+
211
+ ```bash
212
+ dars build
213
+ ```
214
+
215
+ Export using the config entry and outdir:
216
+
217
+ ```bash
218
+ dars export config --format html
219
+ ```
220
+
221
+
222
+ ---
223
+
224
+ ## What's new in v1.2.2
225
+
226
+ Highlights:
227
+
228
+ - Cross-dState calls with `Mod.call(...)` to trigger other states.
229
+ - Immutable default state (index `0`) that restores the component's initial DOM when activated.
230
+ - `Mod.set` accepts multiple attributes and `on_*` event arrays (mix InlineScript, FileScript, dScript, or JS strings), executed sequentially.
231
+ - State bootstrap now serializes embedded scripts safely; runtime reconstitutes them.
232
+
233
+ Upgrade:
234
+
235
+ ```bash
236
+ pip install --upgrade dars-framework
237
+ ```
238
+
239
+ See LandingPage docs for details: state_management.md, events.md, scripts.md.
@@ -20,6 +20,12 @@ class DarsState:
20
20
  "states": self.states,
21
21
  "isCustom": self.is_custom,
22
22
  }
23
+ try:
24
+ d["defaultIndex"] = 0
25
+ d["defaultValue"] = (self.states[0] if isinstance(self.states, list) and len(self.states) > 0 else None)
26
+ except Exception:
27
+ d["defaultIndex"] = 0
28
+ d["defaultValue"] = None
23
29
  if self.rules:
24
30
  d["rules"] = self.rules
25
31
  return d
@@ -96,6 +102,11 @@ class DarsState:
96
102
  # --- cState: define rules/mods for a given state index ---
97
103
  def cState(self, idx: int, mods: Optional[List[Dict[str, Any]]] = None) -> 'CStateRuleBuilder':
98
104
  key = str(idx)
105
+ if idx == 0:
106
+ raise ValueError(
107
+ "Default state (index 0) is immutable. Do not define cState(0). "
108
+ "Configure the component's default directly on the instance instead."
109
+ )
99
110
  if key not in self.rules:
100
111
  self.rules[key] = {}
101
112
  if mods:
@@ -154,6 +165,40 @@ class Mod:
154
165
  tid = getattr(target, 'id', None) or str(target)
155
166
  return {"op": "prependText", "target": tid, "value": value}
156
167
 
168
+ @staticmethod
169
+ def call(target: Any, state: Any = None, goto: Any = None) -> Dict[str, Any]:
170
+ """Invoke another dState's state change.
171
+ - target: DarsState instance or state name string; if a component is passed, use its id.
172
+ - state: target state index/value.
173
+ - goto: relative/absolute goto directive (e.g., '+1').
174
+ The runtime will resolve the state by name first (registry), falling back to id.
175
+ """
176
+ name: Optional[str] = None
177
+ sid: Optional[str] = None
178
+ try:
179
+ # DarsState instance
180
+ if hasattr(target, 'name') and hasattr(target, 'id'):
181
+ name = getattr(target, 'name', None)
182
+ sid = getattr(target, 'id', None)
183
+ elif isinstance(target, str):
184
+ name = target
185
+ else:
186
+ # Maybe a component; try id
187
+ sid = getattr(target, 'id', None) or str(target)
188
+ except Exception:
189
+ name = None
190
+ sid = None
191
+ d: Dict[str, Any] = {"op": "call"}
192
+ if name:
193
+ d['name'] = name
194
+ if sid:
195
+ d['id'] = sid
196
+ if state is not None:
197
+ d['state'] = state
198
+ if goto is not None:
199
+ d['goto'] = goto
200
+ return d
201
+
157
202
 
158
203
  class CStateRuleBuilder:
159
204
  def __init__(self, st: DarsState, key: str):
@@ -214,6 +259,15 @@ class CStateRuleBuilder:
214
259
  self.st._bootstrap_ref['rules'][self.key] = self.st.rules[self.key]
215
260
  return self
216
261
 
262
+ def call(self, target: Any, state: Any = None, goto: Any = None) -> 'CStateRuleBuilder':
263
+ """Append a cross-state call op to this rule."""
264
+ self._ensure()
265
+ self.st.rules[self.key]['mods'].append(Mod.call(target, state=state, goto=goto))
266
+ if self.st._bootstrap_ref is not None:
267
+ self.st._bootstrap_ref.setdefault('rules', {})
268
+ self.st._bootstrap_ref['rules'][self.key] = self.st.rules[self.key]
269
+ return self
270
+
217
271
  def goto(self, value: Any) -> 'CStateRuleBuilder':
218
272
  if self.key not in self.st.rules:
219
273
  self.st.rules[self.key] = {}
@@ -640,7 +640,26 @@ self.addEventListener('fetch', event => {
640
640
  from dars.core.state import STATE_BOOTSTRAP
641
641
  if STATE_BOOTSTRAP:
642
642
  import json as _json
643
- bootstrap_json = _json.dumps(STATE_BOOTSTRAP, ensure_ascii=False)
643
+ from copy import deepcopy as _deepcopy
644
+ try:
645
+ from dars.scripts.script import Script as _Script
646
+ except Exception:
647
+ _Script = None
648
+
649
+ def _ser(v):
650
+ try:
651
+ if _Script and isinstance(v, _Script):
652
+ return {"code": v.get_code()}
653
+ if isinstance(v, dict):
654
+ return {k: _ser(val) for k, val in v.items()}
655
+ if isinstance(v, list):
656
+ return [_ser(x) for x in v]
657
+ return v
658
+ except Exception:
659
+ return v
660
+
661
+ _clean = _ser(_deepcopy(STATE_BOOTSTRAP))
662
+ bootstrap_json = _json.dumps(_clean, ensure_ascii=False)
644
663
  if bundle:
645
664
  # Obfuscate: base64-encode the bootstrap JSON
646
665
  import base64 as _b64
@@ -1798,6 +1817,10 @@ body {
1798
1817
  if(id && eventMap.has(id)){
1799
1818
  const handlers = eventMap.get(id);
1800
1819
  const h = handlers[eventName];
1820
+ // If there is a dynamic handler attached on this node for the same event, let it handle and skip default
1821
+ if(node && node.__darsEv && node.__darsEv[eventName]){
1822
+ return;
1823
+ }
1801
1824
  if(typeof h === 'function'){
1802
1825
  try { h.call(node, e); } catch(err){ console.error('[Dars] handler error', err); }
1803
1826
  return;