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.
- {dars_framework-1.2.1/dars_framework.egg-info → dars_framework-1.2.2}/PKG-INFO +3 -3
- {dars_framework-1.2.1 → dars_framework-1.2.2}/README.md +223 -204
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/core/state.py +54 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/web/html_css_js.py +24 -1
- dars_framework-1.2.2/dars/js_lib.py +206 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/version.py +2 -2
- {dars_framework-1.2.1 → dars_framework-1.2.2/dars_framework.egg-info}/PKG-INFO +3 -3
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars_framework.egg-info/requires.txt +1 -1
- {dars_framework-1.2.1 → dars_framework-1.2.2}/pyproject.toml +3 -5
- dars_framework-1.2.1/dars/js_lib.py +0 -133
- {dars_framework-1.2.1 → dars_framework-1.2.2}/LICENSE +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/MANIFEST.in +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/all.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/cli/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/cli/hot_reload.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/cli/main.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/cli/preview.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/cli/translations.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/accordion.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/card.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/modal.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/navbar.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/table.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/advanced/tabs.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/button.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/checkbox.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/container.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/datepicker.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/image.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/input.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/link.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/markdown.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/page.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/progressbar.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/radiobutton.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/select.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/slider.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/spinner.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/text.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/textarea.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/basic/tooltip.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/layout/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/layout/anchor.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/layout/flex.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/components/layout/grid.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/config.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/core/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/core/app.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/core/component.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/core/events.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/core/properties.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/apps_test/health_check.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/run_tests.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/tests/test_advanced_components.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/tests/test_basic_components.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/tests/test_core_and_cli.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/tests/test_layout_components.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/dars_tests/tests/test_version_check.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/app.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/cli.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/components.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/custom_components.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/events.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/exporters.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/getting_started.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/index.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/scripts.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/docs/state_management.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/base.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/web/OLD/html_css_js_OLD4.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/web/OLD/html_css_js_old.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/web/OLD/html_css_js_old2.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/web/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/exporters/web/vdom.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/scripts/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/scripts/dscript.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/scripts/script.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/security.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/__pycache__/__init__.cpython-311.pyc +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/README.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/__pycache__/dynamic_event_demo.cpython-311.pyc +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/Modal_Demo/advanced_modal_demo.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/SimpleDashboard/dashboard.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/SimpleModermWeb/modern_web_app.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/VariousComponents/all_components_demo.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/index.html +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/lib/dars.min.js +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/runtime_css.css +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/runtime_dars.js +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/script.js +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/snapshot.json +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/styles.css +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/vdom_tree.js +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/dars_preview/version.txt +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/advanced/dState/state_mods_demo.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/Forms/form_components.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/Forms/simple_form.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/HelloWorld/hello_world.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/Layouts/flex_layout_responsive.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/Layouts/grid_layout_responsive.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/Layouts/layout_multipage_demo.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/Multipage/multipage_example.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/PWA/icon-192x192.png +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/PWA/icon-512x512.png +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/PWA/pwa_custom_icons.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/basic/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/demo/__pycache__/complete_app.cpython-311.pyc +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/demo/complete_app.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/markdown/MarkdownTemplate/README.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/markdown/MarkdownTemplate/markdown_template.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/markdown/MarkdownTemplate/other_docs.md +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/examples/markdown/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars/templates/html/__init__.py +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars_framework.egg-info/SOURCES.txt +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars_framework.egg-info/dependency_links.txt +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars_framework.egg-info/entry_points.txt +0 -0
- {dars_framework-1.2.1 → dars_framework-1.2.2}/dars_framework.egg-info/top_level.txt +0 -0
- {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.
|
|
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.
|
|
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
|
-
|
|
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;
|