dars-framework 1.2.3__py3-none-any.whl

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 (118) hide show
  1. dars/__init__.py +0 -0
  2. dars/all.py +69 -0
  3. dars/cli/__init__.py +0 -0
  4. dars/cli/doctor/__init__.py +1 -0
  5. dars/cli/doctor/detect.py +154 -0
  6. dars/cli/doctor/doctor.py +176 -0
  7. dars/cli/doctor/installers.py +100 -0
  8. dars/cli/doctor/persist.py +62 -0
  9. dars/cli/doctor/preflight.py +33 -0
  10. dars/cli/doctor/ui.py +54 -0
  11. dars/cli/hot_reload.py +33 -0
  12. dars/cli/main.py +1107 -0
  13. dars/cli/preview.py +448 -0
  14. dars/cli/translations.py +531 -0
  15. dars/components/__init__.py +0 -0
  16. dars/components/advanced/__init__.py +8 -0
  17. dars/components/advanced/accordion.py +26 -0
  18. dars/components/advanced/card.py +33 -0
  19. dars/components/advanced/modal.py +45 -0
  20. dars/components/advanced/navbar.py +44 -0
  21. dars/components/advanced/table.py +25 -0
  22. dars/components/advanced/tabs.py +31 -0
  23. dars/components/basic/__init__.py +34 -0
  24. dars/components/basic/button.py +55 -0
  25. dars/components/basic/checkbox.py +35 -0
  26. dars/components/basic/container.py +29 -0
  27. dars/components/basic/datepicker.py +139 -0
  28. dars/components/basic/image.py +36 -0
  29. dars/components/basic/input.py +57 -0
  30. dars/components/basic/link.py +31 -0
  31. dars/components/basic/markdown.py +86 -0
  32. dars/components/basic/page.py +20 -0
  33. dars/components/basic/progressbar.py +18 -0
  34. dars/components/basic/radiobutton.py +35 -0
  35. dars/components/basic/select.py +82 -0
  36. dars/components/basic/slider.py +63 -0
  37. dars/components/basic/spinner.py +12 -0
  38. dars/components/basic/text.py +23 -0
  39. dars/components/basic/textarea.py +46 -0
  40. dars/components/basic/tooltip.py +19 -0
  41. dars/components/layout/__init__.py +0 -0
  42. dars/components/layout/anchor.py +13 -0
  43. dars/components/layout/flex.py +26 -0
  44. dars/components/layout/grid.py +45 -0
  45. dars/config.py +134 -0
  46. dars/core/__init__.py +0 -0
  47. dars/core/app.py +957 -0
  48. dars/core/component.py +284 -0
  49. dars/core/events.py +102 -0
  50. dars/core/js_bridge.py +99 -0
  51. dars/core/properties.py +127 -0
  52. dars/core/state.py +309 -0
  53. dars/dars_tests/apps_test/health_check.py +56 -0
  54. dars/dars_tests/run_tests.py +275 -0
  55. dars/dars_tests/tests/test_advanced_components.py +69 -0
  56. dars/dars_tests/tests/test_basic_components.py +88 -0
  57. dars/dars_tests/tests/test_core_and_cli.py +17 -0
  58. dars/dars_tests/tests/test_layout_components.py +58 -0
  59. dars/dars_tests/tests/test_version_check.py +21 -0
  60. dars/docs/__init__.py +0 -0
  61. dars/docs/app.md +290 -0
  62. dars/docs/cli.md +80 -0
  63. dars/docs/components.md +1679 -0
  64. dars/docs/custom_components.md +30 -0
  65. dars/docs/events.md +45 -0
  66. dars/docs/exporters.md +162 -0
  67. dars/docs/getting_started.md +79 -0
  68. dars/docs/index.md +18 -0
  69. dars/docs/scripts.md +593 -0
  70. dars/docs/state_management.md +57 -0
  71. dars/exporters/__init__.py +0 -0
  72. dars/exporters/base.py +96 -0
  73. dars/exporters/web/OLD/html_css_js_OLD4.py +1538 -0
  74. dars/exporters/web/OLD/html_css_js_old.py +1406 -0
  75. dars/exporters/web/OLD/html_css_js_old2.py +1406 -0
  76. dars/exporters/web/__init__.py +0 -0
  77. dars/exporters/web/html_css_js.py +2675 -0
  78. dars/exporters/web/vdom.py +251 -0
  79. dars/js_lib.py +206 -0
  80. dars/scripts/__init__.py +0 -0
  81. dars/scripts/dscript.py +26 -0
  82. dars/scripts/script.py +39 -0
  83. dars/security.py +195 -0
  84. dars/templates/__init__.py +0 -0
  85. dars/templates/__pycache__/__init__.cpython-311.pyc +0 -0
  86. dars/templates/examples/README.md +4 -0
  87. dars/templates/examples/__pycache__/dynamic_event_demo.cpython-311.pyc +0 -0
  88. dars/templates/examples/advanced/Modal_Demo/advanced_modal_demo.py +275 -0
  89. dars/templates/examples/advanced/SimpleDashboard/dashboard.py +437 -0
  90. dars/templates/examples/advanced/SimpleModermWeb/modern_web_app.py +452 -0
  91. dars/templates/examples/advanced/VariousComponents/all_components_demo.py +87 -0
  92. dars/templates/examples/advanced/__init__.py +0 -0
  93. dars/templates/examples/advanced/dState/state_mods_demo.py +68 -0
  94. dars/templates/examples/basic/Forms/form_components.py +516 -0
  95. dars/templates/examples/basic/Forms/simple_form.py +379 -0
  96. dars/templates/examples/basic/HelloWorld/hello_world.py +56 -0
  97. dars/templates/examples/basic/Layouts/flex_layout_responsive.py +13 -0
  98. dars/templates/examples/basic/Layouts/grid_layout_responsive.py +12 -0
  99. dars/templates/examples/basic/Layouts/layout_multipage_demo.py +23 -0
  100. dars/templates/examples/basic/Multipage/multipage_example.py +67 -0
  101. dars/templates/examples/basic/PWA/icon-192x192.png +0 -0
  102. dars/templates/examples/basic/PWA/icon-512x512.png +0 -0
  103. dars/templates/examples/basic/PWA/pwa_custom_icons.py +33 -0
  104. dars/templates/examples/basic/__init__.py +0 -0
  105. dars/templates/examples/demo/__pycache__/complete_app.cpython-311.pyc +0 -0
  106. dars/templates/examples/demo/complete_app.py +21 -0
  107. dars/templates/examples/markdown/MarkdownTemplate/README.md +159 -0
  108. dars/templates/examples/markdown/MarkdownTemplate/markdown_template.py +21 -0
  109. dars/templates/examples/markdown/MarkdownTemplate/other_docs.md +1 -0
  110. dars/templates/examples/markdown/__init__.py +0 -0
  111. dars/templates/html/__init__.py +0 -0
  112. dars/version.py +2 -0
  113. dars_framework-1.2.3.dist-info/METADATA +15 -0
  114. dars_framework-1.2.3.dist-info/RECORD +118 -0
  115. dars_framework-1.2.3.dist-info/WHEEL +5 -0
  116. dars_framework-1.2.3.dist-info/entry_points.txt +2 -0
  117. dars_framework-1.2.3.dist-info/licenses/LICENSE +21 -0
  118. dars_framework-1.2.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,69 @@
1
+ import importlib, inspect, sys, os
2
+ from dars.core.component import Component
3
+ from dars.components.basic.text import Text
4
+
5
+ project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'dars'))
6
+ if project_root not in sys.path:
7
+ sys.path.insert(0, project_root)
8
+
9
+ failures = []
10
+
11
+ def test_advanced_components():
12
+ base_pkg = 'dars.components.advanced'
13
+ try:
14
+ pkg = importlib.import_module(base_pkg)
15
+ except Exception as e:
16
+ raise AssertionError(f'Could not import {base_pkg}: {e}')
17
+
18
+ pkg_path = os.path.dirname(pkg.__file__)
19
+ for fname in os.listdir(pkg_path):
20
+ if not fname.endswith('.py') or fname.startswith('__'):
21
+ continue
22
+
23
+ modname = f"{base_pkg}.{fname[:-3]}"
24
+ try:
25
+ m = importlib.import_module(modname)
26
+ except Exception as e:
27
+ failures.append((modname, 'import', repr(e)))
28
+ continue
29
+
30
+ for _name, obj in inspect.getmembers(m, inspect.isclass):
31
+ try:
32
+ if obj is Component:
33
+ continue
34
+ if issubclass(obj, Component):
35
+ # Proporciona argumentos específicos para cada componente avanzado
36
+ if _name == 'Accordion':
37
+ instance = obj(sections=[{'title': 'Test', 'content': 'Content'}])
38
+ elif _name == 'Table':
39
+ instance = obj(columns=['Col1'], data=[['Data1']])
40
+ elif _name == 'Tabs':
41
+ instance = obj(tabs=['Tab1'], panels=[Text('Panel1')])
42
+ elif _name == 'Card':
43
+ instance = obj(title='Test Card')
44
+ elif _name == 'Modal':
45
+ instance = obj(title='Test Modal')
46
+ elif _name == 'Navbar':
47
+ instance = obj(brand='Test Navbar')
48
+ else:
49
+ # Intenta con argumentos mínimos para otros componentes
50
+ try:
51
+ instance = obj()
52
+ except TypeError:
53
+ instance = obj(id='test')
54
+
55
+ # Verifica que la instancia se creó correctamente
56
+ assert instance is not None, f"Failed to create instance of {_name}"
57
+
58
+ except Exception as e:
59
+ failures.append((f"{modname}.{_name}", 'init', repr(e)))
60
+
61
+ assert not failures, failures
62
+
63
+ if __name__ == '__main__':
64
+ try:
65
+ test_advanced_components()
66
+ print('test_advanced_components: OK')
67
+ except AssertionError as e:
68
+ print('test_advanced_components: FAIL', e)
69
+ sys.exit(1)
@@ -0,0 +1,88 @@
1
+ import importlib, inspect, sys, os
2
+ from dars.core.component import Component
3
+
4
+ project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'dars'))
5
+ if project_root not in sys.path:
6
+ sys.path.insert(0, project_root)
7
+
8
+ failures = []
9
+
10
+ def test_basic_components():
11
+ base_pkg = 'dars.components.basic'
12
+ try:
13
+ pkg = importlib.import_module(base_pkg)
14
+ except Exception as e:
15
+ failures.append((base_pkg, 'import', repr(e)))
16
+ return
17
+
18
+ pkg_path = os.path.dirname(pkg.__file__)
19
+ for fname in os.listdir(pkg_path):
20
+ if not fname.endswith('.py') or fname.startswith('__'):
21
+ continue
22
+
23
+ modname = f"{base_pkg}.{fname[:-3]}"
24
+ try:
25
+ m = importlib.import_module(modname)
26
+ except Exception as e:
27
+ failures.append((modname, 'import', repr(e)))
28
+ continue
29
+
30
+ for _name, obj in inspect.getmembers(m, inspect.isclass):
31
+ try:
32
+ if obj is Component:
33
+ continue
34
+ if issubclass(obj, Component):
35
+ # Proporciona argumentos específicos para cada componente
36
+ if _name == 'Image':
37
+ instance = obj(src='test.png')
38
+ elif _name == 'Link':
39
+ instance = obj(text='Test', href='#')
40
+ elif _name == 'Markdown':
41
+ instance = obj(content='# Test')
42
+ elif _name == 'ProgressBar':
43
+ instance = obj(value=50)
44
+ elif _name == 'Tooltip':
45
+ from dars.components.basic.text import Text
46
+ instance = obj(text='Tip', child=Text('Hover me'))
47
+ elif _name == 'Button':
48
+ instance = obj(text='Test Button')
49
+ elif _name == 'Input':
50
+ instance = obj()
51
+ elif _name == 'Textarea':
52
+ instance = obj()
53
+ elif _name == 'Checkbox':
54
+ instance = obj(label='Test Checkbox')
55
+ elif _name == 'RadioButton':
56
+ instance = obj(label='Test Radio', name='test_radio')
57
+ elif _name == 'Select':
58
+ instance = obj(options=[{'value': 'test', 'label': 'Test'}])
59
+ elif _name == 'Slider':
60
+ instance = obj()
61
+ elif _name == 'DatePicker':
62
+ instance = obj()
63
+ elif _name == 'Container':
64
+ instance = obj()
65
+ elif _name == 'Text':
66
+ instance = obj(text='Test Text')
67
+ else:
68
+ # Intenta con argumentos mínimos para otros componentes
69
+ try:
70
+ instance = obj()
71
+ except TypeError:
72
+ instance = obj(id='test', class_name='c', style={})
73
+
74
+ # Verifica que la instancia se creó correctamente
75
+ assert instance is not None, f"Failed to create instance of {_name}"
76
+
77
+ except Exception as e:
78
+ failures.append((f"{modname}.{_name}", 'init', repr(e)))
79
+
80
+ assert not failures, failures
81
+
82
+ if __name__ == '__main__':
83
+ try:
84
+ test_basic_components()
85
+ print('test_basic_components: OK')
86
+ except AssertionError as e:
87
+ print('test_basic_components: FAIL', e)
88
+ sys.exit(1)
@@ -0,0 +1,17 @@
1
+ import importlib, sys, os
2
+ project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'dars'))
3
+ if project_root not in sys.path:
4
+ sys.path.insert(0, project_root)
5
+
6
+ def test_core_imports():
7
+ import dars.core.app as app
8
+ import dars.core.component as component
9
+ import dars.cli.main as cli_main
10
+ # smoke tests: ensure some expected names exist
11
+ assert hasattr(app, 'App') or hasattr(app, 'Page'), 'app module missing App/Page'
12
+ assert hasattr(component, 'Component'), 'component missing Component'
13
+ assert hasattr(cli_main, 'main') or hasattr(cli_main, 'run'), 'cli main missing entrypoint'
14
+ print('core_and_cli: OK')
15
+
16
+ if __name__ == '__main__':
17
+ test_core_imports()
@@ -0,0 +1,58 @@
1
+ import importlib, inspect, sys, os
2
+ from dars.core.component import Component
3
+
4
+ project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'dars'))
5
+ if project_root not in sys.path:
6
+ sys.path.insert(0, project_root)
7
+
8
+ failures = []
9
+
10
+ def test_layout_components():
11
+ base_pkg = 'dars.components.layout'
12
+ try:
13
+ pkg = importlib.import_module(base_pkg)
14
+ except Exception as e:
15
+ raise AssertionError(f'Could not import {base_pkg}: {e}')
16
+
17
+ pkg_path = os.path.dirname(pkg.__file__)
18
+ for fname in os.listdir(pkg_path):
19
+ if not fname.endswith('.py') or fname.startswith('__'):
20
+ continue
21
+
22
+ modname = f"{base_pkg}.{fname[:-3]}"
23
+ try:
24
+ m = importlib.import_module(modname)
25
+ except Exception as e:
26
+ failures.append((modname, 'import', repr(e)))
27
+ continue
28
+
29
+ for _name, obj in inspect.getmembers(m, inspect.isclass):
30
+ try:
31
+ if obj is Component:
32
+ continue
33
+ if issubclass(obj, Component):
34
+ # Intenta crear una instancia con argumentos mínimos
35
+ try:
36
+ instance = obj()
37
+ except TypeError:
38
+ try:
39
+ instance = obj(id='test')
40
+ except Exception as e:
41
+ failures.append((f"{modname}.{_name}", 'init', repr(e)))
42
+
43
+ # Verifica que la instancia se creó correctamente
44
+ if 'instance' in locals():
45
+ assert instance is not None, f"Failed to create instance of {_name}"
46
+
47
+ except Exception as e:
48
+ failures.append((f"{modname}.{_name}", 'inspect', repr(e)))
49
+
50
+ assert not failures, failures
51
+
52
+ if __name__ == '__main__':
53
+ try:
54
+ test_layout_components()
55
+ print('test_layout_components: OK')
56
+ except AssertionError as e:
57
+ print('test_layout_components: FAIL', e)
58
+ sys.exit(1)
@@ -0,0 +1,21 @@
1
+ import importlib, sys, os
2
+ project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'dars'))
3
+ if project_root not in sys.path:
4
+ sys.path.insert(0, project_root)
5
+ import dars.version as ver
6
+
7
+ # Latest version observed on PyPI / mirrors during analysis: 1.1.3
8
+ LATEST_KNOWN = '1.1.3'
9
+
10
+ def test_version_comparison():
11
+ local = getattr(ver, '__version__', None)
12
+ assert local is not None, 'local version not found in dars.version'
13
+ print(f'local_version={local}; latest_known={LATEST_KNOWN}')
14
+ # The test will not fail if local is newer (dev), but will warn via printing when local differs.
15
+ if local != LATEST_KNOWN:
16
+ print('WARNING: local package version differs from LATEST_KNOWN (see test output).')
17
+ else:
18
+ print('version_check: OK')
19
+
20
+ if __name__ == '__main__':
21
+ test_version_comparison()
dars/docs/__init__.py ADDED
File without changes
dars/docs/app.md ADDED
@@ -0,0 +1,290 @@
1
+ # App Class and PWA Features in Dars Framework
2
+
3
+ ## Overview
4
+
5
+ The `App` class is the core of any Dars Framework application. It represents the complete application and manages all configuration, components, pages, and functionalities, including Progressive Web App (PWA) support.
6
+
7
+ ## Basic Structure
8
+
9
+ ```python
10
+ class App:
11
+ def __init__(
12
+ self,
13
+ title: str = "Dars App",
14
+ description: str = "",
15
+ author: str = "",
16
+ keywords: List[str] = None,
17
+ language: str = "en",
18
+ favicon: str = "",
19
+ icon: str = "",
20
+ apple_touch_icon: str = "",
21
+ manifest: str = "",
22
+ theme_color: str = "#000000",
23
+ background_color: str = "#ffffff",
24
+ service_worker_path: str = "",
25
+ service_worker_enabled: bool = False,
26
+ **config
27
+ ):
28
+ ```
29
+
30
+ ## Global Styles Management
31
+
32
+ ### Enhanced add_global_style() Method
33
+
34
+ The `App` class now includes an enhanced `add_global_style()` method that supports both inline style definitions and external CSS file imports.
35
+
36
+
37
+ #### Usage Examples
38
+
39
+ **1. Inline Style Definition (Traditional)**
40
+ ```python
41
+ app.add_global_style(
42
+ selector=".my-button",
43
+ styles={
44
+ "background-color": "#4CAF50",
45
+ "color": "white",
46
+ "padding": "10px 20px",
47
+ "border-radius": "5px"
48
+ }
49
+ )
50
+ ```
51
+
52
+ **2. External CSS File Import (New in v1.1.2)**
53
+ ```python
54
+ app.add_global_style(file_path="styles.css")
55
+ ```
56
+
57
+ **3. Combined Usage**
58
+ ```python
59
+ # Add inline styles
60
+ app.add_global_style(
61
+ selector=".primary-btn",
62
+ styles={
63
+ "background-color": "#007bff",
64
+ "color": "white"
65
+ }
66
+ )
67
+
68
+ # Import external CSS file
69
+ app.add_global_style(file_path="components.css")
70
+ ```
71
+
72
+ #### Practical Example with External CSS
73
+
74
+ **main.py:**
75
+ ```python
76
+ from dars.all import *
77
+
78
+ app = App(title="Dars Styling Test")
79
+
80
+ index = Page(
81
+ Container(
82
+ Button("Styled Button", class_name="button-styling-test"),
83
+ id="page_sub_container"
84
+ )
85
+ )
86
+
87
+ app.add_page(name="index", root=index, title="index", index=True)
88
+ app.add_global_style(file_path="styles.css")
89
+
90
+ if __name__ == "__main__":
91
+ app.rTimeCompile(add_file_types=".py, .css")
92
+ ```
93
+
94
+ **styles.css:**
95
+ ```css
96
+ .button-styling-test {
97
+ background-color: rgb(51, 255, 0);
98
+ padding: 15px 30px;
99
+ border-radius: 8px;
100
+ border: none;
101
+ font-weight: bold;
102
+ cursor: pointer;
103
+ }
104
+
105
+ .button-styling-test:hover {
106
+ background-color: rgb(30, 200, 0);
107
+ transform: scale(1.05);
108
+ }
109
+
110
+ #page_sub_container {
111
+ padding: 20px;
112
+ background-color: #f5f5f5;
113
+ min-height: 100vh;
114
+ }
115
+ ```
116
+
117
+ ### Hot Reload for CSS Files
118
+
119
+ When using `app.rTimeCompile()` with the `add_file_types=".css"` parameter, the development server automatically watches for changes in CSS files and reloads the application when modifications are detected.
120
+
121
+ ```python
122
+ # Watch for both Python and CSS file changes
123
+ app.rTimeCompile(add_file_types=".py, .css")
124
+
125
+ # Or watch for CSS files only
126
+ app.rTimeCompile(add_file_types=".css")
127
+ ```
128
+
129
+ ### Benefits of External CSS Import
130
+
131
+ 1. **Separation of Concerns**: Keep styles separate from application logic
132
+ 2. **Better Organization**: Maintain complex stylesheets in dedicated files
133
+ 3. **Team Collaboration**: Designers and developers can work simultaneously
134
+ 4. **CSS Preprocessors**: Use SASS, LESS, or other preprocessors
135
+ 5. **Performance**: Browser caching for external CSS files
136
+
137
+ ### Backward Compatibility
138
+
139
+ The enhanced method maintains full backward compatibility - existing code using `add_global_style(selector, styles)` will continue to work without modification.
140
+
141
+
142
+ ## PWA Configuration Properties
143
+
144
+ The App class includes these PWA-specific properties:
145
+
146
+ ```python
147
+ # Icons and visual resources
148
+ self.favicon = favicon # Path to traditional favicon
149
+ self.icon = icon # Main icon for PWA (multiple sizes)
150
+ self.apple_touch_icon = apple_touch_icon # Icon for Apple devices
151
+ self.manifest = manifest # Path to manifest.json file
152
+
153
+ # Colors and theme
154
+ self.theme_color = theme_color # Theme color (#RRGGBB)
155
+ self.background_color = background_color # Background color for splash screens
156
+
157
+ # Service Worker
158
+ self.service_worker_path = service_worker_path # Path to service worker file
159
+ self.service_worker_enabled = service_worker_enabled # Enable/disable
160
+
161
+ # Additional PWA configuration
162
+ self.pwa_enabled = config.get('pwa_enabled', False)
163
+ self.pwa_name = config.get('pwa_name', title)
164
+ self.pwa_short_name = config.get('pwa_short_name', title[:12])
165
+ self.pwa_display = config.get('pwa_display', 'standalone')
166
+ self.pwa_orientation = config.get('pwa_orientation', 'portrait')
167
+ ```
168
+
169
+ ## Meta Tag Generation for PWA
170
+
171
+ The App class provides methods to generate PWA meta tags:
172
+
173
+ ```python
174
+ def get_meta_tags(self) -> Dict[str, str]:
175
+ """Returns all meta tags as a dictionary"""
176
+ meta_tags = {}
177
+
178
+ # Viewport configured for responsiveness
179
+ viewport_parts = []
180
+ for key, value in self.config['viewport'].items():
181
+ if key == 'initial_scale':
182
+ viewport_parts.append(f'initial-scale={value}')
183
+ elif key == 'user_scalable':
184
+ viewport_parts.append(f'user-scalable={value}')
185
+ else:
186
+ viewport_parts.append(f'{key.replace("_", "-")}={value}')
187
+ meta_tags['viewport'] = ', '.join(viewport_parts)
188
+
189
+ # Specific tags for PWA
190
+ meta_tags['theme-color'] = self.theme_color
191
+ if self.pwa_enabled:
192
+ meta_tags['mobile-web-app-capable'] = 'yes'
193
+ meta_tags['apple-mobile-web-app-capable'] = 'yes'
194
+ meta_tags['apple-mobile-web-app-status-bar-style'] = 'default'
195
+ meta_tags['apple-mobile-web-app-title'] = self.pwa_short_name
196
+
197
+ return meta_tags
198
+ ```
199
+
200
+ ## Integration with HTML/CSS/JS Exporter
201
+
202
+ The `HTMLCSSJSExporter` uses the PWA configuration from the App class to generate:
203
+
204
+ 1. **manifest.json file** - Progressive web app configuration
205
+ 2. **Meta tags** - To indicate PWA capabilities in different browsers
206
+ 3. **Icon references** - For multiple devices and sizes
207
+ 4. **Service Worker registration** - For offline functionality
208
+
209
+ ### Example of Generated Manifest.json
210
+
211
+ ```json
212
+ {
213
+ "name": "App Name",
214
+ "short_name": "Short Name",
215
+ "description": "Application description",
216
+ "start_url": "/",
217
+ "display": "standalone",
218
+ "background_color": "#ffffff",
219
+ "theme_color": "#000000",
220
+ "orientation": "portrait",
221
+ "icons": [
222
+ {
223
+ "src": "icon-192x192.png",
224
+ "sizes": "192x192",
225
+ "type": "image/png"
226
+ },
227
+ {
228
+ "src": "icon-512x512.png",
229
+ "sizes": "512x512",
230
+ "type": "image/png"
231
+ }
232
+ ]
233
+ }
234
+ ```
235
+
236
+ ### Service Worker Registration Script
237
+
238
+ The exporter automatically generates code to register the service worker:
239
+
240
+ ```javascript
241
+ if ('serviceWorker' in navigator && '{service_worker_path}') {
242
+ window.addEventListener('load', function() {
243
+ navigator.serviceWorker.register('{service_worker_path}')
244
+ .then(function(registration) {
245
+ console.log('ServiceWorker registration successful');
246
+ })
247
+ .catch(function(error) {
248
+ console.log('ServiceWorker registration failed: ', error);
249
+ });
250
+ });
251
+ }
252
+ ```
253
+
254
+ ## Complete PWA App Configuration Example
255
+
256
+ ```python
257
+ # Create a complete PWA application
258
+ app = App(
259
+ title="My PWA App",
260
+ description="An amazing progressive application",
261
+ author="My Company",
262
+ keywords=["pwa", "webapp", "productivity"],
263
+ language="en",
264
+ favicon="assets/favicon.ico",
265
+ icon="assets/icon-192x192.png",
266
+ apple_touch_icon="assets/apple-touch-icon.png",
267
+ theme_color="#4A90E2",
268
+ background_color="#FFFFFF",
269
+ service_worker_path="sw.js",
270
+ service_worker_enabled=True,
271
+ pwa_enabled=True,
272
+ pwa_name="My App",
273
+ pwa_short_name="MyApp",
274
+ pwa_display="standalone"
275
+ )
276
+
277
+ # Add pages and components
278
+ app.add_page("home", HomeComponent(), title="Home", index=True)
279
+ app.add_page("about", AboutComponent(), title="About")
280
+ ```
281
+
282
+ ## Implementation Considerations
283
+
284
+ ### Browser Compatibility
285
+
286
+ Dars Framework's PWA implementation is compatible with:
287
+ - Chrome/Chromium (full support)
288
+ - Firefox (basic support)
289
+ - Safari (limited support on iOS)
290
+ - Edge (full support)
dars/docs/cli.md ADDED
@@ -0,0 +1,80 @@
1
+ # Dars CLI Reference
2
+
3
+ The Dars Command Line Interface (CLI) lets you manage your projects, export apps, and preview results quickly from the terminal.
4
+
5
+ ## How to Use the CLI
6
+
7
+ Open your terminal in your project directory and use any of the following commands:
8
+
9
+ ```bash
10
+ # Show information about your app
11
+ dars info my_app.py
12
+
13
+ # Export to different formats
14
+ dars export my_app.py --format html --output ./output
15
+
16
+ # List supported export formats
17
+ dars formats
18
+
19
+ # Initialize a new project
20
+ dars init my_new_project
21
+
22
+ # Initialize a project with a specific template
23
+ dars init my_new_project -t demo/complete_app
24
+
25
+ # Preview an exported app
26
+ dars preview ./output_directory
27
+
28
+ # Help
29
+ dars --help
30
+
31
+ # Version
32
+ dars -v
33
+ ```
34
+
35
+ ## Main Commands Table
36
+ | Command | What it does |
37
+ |-----------------------------------------|--------------------------------------------|
38
+ | `dars export my_app.py --format html` | Export app to HTML/CSS/JS in `./my_app_web` |
39
+ | `dars preview ./my_app_web` | Preview exported app locally |
40
+ | `dars init my_project` | Create a new Dars project |
41
+ | `dars info my_app.py` | Show info about your app |
42
+ | `dars formats` | List supported export formats |
43
+ | `dars --help` | Show help and all CLI options |
44
+
45
+ ## Using Official Templates
46
+
47
+ Dars provides official templates to help you start new projects quickly. Templates include ready-to-use apps for forms, layouts, dashboards, multipage, and more.
48
+
49
+ ### How to Use a Template
50
+
51
+ 1. **Initialize a new project with a template:**
52
+ ```bash
53
+ dars init my_new_project -t basic/HelloWorld
54
+ # ...and more (see below)
55
+ ```
56
+
57
+ You can see the templates available with
58
+
59
+ ```bash
60
+ dars init --list-templates
61
+ dars init -L
62
+ ```
63
+
64
+ 2. **Export the template to HTML/CSS/JS:**
65
+ ```bash
66
+ dars export main.py --format html --output ./hello_output
67
+ dars export main.py --format html --output ./dashboard_output
68
+ # ...etc
69
+ ```
70
+ 3. **Preview the exported app:**
71
+ ```bash
72
+ dars preview ./hello_output
73
+ ```
74
+
75
+ ## Tips
76
+ - Use `dars --help` for a full list of commands and options.
77
+ - You can preview apps either live (with `app.rTimeCompile()`) or from exported files with `dars preview`.
78
+ - Templates are available for quick project setup: use `dars init my_project -t <template>`.
79
+
80
+ For more, see the [Getting Started](getting_started.md) guide and the main documentation index.