dars-framework 1.9.2__tar.gz → 1.9.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dars_framework-1.9.2/dars_framework.egg-info → dars_framework-1.9.3}/PKG-INFO +5 -2
- {dars_framework-1.9.2 → dars_framework-1.9.3}/README.md +4 -1
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/main.py +11 -1
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/page.py +67 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/config.py +1 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/core/app.py +143 -15
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/exporters/web/html_css_js.py +51 -88
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/security.py +1 -1
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/version.py +2 -2
- {dars_framework-1.9.2 → dars_framework-1.9.3/dars_framework.egg-info}/PKG-INFO +5 -2
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars_framework.egg-info/SOURCES.txt +0 -1
- {dars_framework-1.9.2 → dars_framework-1.9.3}/pyproject.toml +1 -1
- dars_framework-1.9.2/dars/js_lib.py +0 -2049
- {dars_framework-1.9.2 → dars_framework-1.9.3}/Dars-logo.png +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/LICENSE +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/MANIFEST.in +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/actionProtocol.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/all.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/backend/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/backend/components.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/backend/data.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/backend/http.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/backend/json_utils.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/backend/route_loader.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/backend/ssr.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/doctor/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/doctor/detect.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/doctor/doctor.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/doctor/installers.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/doctor/persist.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/doctor/preflight.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/doctor/ui.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/dpm.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/hot_reload.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/preview.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/cli/translations.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/advanced/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/advanced/accordion.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/advanced/card.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/advanced/file_upload.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/advanced/head.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/advanced/modal.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/advanced/navbar.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/advanced/outlet.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/advanced/table.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/advanced/tabs.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/audio.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/button.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/checkbox.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/container.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/datepicker.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/image.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/input.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/link.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/markdown.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/progressbar.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/radiobutton.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/section.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/select.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/slider.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/spinner.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/text.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/textarea.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/tooltip.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/basic/video.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/layout/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/layout/anchor.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/layout/flex.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/layout/grid.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/visualization/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/visualization/chart.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/components/visualization/table.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/core/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/core/component.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/core/events.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/core/js_bridge.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/core/properties.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/core/route_types.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/core/routing.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/core/state.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/core/state_v2.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/core/utilities.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/dars_tests/apps_test/health_check.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/dars_tests/run_tests.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/dars_tests/tests/test_advanced_components.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/dars_tests/tests/test_basic_components.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/dars_tests/tests/test_core_and_cli.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/dars_tests/tests/test_layout_components.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/dars_tests/tests/test_version_check.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/desktop/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/desktop/api.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/desktop/js_generator.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/INSTALL.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/KeyEvents.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/animations.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/app.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/backend_api.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/cli.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/components.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/config.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/custom_components.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/env.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/events.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/exporters.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/getting_started.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/hooks.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/index.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/operations.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/routing.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/scripts.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/ssr.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/state_management.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/docs/styling.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/env.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/exporters/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/exporters/base.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/exporters/desktop/electron.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/exporters/web/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/exporters/web/vdom.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/hooks/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/hooks/form_helpers.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/hooks/set_vref.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/hooks/update_vref.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/hooks/use_dynamic.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/hooks/use_value.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/hooks/use_vref.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/hooks/use_watch.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/hooks/value_helpers.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/scripts/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/scripts/animations.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/scripts/dscript.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/scripts/keycode.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/scripts/script.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/scripts/utils_ds.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/desktop/icon.png +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/desktop/template/backend/icons/icon.png +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/desktop/template/backend/main.js +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/desktop/template/backend/package.json +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/desktop/template/backend/preload.js +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/desktop/template/dars.config.json +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/desktop/template/icons/icon.png +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/desktop/template/main.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/desktop/template/public/electron-icon.png +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/desktop/template/public/icon.png +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/README.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/CustomComp/main.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/Modal_Demo/advanced_modal_demo.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/StateV2/README.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/StateV2/animation_component.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/StateV2/counter_component.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/StateV2/hero_component.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/StateV2/main.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/StateV2/styles.css +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/StateV2/timer_component.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/VariousComponents/all_components_demo.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/dState/state_mods_demo.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/hooks/useDynamic.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/hooks/useValue.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/advanced/hooks/useWatch.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/basic/HelloWorld/hello_world.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/basic/Layouts/flex_layout_responsive.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/basic/Layouts/grid_layout_responsive.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/basic/Layouts/layout_multipage_demo.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/basic/PWA/icon-192x192.png +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/basic/PWA/icon-512x512.png +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/basic/PWA/pwa_custom_icons.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/basic/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/markdown/MarkdownTemplate/README.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/markdown/MarkdownTemplate/markdown_template.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/markdown/MarkdownTemplate/other_docs.md +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars/templates/examples/markdown/__init__.py +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars_framework.egg-info/dependency_links.txt +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars_framework.egg-info/entry_points.txt +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars_framework.egg-info/requires.txt +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/dars_framework.egg-info/top_level.txt +0 -0
- {dars_framework-1.9.2 → dars_framework-1.9.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dars-framework
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.3
|
|
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>
|
|
@@ -483,6 +483,7 @@ For complete documentation, see the [Backend API Guide](https://ztamdev.github.i
|
|
|
483
483
|
| `dars info my_app.py` | Show info about your app |
|
|
484
484
|
| `dars formats` | List supported export formats |
|
|
485
485
|
| `dars dev` | Run the configured entry file with hot preview (app.rTimeCompile) |
|
|
486
|
+
| `dars dev --port 9000` | Run dev server on a custom port (overrides config) |
|
|
486
487
|
| `dars dev --backend` | Run only the configured backendEntry (FastAPI/SSR backend) |
|
|
487
488
|
| `dars --help` | Show help and all CLI options |
|
|
488
489
|
|
|
@@ -516,7 +517,7 @@ Then run your file directly:
|
|
|
516
517
|
python my_app.py
|
|
517
518
|
```
|
|
518
519
|
|
|
519
|
-
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
|
|
520
|
+
This will start a local server at the port specified in your `dars.config.json` (defaults to http://localhost:8000) so you can view your app in the browser—no manual export needed. You can override the port with:
|
|
520
521
|
|
|
521
522
|
```bash
|
|
522
523
|
python my_app.py --port 8088
|
|
@@ -554,6 +555,7 @@ Example default:
|
|
|
554
555
|
"utility_styles": {},
|
|
555
556
|
"markdownHighlight": true,
|
|
556
557
|
"markdownHighlightTheme": "auto",
|
|
558
|
+
"port": 8000,
|
|
557
559
|
"backendEntry": "backend.api:app"
|
|
558
560
|
}
|
|
559
561
|
```
|
|
@@ -569,6 +571,7 @@ Example default:
|
|
|
569
571
|
- `utility_styles`: Dictionary defining custom utility classes. Keys are class names, values are lists of utility strings or raw CSS properties.
|
|
570
572
|
- `markdownHighlight`: Auto-inject a client-side syntax highlighter for fenced code blocks in Markdown. Default `true`.
|
|
571
573
|
- `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`.
|
|
574
|
+
- `port`: The port for the development preview server. Default `8000`.
|
|
572
575
|
|
|
573
576
|
Validate your config:
|
|
574
577
|
|
|
@@ -442,6 +442,7 @@ For complete documentation, see the [Backend API Guide](https://ztamdev.github.i
|
|
|
442
442
|
| `dars info my_app.py` | Show info about your app |
|
|
443
443
|
| `dars formats` | List supported export formats |
|
|
444
444
|
| `dars dev` | Run the configured entry file with hot preview (app.rTimeCompile) |
|
|
445
|
+
| `dars dev --port 9000` | Run dev server on a custom port (overrides config) |
|
|
445
446
|
| `dars dev --backend` | Run only the configured backendEntry (FastAPI/SSR backend) |
|
|
446
447
|
| `dars --help` | Show help and all CLI options |
|
|
447
448
|
|
|
@@ -475,7 +476,7 @@ Then run your file directly:
|
|
|
475
476
|
python my_app.py
|
|
476
477
|
```
|
|
477
478
|
|
|
478
|
-
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
|
|
479
|
+
This will start a local server at the port specified in your `dars.config.json` (defaults to http://localhost:8000) so you can view your app in the browser—no manual export needed. You can override the port with:
|
|
479
480
|
|
|
480
481
|
```bash
|
|
481
482
|
python my_app.py --port 8088
|
|
@@ -513,6 +514,7 @@ Example default:
|
|
|
513
514
|
"utility_styles": {},
|
|
514
515
|
"markdownHighlight": true,
|
|
515
516
|
"markdownHighlightTheme": "auto",
|
|
517
|
+
"port": 8000,
|
|
516
518
|
"backendEntry": "backend.api:app"
|
|
517
519
|
}
|
|
518
520
|
```
|
|
@@ -528,6 +530,7 @@ Example default:
|
|
|
528
530
|
- `utility_styles`: Dictionary defining custom utility classes. Keys are class names, values are lists of utility strings or raw CSS properties.
|
|
529
531
|
- `markdownHighlight`: Auto-inject a client-side syntax highlighter for fenced code blocks in Markdown. Default `true`.
|
|
530
532
|
- `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`.
|
|
533
|
+
- `port`: The port for the development preview server. Default `8000`.
|
|
531
534
|
|
|
532
535
|
Validate your config:
|
|
533
536
|
|
|
@@ -1206,6 +1206,7 @@ def create_parser(include_hidden: bool = True) -> argparse.ArgumentParser:
|
|
|
1206
1206
|
# Dev command (run entry in dev mode)
|
|
1207
1207
|
dev_parser = subparsers.add_parser('dev', help='Run the configured entry file in development mode')
|
|
1208
1208
|
dev_parser.add_argument('--project', '-p', default='.', help='Project root where dars.config.json resides (default: .)')
|
|
1209
|
+
dev_parser.add_argument('--port', '-P', type=int, help='Port to run the dev server on (overrides config)')
|
|
1209
1210
|
dev_parser.add_argument('--backend', action='store_true', help='Run only the configured backendEntry (SSR/API) instead of the frontend entry')
|
|
1210
1211
|
# English-only: no language option on subparsers
|
|
1211
1212
|
|
|
@@ -2296,7 +2297,16 @@ def main():
|
|
|
2296
2297
|
# Backend/SSR server can be started in a separate terminal with `dars dev --backend` if needed.
|
|
2297
2298
|
process = None
|
|
2298
2299
|
try:
|
|
2299
|
-
|
|
2300
|
+
cmd = [sys.executable, entry]
|
|
2301
|
+
# Prioritize CLI arg, then config, then fallback to 8000
|
|
2302
|
+
port_to_pass = getattr(args, 'port', None)
|
|
2303
|
+
if port_to_pass is None and found and "port" in cfg:
|
|
2304
|
+
port_to_pass = cfg["port"]
|
|
2305
|
+
|
|
2306
|
+
if port_to_pass:
|
|
2307
|
+
cmd.extend(['--port', str(port_to_pass)])
|
|
2308
|
+
|
|
2309
|
+
process = subprocess.Popen(cmd, cwd=os.path.dirname(entry))
|
|
2300
2310
|
process.wait()
|
|
2301
2311
|
sys.exit(process.returncode or 0)
|
|
2302
2312
|
except KeyboardInterrupt:
|
|
@@ -39,6 +39,73 @@ class Page(Component):
|
|
|
39
39
|
self.add_child(child)
|
|
40
40
|
|
|
41
41
|
def add_script(self, script):
|
|
42
|
+
"""
|
|
43
|
+
Adds a script to this page.
|
|
44
|
+
|
|
45
|
+
Supports multiple script types:
|
|
46
|
+
|
|
47
|
+
- **DScript**: Direct Python function compilation to JavaScript
|
|
48
|
+
- **String**: Inline JavaScript code
|
|
49
|
+
- **Dictionary**: Raw script object (fallback)
|
|
50
|
+
- **Utility Chains**: DAP utility functions with promise-based chaining
|
|
51
|
+
|
|
52
|
+
**Script Types:**
|
|
53
|
+
|
|
54
|
+
1. **DScript** - Compile Python to JavaScript:
|
|
55
|
+
```python
|
|
56
|
+
page.add_script(dScript(file_path="script.js"))
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
2. **Inline JavaScript**:
|
|
60
|
+
```python
|
|
61
|
+
page.add_script("console.log('Page loaded');")
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
3. **Utility Functions** - Chain DAP commands:
|
|
65
|
+
```python
|
|
66
|
+
from dars.scripts.utils_ds import setTimeout, addClass, log
|
|
67
|
+
|
|
68
|
+
# Sequential animations with promise chaining
|
|
69
|
+
page.add_script(
|
|
70
|
+
setTimeout(5, addClass("logo", "show"))
|
|
71
|
+
.then(setTimeout(350, addClass("title", "show")))
|
|
72
|
+
.then(setTimeout(650, addClass("description", "show")))
|
|
73
|
+
)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
4. **useWatch** - React to state changes:
|
|
77
|
+
```python
|
|
78
|
+
page.add_script(
|
|
79
|
+
useWatch("user.name", log("Name changed!"))
|
|
80
|
+
)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Common Utilities:**
|
|
84
|
+
|
|
85
|
+
- **setTimeout(ms, action)**: Execute action after delay (returns Promise)
|
|
86
|
+
- **addClass(id, class)**: Add CSS class to element
|
|
87
|
+
- **removeClass(id, class)**: Remove CSS class
|
|
88
|
+
- **toggleClass(id, class)**: Toggle CSS class
|
|
89
|
+
- **log(msg)**: Log to console
|
|
90
|
+
- **navigate(url)**: Navigate to URL
|
|
91
|
+
- **createComp(target, root)**: Dynamically create components
|
|
92
|
+
- **updateComp(id, props)**: Update component properties
|
|
93
|
+
- **deleteComp(id)**: Remove component from DOM
|
|
94
|
+
|
|
95
|
+
**Promise Chaining:**
|
|
96
|
+
|
|
97
|
+
All timeout/async utilities return Promises, allowing sequential execution:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
page.add_script(
|
|
101
|
+
setTimeout(100, log("Step 1"))
|
|
102
|
+
.then(setTimeout(200, log("Step 2")))
|
|
103
|
+
.then(setTimeout(300, log("Step 3")))
|
|
104
|
+
)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Returns self to allow method chaining.
|
|
108
|
+
"""
|
|
42
109
|
self.scripts.append(script)
|
|
43
110
|
|
|
44
111
|
def useWatch(self, state_path: str, *js_helpers):
|
|
@@ -22,6 +22,7 @@ DEFAULT_CONFIG = {
|
|
|
22
22
|
"markdownHighlight": True,
|
|
23
23
|
"markdownHighlightTheme": "auto",
|
|
24
24
|
"targetPlatform": "auto", # Desktop-only option: platform target for Electron build (auto|windows|linux|macos)
|
|
25
|
+
"port": 8000,
|
|
25
26
|
# Optional: backend entry for SSR projects (module or file path). Disabled by default.
|
|
26
27
|
"backendEntry": None,
|
|
27
28
|
# Optional: custom utility styles map consumed by register_custom_utilities
|
|
@@ -46,11 +46,73 @@ class Page:
|
|
|
46
46
|
# Métodos para manejar scripts
|
|
47
47
|
# -----------------------------
|
|
48
48
|
def add_script(self, script: Any):
|
|
49
|
-
"""
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
"""
|
|
50
|
+
Adds a script to this page.
|
|
51
|
+
|
|
52
|
+
Supports multiple script types:
|
|
53
|
+
|
|
54
|
+
- **DScript**: Direct Python function compilation to JavaScript
|
|
55
|
+
- **String**: Inline JavaScript code
|
|
56
|
+
- **Dictionary**: Raw script object (fallback)
|
|
57
|
+
- **Utility Chains**: DAP utility functions with promise-based chaining
|
|
58
|
+
|
|
59
|
+
**Script Types:**
|
|
60
|
+
|
|
61
|
+
1. **DScript** - Compile Python to JavaScript:
|
|
62
|
+
```python
|
|
63
|
+
page.add_script(dScript(file_path="script.js"))
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
2. **Inline JavaScript**:
|
|
67
|
+
```python
|
|
68
|
+
page.add_script("console.log('Page loaded');")
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
3. **Utility Functions** - Chain DAP commands:
|
|
72
|
+
```python
|
|
73
|
+
from dars.scripts.utils_ds import setTimeout, addClass, log
|
|
74
|
+
|
|
75
|
+
# Sequential animations with promise chaining
|
|
76
|
+
page.add_script(
|
|
77
|
+
setTimeout(5, addClass("logo", "show"))
|
|
78
|
+
.then(setTimeout(350, addClass("title", "show")))
|
|
79
|
+
.then(setTimeout(650, addClass("description", "show")))
|
|
80
|
+
)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
4. **useWatch** - React to state changes:
|
|
84
|
+
```python
|
|
85
|
+
page.add_script(
|
|
86
|
+
useWatch("user.name", log("Name changed!"))
|
|
87
|
+
)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Common Utilities:**
|
|
91
|
+
|
|
92
|
+
- **setTimeout(ms, action)**: Execute action after delay (returns Promise)
|
|
93
|
+
- **addClass(id, class)**: Add CSS class to element
|
|
94
|
+
- **removeClass(id, class)**: Remove CSS class
|
|
95
|
+
- **toggleClass(id, class)**: Toggle CSS class
|
|
96
|
+
- **log(msg)**: Log to console
|
|
97
|
+
- **navigate(url)**: Navigate to URL
|
|
98
|
+
- **createComp(target, root)**: Dynamically create components
|
|
99
|
+
- **updateComp(id, props)**: Update component properties
|
|
100
|
+
- **deleteComp(id)**: Remove component from DOM
|
|
101
|
+
|
|
102
|
+
**Promise Chaining:**
|
|
103
|
+
|
|
104
|
+
All timeout/async utilities return Promises, allowing sequential execution:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
page.add_script(
|
|
108
|
+
setTimeout(100, log("Step 1"))
|
|
109
|
+
.then(setTimeout(200, log("Step 2")))
|
|
110
|
+
.then(setTimeout(300, log("Step 3")))
|
|
111
|
+
)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Returns self to allow method chaining.
|
|
115
|
+
"""
|
|
54
116
|
|
|
55
117
|
# si es str => interpretarlo como inline
|
|
56
118
|
if isinstance(script, str):
|
|
@@ -614,15 +676,6 @@ class App:
|
|
|
614
676
|
except Exception:
|
|
615
677
|
console = None
|
|
616
678
|
|
|
617
|
-
# ---- PORT ----
|
|
618
|
-
if port is None:
|
|
619
|
-
port = 8000
|
|
620
|
-
for i, arg in enumerate(sys.argv):
|
|
621
|
-
if arg in ('--port', '-p') and i + 1 < len(sys.argv):
|
|
622
|
-
try:
|
|
623
|
-
port = int(sys.argv[i + 1])
|
|
624
|
-
except:
|
|
625
|
-
pass
|
|
626
679
|
|
|
627
680
|
# ---- NORMALIZE EXTENSIONS ----
|
|
628
681
|
def _normalize_exts(exts):
|
|
@@ -777,6 +830,27 @@ class App:
|
|
|
777
830
|
# Fix logic: Use self.desktop attribute if available, regardless of config
|
|
778
831
|
is_desktop = bool(getattr(self, 'desktop', False) or fmt == 'desktop')
|
|
779
832
|
|
|
833
|
+
# ---- PORT (CONFIG DRIVEN) ----
|
|
834
|
+
if port is None:
|
|
835
|
+
# 1. Try to get port from config
|
|
836
|
+
if cfg_found and "port" in cfg:
|
|
837
|
+
try:
|
|
838
|
+
port = int(cfg["port"])
|
|
839
|
+
except:
|
|
840
|
+
pass
|
|
841
|
+
|
|
842
|
+
# 2. Default if not in config
|
|
843
|
+
if port is None:
|
|
844
|
+
port = 8000
|
|
845
|
+
|
|
846
|
+
# 3. CLI override always takes precedence
|
|
847
|
+
for i, arg in enumerate(sys.argv):
|
|
848
|
+
if arg in ('--port', '-p') and i + 1 < len(sys.argv):
|
|
849
|
+
try:
|
|
850
|
+
port = int(sys.argv[i + 1])
|
|
851
|
+
except:
|
|
852
|
+
pass
|
|
853
|
+
|
|
780
854
|
# ---- STARTUP SPINNER ----
|
|
781
855
|
startup_status = None
|
|
782
856
|
if console:
|
|
@@ -1674,7 +1748,61 @@ class App:
|
|
|
1674
1748
|
self._spa_error_page = onErrorComp
|
|
1675
1749
|
|
|
1676
1750
|
def add_script(self, script: 'Script'):
|
|
1677
|
-
"""
|
|
1751
|
+
"""
|
|
1752
|
+
Adds a global script to the application (runs on every page).
|
|
1753
|
+
|
|
1754
|
+
Global scripts are injected into every page of your application and can be used for:
|
|
1755
|
+
- Global utilities and helpers
|
|
1756
|
+
- Application-wide event listeners
|
|
1757
|
+
- Initialization code
|
|
1758
|
+
- Analytics and tracking
|
|
1759
|
+
- Feature detection
|
|
1760
|
+
|
|
1761
|
+
**Supported Script Types:**
|
|
1762
|
+
|
|
1763
|
+
1. **DScript** - Compiled Python functions:
|
|
1764
|
+
```python
|
|
1765
|
+
app.add_script(dScript(file_path="global.js"))
|
|
1766
|
+
```
|
|
1767
|
+
|
|
1768
|
+
2. **Inline JavaScript**:
|
|
1769
|
+
```python
|
|
1770
|
+
app.add_script("window.appVersion = '1.0.0';")
|
|
1771
|
+
```
|
|
1772
|
+
|
|
1773
|
+
3. **Utility Chains** - Global DAP utilities:
|
|
1774
|
+
```python
|
|
1775
|
+
from dars.scripts.utils_ds import setTimeout, addClass, log
|
|
1776
|
+
|
|
1777
|
+
# Global theme initialization with animations
|
|
1778
|
+
app.add_script(
|
|
1779
|
+
setTimeout(100, addClass("app-container", "initialized"))
|
|
1780
|
+
.then(setTimeout(500, log("App ready!")))
|
|
1781
|
+
)
|
|
1782
|
+
```
|
|
1783
|
+
|
|
1784
|
+
4. **useWatch** - Global state monitoring:
|
|
1785
|
+
```python
|
|
1786
|
+
app.add_script(
|
|
1787
|
+
useWatch("theme", log("Theme changed!"))
|
|
1788
|
+
)
|
|
1789
|
+
```
|
|
1790
|
+
|
|
1791
|
+
**Example: Global animations on page load**
|
|
1792
|
+
|
|
1793
|
+
```python
|
|
1794
|
+
from dars.scripts.utils_ds import setTimeout, addClass
|
|
1795
|
+
|
|
1796
|
+
# Add fade-in animation for all pages
|
|
1797
|
+
app.add_script(
|
|
1798
|
+
setTimeout(5, addClass("app-content", "fade-in"))
|
|
1799
|
+
.then(setTimeout(500, addClass("app-content", "show")))
|
|
1800
|
+
)
|
|
1801
|
+
```
|
|
1802
|
+
|
|
1803
|
+
**Note:** Global scripts are included in every page and should be lightweight.
|
|
1804
|
+
For page-specific scripts, use `page.add_script()` instead.
|
|
1805
|
+
"""
|
|
1678
1806
|
self.scripts.append(script)
|
|
1679
1807
|
|
|
1680
1808
|
def useWatch(self, state_path: str, *js_helpers):
|
|
@@ -44,6 +44,8 @@ from bs4 import BeautifulSoup
|
|
|
44
44
|
from dars.exporters.web.vdom import VDomBuilder
|
|
45
45
|
from dars.config import load_config, resolve_paths, copy_public_dir
|
|
46
46
|
import json
|
|
47
|
+
import shutil
|
|
48
|
+
import inspect
|
|
47
49
|
|
|
48
50
|
class DarsJSONEncoder(json.JSONEncoder):
|
|
49
51
|
def default(self, obj):
|
|
@@ -113,38 +115,7 @@ class HTMLCSSJSExporter(Exporter):
|
|
|
113
115
|
# Initialize style registry for this export (Phase 1 of style optimization)
|
|
114
116
|
# Maps generated class name -> dict(style)
|
|
115
117
|
self._style_registry: Dict[str, Dict[str, Any]] = {}
|
|
116
|
-
self._global_css_blocks: List[str] = [
|
|
117
|
-
/* Dars Markdown Copy Button Styles */
|
|
118
|
-
.dars-code-copy {
|
|
119
|
-
position: absolute;
|
|
120
|
-
top: 8px;
|
|
121
|
-
right: 8px;
|
|
122
|
-
background: rgba(0,0,0,0.6);
|
|
123
|
-
color: #fff;
|
|
124
|
-
border: none;
|
|
125
|
-
border-radius: 6px;
|
|
126
|
-
padding: 5px 10px;
|
|
127
|
-
font-size: 12px;
|
|
128
|
-
font-weight: 500;
|
|
129
|
-
cursor: pointer;
|
|
130
|
-
opacity: 0;
|
|
131
|
-
transition: all 0.2s ease;
|
|
132
|
-
z-index: 10;
|
|
133
|
-
backdrop-filter: blur(4px);
|
|
134
|
-
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
|
135
|
-
}
|
|
136
|
-
pre:hover .dars-code-copy {
|
|
137
|
-
opacity: 1;
|
|
138
|
-
}
|
|
139
|
-
.dars-code-copy:hover {
|
|
140
|
-
background: rgba(0,0,0,0.8);
|
|
141
|
-
transform: translateY(-1px);
|
|
142
|
-
}
|
|
143
|
-
.dars-code-copy.copied {
|
|
144
|
-
background: #16a34a !important;
|
|
145
|
-
opacity: 1 !important;
|
|
146
|
-
}
|
|
147
|
-
"""]
|
|
118
|
+
self._global_css_blocks: List[str] = []
|
|
148
119
|
self._markdown_html_assets = {} # route_name -> list of html strings
|
|
149
120
|
# Separate registries for hover/active variants (class -> dict(style))
|
|
150
121
|
self._hover_style_registry: Dict[str, Dict[str, Any]] = {}
|
|
@@ -178,30 +149,25 @@ pre:hover .dars-code-copy {
|
|
|
178
149
|
pass
|
|
179
150
|
|
|
180
151
|
# --- Escribir librería de reactividad (dars.min.js) embebida ---
|
|
181
|
-
#
|
|
152
|
+
# --- Runtime Assets (lib/) ---
|
|
182
153
|
try:
|
|
183
154
|
lib_dir = os.path.join(output_path, 'lib')
|
|
184
155
|
os.makedirs(lib_dir, exist_ok=True)
|
|
185
|
-
dest_js = os.path.join(lib_dir, 'dars.min.js')
|
|
186
156
|
|
|
187
|
-
#
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
with open(dest_js, 'r', encoding='utf-8') as f:
|
|
192
|
-
existing_content = f.read()
|
|
193
|
-
from dars.js_lib import DARS_MIN_JS
|
|
194
|
-
if existing_content == DARS_MIN_JS:
|
|
195
|
-
should_write = False # Skip write, already up to date
|
|
196
|
-
except Exception:
|
|
197
|
-
pass # If read fails, write anyway
|
|
157
|
+
# Copy all resources from dars/exporters/web/resources/
|
|
158
|
+
# This includes dars.min.js, dap.js, router.js, ssr.js, dompurify.js
|
|
159
|
+
exporter_dir = os.path.dirname(os.path.abspath(inspect.getfile(self.__class__)))
|
|
160
|
+
resources_dir = os.path.join(exporter_dir, 'resources')
|
|
198
161
|
|
|
199
|
-
if
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
162
|
+
if os.path.exists(resources_dir):
|
|
163
|
+
for filename in os.listdir(resources_dir):
|
|
164
|
+
if filename.endswith('.js') or filename.endswith('.js.map'):
|
|
165
|
+
src = os.path.join(resources_dir, filename)
|
|
166
|
+
dst = os.path.join(lib_dir, filename)
|
|
167
|
+
# Copy fresh every time to ensure updates are reflected
|
|
168
|
+
shutil.copy2(src, dst)
|
|
169
|
+
except Exception as e:
|
|
170
|
+
print(f"[Dars] Error copying runtime resources: {e}")
|
|
205
171
|
|
|
206
172
|
# --- Cargar configuración si existe y copiar public/assets ---
|
|
207
173
|
try:
|
|
@@ -1279,7 +1245,7 @@ self.addEventListener('fetch', event => {
|
|
|
1279
1245
|
|
|
1280
1246
|
def generate_custom_css(self, app: App) -> str:
|
|
1281
1247
|
"""Genera solo los estilos personalizados de la aplicación"""
|
|
1282
|
-
css_content =
|
|
1248
|
+
css_content = ""
|
|
1283
1249
|
|
|
1284
1250
|
# Generar estilos hover PRIMERO para que tengan prioridad
|
|
1285
1251
|
css_content += self._generate_hover_styles(app)
|
|
@@ -2236,6 +2202,37 @@ body {
|
|
|
2236
2202
|
}
|
|
2237
2203
|
|
|
2238
2204
|
/* Markdown */
|
|
2205
|
+
/* Dars Markdown Copy Button Styles */
|
|
2206
|
+
.dars-code-copy {
|
|
2207
|
+
position: absolute;
|
|
2208
|
+
top: 8px;
|
|
2209
|
+
right: 8px;
|
|
2210
|
+
background: rgba(0,0,0,0.6);
|
|
2211
|
+
color: #fff;
|
|
2212
|
+
border: none;
|
|
2213
|
+
border-radius: 6px;
|
|
2214
|
+
padding: 5px 10px;
|
|
2215
|
+
font-size: 12px;
|
|
2216
|
+
font-weight: 500;
|
|
2217
|
+
cursor: pointer;
|
|
2218
|
+
opacity: 0;
|
|
2219
|
+
transition: all 0.2s ease;
|
|
2220
|
+
z-index: 10;
|
|
2221
|
+
backdrop-filter: blur(4px);
|
|
2222
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
|
2223
|
+
}
|
|
2224
|
+
pre:hover .dars-code-copy {
|
|
2225
|
+
opacity: 1;
|
|
2226
|
+
}
|
|
2227
|
+
.dars-code-copy:hover {
|
|
2228
|
+
background: rgba(0,0,0,0.8);
|
|
2229
|
+
transform: translateY(-1px);
|
|
2230
|
+
}
|
|
2231
|
+
.dars-code-copy.copied {
|
|
2232
|
+
background: #16a34a !important;
|
|
2233
|
+
opacity: 1 !important;
|
|
2234
|
+
}
|
|
2235
|
+
|
|
2239
2236
|
.dars-markdown {
|
|
2240
2237
|
font-family: var(--dars-font-family);
|
|
2241
2238
|
line-height: 1.6;
|
|
@@ -5365,42 +5362,8 @@ audio.dars-audio {
|
|
|
5365
5362
|
'<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-okaidia.min.css" media="(prefers-color-scheme: dark)">\n'
|
|
5366
5363
|
)
|
|
5367
5364
|
|
|
5368
|
-
#
|
|
5369
|
-
|
|
5370
|
-
self._markdown_styles_registered = True
|
|
5371
|
-
if not hasattr(self, '_global_css_blocks'):
|
|
5372
|
-
self._global_css_blocks = []
|
|
5373
|
-
self._global_css_blocks.append("""
|
|
5374
|
-
.dars-code-copy {
|
|
5375
|
-
position: absolute;
|
|
5376
|
-
top: 8px;
|
|
5377
|
-
right: 8px;
|
|
5378
|
-
background: rgba(0,0,0,0.6);
|
|
5379
|
-
color: #fff;
|
|
5380
|
-
border: none;
|
|
5381
|
-
border-radius: 6px;
|
|
5382
|
-
padding: 5px 10px;
|
|
5383
|
-
font-size: 12px;
|
|
5384
|
-
font-weight: 500;
|
|
5385
|
-
cursor: pointer;
|
|
5386
|
-
opacity: 0;
|
|
5387
|
-
transition: all 0.2s ease;
|
|
5388
|
-
z-index: 10;
|
|
5389
|
-
backdrop-filter: blur(4px);
|
|
5390
|
-
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
|
5391
|
-
}
|
|
5392
|
-
pre:hover .dars-code-copy {
|
|
5393
|
-
opacity: 1;
|
|
5394
|
-
}
|
|
5395
|
-
.dars-code-copy:hover {
|
|
5396
|
-
background: rgba(0,0,0,0.8);
|
|
5397
|
-
transform: translateY(-1px);
|
|
5398
|
-
}
|
|
5399
|
-
.dars-code-copy.copied {
|
|
5400
|
-
background: #16a34a;
|
|
5401
|
-
opacity: 1;
|
|
5402
|
-
}
|
|
5403
|
-
""")
|
|
5365
|
+
# Copy Button styles are now in runtime_css.css
|
|
5366
|
+
pass
|
|
5404
5367
|
|
|
5405
5368
|
parts = []
|
|
5406
5369
|
parts.append(css_links)
|
|
@@ -275,7 +275,7 @@ def minify_output_dir(output_dir: str, extra_skip: Iterable[str] = None, progres
|
|
|
275
275
|
# It is already minified and toolchains can corrupt it (e.g. emit ESM exports).
|
|
276
276
|
# If you still want to re-minify it, do it with Python-only rjsmin.
|
|
277
277
|
base0 = os.path.basename(full_path)
|
|
278
|
-
if ext0 in SAFE_JS_EXT and base0
|
|
278
|
+
if ext0 in SAFE_JS_EXT and (base0 in ('dars.min.js', 'dompurify.js') or 'lib' in full_path.split(os.sep)):
|
|
279
279
|
# Fall back to Python-only rjsmin (never run Vite on this file)
|
|
280
280
|
try:
|
|
281
281
|
with open(full_path, 'r', encoding='utf-8') as f:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dars-framework
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.3
|
|
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>
|
|
@@ -483,6 +483,7 @@ For complete documentation, see the [Backend API Guide](https://ztamdev.github.i
|
|
|
483
483
|
| `dars info my_app.py` | Show info about your app |
|
|
484
484
|
| `dars formats` | List supported export formats |
|
|
485
485
|
| `dars dev` | Run the configured entry file with hot preview (app.rTimeCompile) |
|
|
486
|
+
| `dars dev --port 9000` | Run dev server on a custom port (overrides config) |
|
|
486
487
|
| `dars dev --backend` | Run only the configured backendEntry (FastAPI/SSR backend) |
|
|
487
488
|
| `dars --help` | Show help and all CLI options |
|
|
488
489
|
|
|
@@ -516,7 +517,7 @@ Then run your file directly:
|
|
|
516
517
|
python my_app.py
|
|
517
518
|
```
|
|
518
519
|
|
|
519
|
-
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
|
|
520
|
+
This will start a local server at the port specified in your `dars.config.json` (defaults to http://localhost:8000) so you can view your app in the browser—no manual export needed. You can override the port with:
|
|
520
521
|
|
|
521
522
|
```bash
|
|
522
523
|
python my_app.py --port 8088
|
|
@@ -554,6 +555,7 @@ Example default:
|
|
|
554
555
|
"utility_styles": {},
|
|
555
556
|
"markdownHighlight": true,
|
|
556
557
|
"markdownHighlightTheme": "auto",
|
|
558
|
+
"port": 8000,
|
|
557
559
|
"backendEntry": "backend.api:app"
|
|
558
560
|
}
|
|
559
561
|
```
|
|
@@ -569,6 +571,7 @@ Example default:
|
|
|
569
571
|
- `utility_styles`: Dictionary defining custom utility classes. Keys are class names, values are lists of utility strings or raw CSS properties.
|
|
570
572
|
- `markdownHighlight`: Auto-inject a client-side syntax highlighter for fenced code blocks in Markdown. Default `true`.
|
|
571
573
|
- `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`.
|
|
574
|
+
- `port`: The port for the development preview server. Default `8000`.
|
|
572
575
|
|
|
573
576
|
Validate your config:
|
|
574
577
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dars-framework"
|
|
7
|
-
version = "1.9.
|
|
7
|
+
version = "1.9.3"
|
|
8
8
|
description = "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."
|
|
9
9
|
dependencies = [ "rich==15.0.0", "bs4==0.0.2", "uvicorn==0.46.0", "markdown2==2.5.5", "requests==2.33.1", "plotly==6.7.0", "fastapi==0.136.1", "rjsmin==1.2.5", "rcssmin==1.2.2",]
|
|
10
10
|
license = "MPL-2.0"
|