dars-framework 1.9.5__tar.gz → 1.9.7__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 (191) hide show
  1. {dars_framework-1.9.5 → dars_framework-1.9.7}/MANIFEST.in +1 -0
  2. {dars_framework-1.9.5/dars_framework.egg-info → dars_framework-1.9.7}/PKG-INFO +29 -6
  3. {dars_framework-1.9.5 → dars_framework-1.9.7}/README.md +28 -5
  4. dars_framework-1.9.7/dars/cli/generate.py +288 -0
  5. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/main.py +132 -30
  6. dars_framework-1.9.7/dars/cli/prompts.py +68 -0
  7. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/button.py +1 -1
  8. dars_framework-1.9.7/dars/docs/index.md +5 -0
  9. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/exporters/web/html_css_js.py +222 -17
  10. dars_framework-1.9.7/dars/exporters/web/resources/anim.js +317 -0
  11. dars_framework-1.9.7/dars/exporters/web/resources/dap.js +417 -0
  12. dars_framework-1.9.7/dars/exporters/web/resources/dars.min.js +1110 -0
  13. dars_framework-1.9.7/dars/exporters/web/resources/dompurify.js +2633 -0
  14. dars_framework-1.9.7/dars/exporters/web/resources/router.js +821 -0
  15. dars_framework-1.9.7/dars/exporters/web/resources/ssr.js +246 -0
  16. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/version.py +2 -2
  17. {dars_framework-1.9.5 → dars_framework-1.9.7/dars_framework.egg-info}/PKG-INFO +29 -6
  18. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars_framework.egg-info/SOURCES.txt +8 -20
  19. {dars_framework-1.9.5 → dars_framework-1.9.7}/pyproject.toml +1 -1
  20. dars_framework-1.9.5/dars/docs/INSTALL.md +0 -164
  21. dars_framework-1.9.5/dars/docs/KeyEvents.md +0 -492
  22. dars_framework-1.9.5/dars/docs/animations.md +0 -199
  23. dars_framework-1.9.5/dars/docs/app.md +0 -344
  24. dars_framework-1.9.5/dars/docs/backend_api.md +0 -363
  25. dars_framework-1.9.5/dars/docs/cli.md +0 -130
  26. dars_framework-1.9.5/dars/docs/components.md +0 -405
  27. dars_framework-1.9.5/dars/docs/config.md +0 -109
  28. dars_framework-1.9.5/dars/docs/custom_components.md +0 -288
  29. dars_framework-1.9.5/dars/docs/env.md +0 -58
  30. dars_framework-1.9.5/dars/docs/events.md +0 -114
  31. dars_framework-1.9.5/dars/docs/exporters.md +0 -322
  32. dars_framework-1.9.5/dars/docs/getting_started.md +0 -96
  33. dars_framework-1.9.5/dars/docs/hooks.md +0 -1335
  34. dars_framework-1.9.5/dars/docs/index.md +0 -52
  35. dars_framework-1.9.5/dars/docs/operations.md +0 -471
  36. dars_framework-1.9.5/dars/docs/routing.md +0 -337
  37. dars_framework-1.9.5/dars/docs/scripts.md +0 -155
  38. dars_framework-1.9.5/dars/docs/ssr.md +0 -448
  39. dars_framework-1.9.5/dars/docs/state_management.md +0 -334
  40. dars_framework-1.9.5/dars/docs/styling.md +0 -499
  41. {dars_framework-1.9.5 → dars_framework-1.9.7}/Dars-logo.png +0 -0
  42. {dars_framework-1.9.5 → dars_framework-1.9.7}/LICENSE +0 -0
  43. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/__init__.py +0 -0
  44. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/actionProtocol.py +0 -0
  45. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/all.py +0 -0
  46. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/__init__.py +0 -0
  47. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/components.py +0 -0
  48. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/data.py +0 -0
  49. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/http.py +0 -0
  50. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/json_utils.py +0 -0
  51. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/route_loader.py +0 -0
  52. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/backend/ssr.py +0 -0
  53. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/__init__.py +0 -0
  54. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/__init__.py +0 -0
  55. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/detect.py +0 -0
  56. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/doctor.py +0 -0
  57. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/installers.py +0 -0
  58. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/persist.py +0 -0
  59. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/preflight.py +0 -0
  60. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/doctor/ui.py +0 -0
  61. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/dpm.py +0 -0
  62. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/hot_reload.py +0 -0
  63. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/preview.py +0 -0
  64. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/cli/translations.py +0 -0
  65. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/__init__.py +0 -0
  66. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/__init__.py +0 -0
  67. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/accordion.py +0 -0
  68. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/card.py +0 -0
  69. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/file_upload.py +0 -0
  70. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/head.py +0 -0
  71. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/modal.py +0 -0
  72. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/navbar.py +0 -0
  73. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/outlet.py +0 -0
  74. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/table.py +0 -0
  75. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/advanced/tabs.py +0 -0
  76. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/__init__.py +0 -0
  77. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/audio.py +0 -0
  78. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/checkbox.py +0 -0
  79. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/container.py +0 -0
  80. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/datepicker.py +0 -0
  81. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/image.py +0 -0
  82. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/input.py +0 -0
  83. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/link.py +0 -0
  84. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/markdown.py +0 -0
  85. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/page.py +0 -0
  86. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/progressbar.py +0 -0
  87. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/radiobutton.py +0 -0
  88. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/section.py +0 -0
  89. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/select.py +0 -0
  90. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/slider.py +0 -0
  91. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/spinner.py +0 -0
  92. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/text.py +0 -0
  93. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/textarea.py +0 -0
  94. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/tooltip.py +0 -0
  95. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/basic/video.py +0 -0
  96. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/layout/__init__.py +0 -0
  97. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/layout/anchor.py +0 -0
  98. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/layout/flex.py +0 -0
  99. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/layout/grid.py +0 -0
  100. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/visualization/__init__.py +0 -0
  101. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/visualization/chart.py +0 -0
  102. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/components/visualization/table.py +0 -0
  103. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/config.py +0 -0
  104. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/__init__.py +0 -0
  105. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/app.py +0 -0
  106. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/component.py +0 -0
  107. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/events.py +0 -0
  108. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/js_bridge.py +0 -0
  109. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/properties.py +0 -0
  110. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/route_types.py +0 -0
  111. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/routing.py +0 -0
  112. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/state.py +0 -0
  113. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/state_v2.py +0 -0
  114. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/core/utilities.py +0 -0
  115. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/apps_test/health_check.py +0 -0
  116. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/run_tests.py +0 -0
  117. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/tests/test_advanced_components.py +0 -0
  118. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/tests/test_basic_components.py +0 -0
  119. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/tests/test_core_and_cli.py +0 -0
  120. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/tests/test_layout_components.py +0 -0
  121. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/dars_tests/tests/test_version_check.py +0 -0
  122. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/desktop/__init__.py +0 -0
  123. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/desktop/api.py +0 -0
  124. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/desktop/js_generator.py +0 -0
  125. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/docs/__init__.py +0 -0
  126. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/env.py +0 -0
  127. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/exporters/__init__.py +0 -0
  128. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/exporters/base.py +0 -0
  129. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/exporters/desktop/electron.py +0 -0
  130. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/exporters/web/__init__.py +0 -0
  131. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/exporters/web/vdom.py +0 -0
  132. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/__init__.py +0 -0
  133. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/form_helpers.py +0 -0
  134. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/set_vref.py +0 -0
  135. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/update_vref.py +0 -0
  136. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/use_dynamic.py +0 -0
  137. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/use_value.py +0 -0
  138. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/use_vref.py +0 -0
  139. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/use_watch.py +0 -0
  140. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/hooks/value_helpers.py +0 -0
  141. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/scripts/__init__.py +0 -0
  142. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/scripts/animations.py +0 -0
  143. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/scripts/dscript.py +0 -0
  144. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/scripts/keycode.py +0 -0
  145. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/scripts/script.py +0 -0
  146. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/scripts/utils_ds.py +0 -0
  147. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/security.py +0 -0
  148. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/__init__.py +0 -0
  149. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/icon.png +0 -0
  150. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/backend/icons/icon.png +0 -0
  151. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/backend/main.js +0 -0
  152. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/backend/package.json +0 -0
  153. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/backend/preload.js +0 -0
  154. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/dars.config.json +0 -0
  155. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/icons/icon.png +0 -0
  156. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/main.py +0 -0
  157. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/public/electron-icon.png +0 -0
  158. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/desktop/template/public/icon.png +0 -0
  159. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/README.md +0 -0
  160. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/CustomComp/main.py +0 -0
  161. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/Modal_Demo/advanced_modal_demo.py +0 -0
  162. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/README.md +0 -0
  163. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/animation_component.py +0 -0
  164. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/counter_component.py +0 -0
  165. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/hero_component.py +0 -0
  166. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/main.py +0 -0
  167. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/styles.css +0 -0
  168. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/StateV2/timer_component.py +0 -0
  169. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/VariousComponents/all_components_demo.py +0 -0
  170. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/__init__.py +0 -0
  171. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/dState/state_mods_demo.py +0 -0
  172. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/hooks/useDynamic.py +0 -0
  173. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/hooks/useValue.py +0 -0
  174. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/advanced/hooks/useWatch.py +0 -0
  175. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/HelloWorld/hello_world.py +0 -0
  176. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/Layouts/flex_layout_responsive.py +0 -0
  177. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/Layouts/grid_layout_responsive.py +0 -0
  178. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/Layouts/layout_multipage_demo.py +0 -0
  179. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/PWA/icon-192x192.png +0 -0
  180. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/PWA/icon-512x512.png +0 -0
  181. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/PWA/pwa_custom_icons.py +0 -0
  182. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/basic/__init__.py +0 -0
  183. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/markdown/MarkdownTemplate/README.md +0 -0
  184. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/markdown/MarkdownTemplate/markdown_template.py +0 -0
  185. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/markdown/MarkdownTemplate/other_docs.md +0 -0
  186. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars/templates/examples/markdown/__init__.py +0 -0
  187. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars_framework.egg-info/dependency_links.txt +0 -0
  188. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars_framework.egg-info/entry_points.txt +0 -0
  189. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars_framework.egg-info/requires.txt +0 -0
  190. {dars_framework-1.9.5 → dars_framework-1.9.7}/dars_framework.egg-info/top_level.txt +0 -0
  191. {dars_framework-1.9.5 → dars_framework-1.9.7}/setup.cfg +0 -0
@@ -5,5 +5,6 @@ recursive-include dars/templates *
5
5
  recursive-include dars/docs *
6
6
  recursive-include dars *.json
7
7
  recursive-include dars *.md
8
+ recursive-include dars/exporters/web/resources *
8
9
  exclude LandingPage
9
10
  exclude tst
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dars-framework
3
- Version: 1.9.5
3
+ Version: 1.9.7
4
4
  Summary: Dars is a Full-Stack multiplatform Python UI framework for building modern, interactive web and desktop apps with Python code. Seamlessly integrated with FastAPI, it allows you to build complete applications with Server-Side Rendering (SSR) and reactive SPA capabilities also classic multipage html and desktop apps in a single codebase.
5
5
  Author-email: ztamdev <ztadevs@gmail.com>
6
6
  Maintainer-email: ztamdev <ztadevs@gmail.com>
@@ -480,7 +480,8 @@ For complete documentation, see the [Backend API Guide](https://ztamdev.github.i
480
480
  | `dars init --type desktop` | Scaffold desktop-capable project (BETA) |
481
481
  | `dars init --type ssr` | Scaffold full-stack SSR project (SSR + API) |
482
482
  | `dars build` (desktop config) | Build desktop app artifacts (BETA) |
483
- | `dars preview ./my_app_web` | Preview exported app locally |
483
+ | `dars preview` | Preview exported app (auto-detects output) |
484
+ | `dars preview --port 9000` | Preview on a custom port |
484
485
  | `dars init my_project` | Create a new Dars project (also creates dars.config.json) |
485
486
  | `dars init --update` | Create/Update dars.config.json in current dir |
486
487
  | `dars build` | Build using dars.config.json (entry/outdir/format) |
@@ -490,6 +491,8 @@ For complete documentation, see the [Backend API Guide](https://ztamdev.github.i
490
491
  | `dars dev` | Run the configured entry file with hot preview (app.rTimeCompile) |
491
492
  | `dars dev --port 9000` | Run dev server on a custom port (overrides config) |
492
493
  | `dars dev --backend` | Run only the configured backendEntry (FastAPI/SSR backend) |
494
+ | `dars generate component <name>` | Scaffold a new FunctionComponent |
495
+ | `dars generate page <name>` | Scaffold a new page (static or SPA) |
493
496
  | `dars --help` | Show help and all CLI options |
494
497
 
495
498
  Tip: use `dars doctor` to review optional tooling that can enhance bundling/minification.
@@ -501,6 +504,22 @@ Tip: use `dars doctor` to review optional tooling that can enhance bundling/mini
501
504
  - Build with `dars build` to produce desktop artifacts under `dist/`.
502
505
  - This feature is in BETA: usable for testing, not yet recommended for production.
503
506
 
507
+ ### Code Generation
508
+
509
+ Scaffold new components and pages instantly with automatic project integration.
510
+
511
+ ```bash
512
+ # Generate a new FunctionComponent
513
+ dars generate component MyComponent
514
+
515
+ # Generate a new Page (Static, SPA or SSR)
516
+ dars generate page About --page-type spa
517
+ dars generate page Dashboard --page-type ssr
518
+
519
+ # Scaffold and auto-inject into your main.py file
520
+ dars generate page Contact --yes
521
+ ```
522
+
504
523
  ---
505
524
 
506
525
  - Visit dars [official website](https://ztamdev.github.io/Dars-Framework/)
@@ -530,13 +549,17 @@ python my_app.py --port 8088
530
549
 
531
550
  ---
532
551
 
533
- You can also use the CLI preview command on an exported app:
552
+ You can also use the CLI preview command on an exported app. Starting from v1.9.6, the path is optional and will be automatically detected from your `dars.config.json` (defaults to `./dist`):
534
553
 
535
554
  ```bash
536
- dars preview ./my_exported_app
555
+ # Auto-detects output directory and port from config
556
+ dars preview
557
+
558
+ # Or specify a custom path and port
559
+ dars preview ./my_exported_app -p 8080
537
560
  ```
538
561
 
539
- This will start a local server at http://localhost:8000 to view your exported app in the browser.
562
+ This will start a local server at the configured port (defaults to http://localhost:8000) to view your exported app in the browser.
540
563
 
541
564
  ---
542
565
 
@@ -576,7 +599,7 @@ Example default:
576
599
  - `utility_styles`: Dictionary defining custom utility classes. Keys are class names, values are lists of utility strings or raw CSS properties.
577
600
  - `markdownHighlight`: Auto-inject a client-side syntax highlighter for fenced code blocks in Markdown. Default `true`.
578
601
  - `backendEntry`: Python import path for your SSR/backend app (e.g. `"backend.api:app"`). Required when your app uses `RouteType.SSR` routes. Used by `dars dev --backend`.
579
- - `port`: The port for the development preview server. Default `8000`.
602
+ - `port`: The port for the development preview server. Default `8000`. This port is used by `dars dev`, `python app.py` (rTimeCompile), and `dars preview`.
580
603
 
581
604
  Validate your config:
582
605
 
@@ -439,7 +439,8 @@ For complete documentation, see the [Backend API Guide](https://ztamdev.github.i
439
439
  | `dars init --type desktop` | Scaffold desktop-capable project (BETA) |
440
440
  | `dars init --type ssr` | Scaffold full-stack SSR project (SSR + API) |
441
441
  | `dars build` (desktop config) | Build desktop app artifacts (BETA) |
442
- | `dars preview ./my_app_web` | Preview exported app locally |
442
+ | `dars preview` | Preview exported app (auto-detects output) |
443
+ | `dars preview --port 9000` | Preview on a custom port |
443
444
  | `dars init my_project` | Create a new Dars project (also creates dars.config.json) |
444
445
  | `dars init --update` | Create/Update dars.config.json in current dir |
445
446
  | `dars build` | Build using dars.config.json (entry/outdir/format) |
@@ -449,6 +450,8 @@ For complete documentation, see the [Backend API Guide](https://ztamdev.github.i
449
450
  | `dars dev` | Run the configured entry file with hot preview (app.rTimeCompile) |
450
451
  | `dars dev --port 9000` | Run dev server on a custom port (overrides config) |
451
452
  | `dars dev --backend` | Run only the configured backendEntry (FastAPI/SSR backend) |
453
+ | `dars generate component <name>` | Scaffold a new FunctionComponent |
454
+ | `dars generate page <name>` | Scaffold a new page (static or SPA) |
452
455
  | `dars --help` | Show help and all CLI options |
453
456
 
454
457
  Tip: use `dars doctor` to review optional tooling that can enhance bundling/minification.
@@ -460,6 +463,22 @@ Tip: use `dars doctor` to review optional tooling that can enhance bundling/mini
460
463
  - Build with `dars build` to produce desktop artifacts under `dist/`.
461
464
  - This feature is in BETA: usable for testing, not yet recommended for production.
462
465
 
466
+ ### Code Generation
467
+
468
+ Scaffold new components and pages instantly with automatic project integration.
469
+
470
+ ```bash
471
+ # Generate a new FunctionComponent
472
+ dars generate component MyComponent
473
+
474
+ # Generate a new Page (Static, SPA or SSR)
475
+ dars generate page About --page-type spa
476
+ dars generate page Dashboard --page-type ssr
477
+
478
+ # Scaffold and auto-inject into your main.py file
479
+ dars generate page Contact --yes
480
+ ```
481
+
463
482
  ---
464
483
 
465
484
  - Visit dars [official website](https://ztamdev.github.io/Dars-Framework/)
@@ -489,13 +508,17 @@ python my_app.py --port 8088
489
508
 
490
509
  ---
491
510
 
492
- You can also use the CLI preview command on an exported app:
511
+ You can also use the CLI preview command on an exported app. Starting from v1.9.6, the path is optional and will be automatically detected from your `dars.config.json` (defaults to `./dist`):
493
512
 
494
513
  ```bash
495
- dars preview ./my_exported_app
514
+ # Auto-detects output directory and port from config
515
+ dars preview
516
+
517
+ # Or specify a custom path and port
518
+ dars preview ./my_exported_app -p 8080
496
519
  ```
497
520
 
498
- This will start a local server at http://localhost:8000 to view your exported app in the browser.
521
+ This will start a local server at the configured port (defaults to http://localhost:8000) to view your exported app in the browser.
499
522
 
500
523
  ---
501
524
 
@@ -535,7 +558,7 @@ Example default:
535
558
  - `utility_styles`: Dictionary defining custom utility classes. Keys are class names, values are lists of utility strings or raw CSS properties.
536
559
  - `markdownHighlight`: Auto-inject a client-side syntax highlighter for fenced code blocks in Markdown. Default `true`.
537
560
  - `backendEntry`: Python import path for your SSR/backend app (e.g. `"backend.api:app"`). Required when your app uses `RouteType.SSR` routes. Used by `dars dev --backend`.
538
- - `port`: The port for the development preview server. Default `8000`.
561
+ - `port`: The port for the development preview server. Default `8000`. This port is used by `dars dev`, `python app.py` (rTimeCompile), and `dars preview`.
539
562
 
540
563
  Validate your config:
541
564
 
@@ -0,0 +1,288 @@
1
+ import os
2
+ import re
3
+ from rich.console import Console
4
+ from rich.prompt import Prompt, Confirm
5
+ from dars.cli.prompts import select_prompt, confirm_prompt
6
+
7
+ API_CONFIG_PY_CODE = """import os
8
+ import sys
9
+
10
+ class DarsEnv:
11
+ # Set this to "production" when deploying
12
+ MODE = "development"
13
+
14
+ DEV = "development"
15
+ BUILD = "production"
16
+
17
+ @staticmethod
18
+ def get_env():
19
+ return DarsEnv.MODE
20
+
21
+ @staticmethod
22
+ def is_dev():
23
+ return DarsEnv.get_env() == DarsEnv.DEV
24
+
25
+ @staticmethod
26
+ def get_urls():
27
+ # Configuration for URLs
28
+ if DarsEnv.is_dev():
29
+ return {
30
+ "backend": "http://localhost:3000", # SSR/API Server
31
+ "frontend": "http://localhost:8000" # Dev Server
32
+ }
33
+ return {
34
+ "backend": "/", # Production: Same origin
35
+ "frontend": "/"
36
+ }
37
+ """
38
+
39
+ API_PY_CODE = """\"""
40
+ SSR Backend - Dars Framework
41
+ Run with: python -m backend.api
42
+ \"""
43
+ from fastapi import FastAPI
44
+ from fastapi.middleware.cors import CORSMiddleware
45
+ from dars.backend.ssr import create_ssr_app
46
+ import sys
47
+ import os
48
+ from backend.apiConfig import DarsEnv
49
+
50
+ # Import the Dars app
51
+ import sys
52
+ sys.path.insert(0, '.')
53
+ from main import app as dars_app
54
+
55
+
56
+ # Create FastAPI app with SSR support
57
+ app = create_ssr_app(dars_app)
58
+
59
+ # Enable CORS for local development
60
+ if DarsEnv.is_dev():
61
+ urls = DarsEnv.get_urls()
62
+ app.add_middleware(
63
+ CORSMiddleware,
64
+ allow_origins=[urls['frontend'], "http://127.0.0.1:3000"],
65
+ allow_credentials=True,
66
+ allow_methods=["*"],
67
+ allow_headers=["*"],
68
+ )
69
+
70
+ if __name__ == "__main__":
71
+ import uvicorn
72
+ urls = DarsEnv.get_urls()
73
+ print(" " + "="*60)
74
+ print("Dars SSR Backend")
75
+ print("="*60)
76
+ print(f"Endpoints:")
77
+ print(f" • {urls['backend']}/ - API info")
78
+ print(f" • {urls['backend']}/api/ssr/* - SSR routes")
79
+ print(f"Frontend: {urls['frontend']}")
80
+ print("="*60 + " ")
81
+
82
+ uvicorn.run(app, host="127.0.0.1", port=3000)
83
+ """
84
+
85
+ console = Console()
86
+
87
+ def handle_generate(args):
88
+ gen_type = args.type
89
+ if not gen_type:
90
+ gen_type = select_prompt("What do you want to generate?", choices=["component", "page"])
91
+
92
+ name = args.name
93
+ if not name:
94
+ while True:
95
+ name = Prompt.ask(f"Enter the name of the {gen_type}")
96
+ if name and name.strip():
97
+ break
98
+ console.print(f"[red]Error: {gen_type.capitalize()} name cannot be empty.[/red]")
99
+
100
+ # Ensure it's a valid python identifier
101
+ safe_name = re.sub(r'[^a-zA-Z0-9_]', '_', name)
102
+ # Avoid python keywords or starting with numbers
103
+ if safe_name and safe_name[0].isdigit():
104
+ safe_name = "_" + safe_name
105
+
106
+ if gen_type == "component":
107
+ os.makedirs("components", exist_ok=True)
108
+ file_path = f"components/{name}.py"
109
+ if os.path.exists(file_path):
110
+ console.print(f"[red]Error: Component {file_path} already exists.[/red]")
111
+ return
112
+
113
+ content = f"""from dars.all import *
114
+
115
+ @FunctionComponent
116
+ def {safe_name}(props):
117
+ return Container(
118
+ Text("{name} Component works!")
119
+ )
120
+ """
121
+ with open(file_path, "w") as f:
122
+ f.write(content)
123
+ console.print(f"[green]SUCCESS: Component {name} generated successfully at {file_path}[/green]")
124
+ console.print("[yellow]Note: Remember to import and use it in your main application.[/yellow]")
125
+
126
+ elif gen_type == "page":
127
+ page_type = args.page_type
128
+ if not page_type:
129
+ page_type = select_prompt(f"What type of page is '{name}'?", choices=["static", "spa", "ssr"])
130
+
131
+ os.makedirs("pages", exist_ok=True)
132
+ file_path = f"pages/{name}.py"
133
+ if os.path.exists(file_path):
134
+ console.print(f"[red]Error: Page {file_path} already exists.[/red]")
135
+ return
136
+
137
+ if page_type == "static":
138
+ content = f"""from dars.all import *
139
+
140
+ {safe_name} = Page(
141
+ Container(
142
+ Text("{name} Static Page works!")
143
+ )
144
+ )
145
+ """
146
+ import_statement = f"from pages.{name} import {safe_name}"
147
+ inject_statement = f"app.add_page('{name}', {safe_name})"
148
+ elif page_type == "spa":
149
+ content = f"""from dars.all import *
150
+
151
+ @route("/{name}")
152
+ def {safe_name}():
153
+ return Page(
154
+ Container(
155
+ Text("{name} SPA Page works!")
156
+ )
157
+ )
158
+ """
159
+ import_statement = f"from pages.{name} import {safe_name}"
160
+ inject_statement = f"app.add_page('{name}', {safe_name}())"
161
+ else: # ssr
162
+ content = f"""from dars.all import *
163
+
164
+ @route("/{name}", route_type=RouteType.SSR)
165
+ def {safe_name}():
166
+ return Page(
167
+ Container(
168
+ Text("{name} SSR Page works!")
169
+ )
170
+ )
171
+ """
172
+ import_statement = f"from pages.{name} import {safe_name}"
173
+ inject_statement = f"app.add_page('{name}', {safe_name}())"
174
+
175
+ # Check for backend files
176
+ if not os.path.exists("backend"):
177
+ console.print("\n[bold yellow]⚠ WARNING: SSR routes require a backend configuration.[/bold yellow]")
178
+ console.print("[yellow]It seems your project doesn't have the '/backend' directory required for Dars SSR.[/yellow]")
179
+
180
+ if confirm_prompt("Do you want to automatically scaffold the SSR backend now?"):
181
+ os.makedirs("backend", exist_ok=True)
182
+ with open("backend/__init__.py", "w") as f: pass
183
+
184
+ with open("backend/apiConfig.py", "w") as f:
185
+ f.write(API_CONFIG_PY_CODE.strip())
186
+
187
+ with open("backend/api.py", "w") as f:
188
+ f.write(API_PY_CODE.strip())
189
+
190
+ # Update config
191
+ if os.path.exists("dars.config.json"):
192
+ import json
193
+ try:
194
+ with open("dars.config.json", "r") as f:
195
+ config = json.load(f)
196
+ if "backendEntry" not in config:
197
+ config["backendEntry"] = "backend.api:app"
198
+ with open("dars.config.json", "w") as f:
199
+ json.dump(config, f, indent=2)
200
+ console.print("[green]SUCCESS: Updated dars.config.json with backendEntry.[/green]")
201
+ except:
202
+ pass
203
+
204
+ console.print("[green]SUCCESS: SSR Backend scaffolded at /backend[/green]")
205
+ console.print("[yellow]Note: Remember to run 'dars dev --backend' to start the SSR server.[/yellow]")
206
+
207
+ with open(file_path, "w") as f:
208
+ f.write(content)
209
+ console.print(f"[green]SUCCESS: Page {name} generated successfully at {file_path}[/green]")
210
+
211
+ # Inject to main.py
212
+ auto_inject = args.yes
213
+ if not auto_inject:
214
+ auto_inject = confirm_prompt(f"Do you want to automatically add this page to your main app file?")
215
+
216
+ if auto_inject:
217
+ entry_file = "main.py"
218
+ if os.path.exists("dars.config.json"):
219
+ import json
220
+ try:
221
+ with open("dars.config.json", "r") as f:
222
+ config = json.load(f)
223
+ entry_file = config.get("entry", "main.py")
224
+ except:
225
+ pass
226
+
227
+ if not os.path.exists(entry_file):
228
+ if os.path.exists("index.py"):
229
+ entry_file = "index.py"
230
+ else:
231
+ console.print(f"[red]Error: Could not find main application file ({entry_file}). Please add the page manually.[/red]")
232
+ console.print(f"[cyan]{import_statement}[/cyan]")
233
+ console.print(f"[cyan]{inject_statement}[/cyan]")
234
+ return
235
+
236
+ try:
237
+ with open(entry_file, "r") as f:
238
+ lines = f.readlines()
239
+
240
+ content_all = "".join(lines)
241
+
242
+ # Default app variable name might be different
243
+ app_var_match = re.search(r'([a-zA-Z0-9_]+)\s*=\s*App\(', content_all)
244
+ app_var = app_var_match.group(1) if app_var_match else "app"
245
+
246
+ if app_var != "app":
247
+ inject_statement = inject_statement.replace("app.", f"{app_var}.")
248
+
249
+ # 1. Inject Import
250
+ last_import_line = -1
251
+ for i, line in enumerate(lines):
252
+ if line.strip().startswith(("import ", "from ")):
253
+ last_import_line = i
254
+
255
+ if last_import_line != -1:
256
+ lines.insert(last_import_line + 1, import_statement + "\n")
257
+ else:
258
+ lines.insert(0, import_statement + "\n")
259
+
260
+ # 2. Inject add_page
261
+ last_add_page_line = -1
262
+ for i, line in enumerate(lines):
263
+ if f"{app_var}.add_page(" in line:
264
+ last_add_page_line = i
265
+
266
+ if last_add_page_line != -1:
267
+ lines.insert(last_add_page_line + 1, inject_statement + "\n")
268
+ else:
269
+ # Fallback: after app = App(...)
270
+ app_def_line = -1
271
+ for i, line in enumerate(lines):
272
+ if f"{app_var} = App(" in line:
273
+ app_def_line = i
274
+ break
275
+ if app_def_line != -1:
276
+ lines.insert(app_def_line + 1, "\n" + inject_statement + "\n")
277
+ else:
278
+ lines.append("\n" + inject_statement + "\n")
279
+
280
+ with open(entry_file, "w") as f:
281
+ f.writelines(lines)
282
+
283
+ console.print(f"[green]SUCCESS: Successfully added {name} to {entry_file}[/green]")
284
+ except Exception as e:
285
+ console.print(f"[red]Failed to auto-inject: {str(e)}[/red]")
286
+ console.print(f"[yellow]Please add manually:[/yellow]")
287
+ console.print(f"[cyan]{import_statement}[/cyan]")
288
+ console.print(f"[cyan]{inject_statement}[/cyan]")