reflex 0.2.2a1__tar.gz → 0.2.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.
Potentially problematic release.
This version of reflex might be problematic. Click here for more details.
- {reflex-0.2.2a1 → reflex-0.2.3}/PKG-INFO +2 -2
- {reflex-0.2.2a1 → reflex-0.2.3}/README.md +1 -1
- {reflex-0.2.2a1 → reflex-0.2.3}/pyproject.toml +2 -2
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/apps/counter/counter.py +1 -1
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/apps/default/default.py +1 -1
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/web/utils/state.js +5 -1
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/__init__.py +1 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/app.py +40 -24
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/datadisplay/datatable.py +16 -19
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/navigation/breadcrumb.py +31 -8
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/tags/tag.py +40 -38
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/typography/heading.py +3 -0
- reflex-0.2.3/reflex/components/typography/markdown.py +155 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/config.py +0 -6
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/constants.py +59 -14
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/model.py +2 -2
- reflex-0.2.3/reflex/page.py +66 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/reflex.py +93 -79
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/route.py +11 -21
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/state.py +29 -12
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/testing.py +3 -1
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/utils/build.py +17 -61
- reflex-0.2.3/reflex/utils/console.py +168 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/utils/exec.py +25 -42
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/utils/format.py +19 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/utils/imports.py +1 -1
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/utils/prerequisites.py +242 -145
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/utils/processes.py +96 -16
- reflex-0.2.2a1/reflex/components/typography/markdown.py +0 -99
- reflex-0.2.2a1/reflex/utils/console.py +0 -78
- {reflex-0.2.2a1 → reflex-0.2.3}/LICENSE +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/apps/counter/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/apps/default/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/assets/favicon.ico +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/jinja/app/rxconfig.py.jinja2 +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/jinja/web/pages/_document.js.jinja2 +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/jinja/web/pages/base_page.js.jinja2 +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/jinja/web/pages/custom_component.js.jinja2 +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/jinja/web/pages/index.js.jinja2 +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/jinja/web/pages/utils.js.jinja2 +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/jinja/web/tailwind.config.js.jinja2 +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/jinja/web/utils/theme.js.jinja2 +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/web/.gitignore +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/web/bun.lockb +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/web/jsconfig.json +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/web/next.config.js +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/web/package.json +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/web/pages/404.js +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/web/pages/_app.js +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/web/postcss.config.js +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/web/styles/code/prism.js +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/.templates/web/styles/tailwind.css +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/admin.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/base.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/compiler/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/compiler/compiler.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/compiler/templates.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/compiler/utils.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/base/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/base/bare.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/base/body.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/base/document.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/base/head.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/base/link.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/base/meta.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/base/script.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/component.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/datadisplay/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/datadisplay/badge.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/datadisplay/code.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/datadisplay/divider.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/datadisplay/keyboard_key.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/datadisplay/list.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/datadisplay/stat.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/datadisplay/table.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/datadisplay/tag.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/disclosure/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/disclosure/accordion.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/disclosure/tabs.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/disclosure/transition.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/disclosure/visuallyhidden.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/feedback/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/feedback/alert.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/feedback/circularprogress.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/feedback/progress.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/feedback/skeleton.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/feedback/spinner.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/button.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/checkbox.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/colormodeswitch.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/copytoclipboard.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/date_picker.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/date_time_picker.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/debounce.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/editable.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/email.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/form.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/iconbutton.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/input.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/multiselect.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/numberinput.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/password.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/pininput.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/radio.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/rangeslider.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/select.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/slider.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/switch.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/textarea.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/forms/upload.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/graphing/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/graphing/plotly.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/graphing/victory.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/aspect_ratio.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/box.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/card.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/center.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/cond.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/container.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/flex.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/foreach.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/fragment.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/grid.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/html.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/responsive.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/spacer.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/stack.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/layout/wrap.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/libs/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/libs/chakra.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/libs/react_player.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/media/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/media/audio.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/media/avatar.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/media/icon.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/media/image.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/media/video.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/navigation/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/navigation/link.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/navigation/linkoverlay.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/navigation/nextlink.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/navigation/stepper.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/overlay/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/overlay/alertdialog.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/overlay/banner.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/overlay/drawer.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/overlay/menu.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/overlay/modal.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/overlay/popover.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/overlay/tooltip.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/tags/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/tags/cond_tag.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/tags/iter_tag.py +1 -1
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/tags/tagless.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/typography/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/typography/highlight.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/typography/span.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/components/typography/text.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/el/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/el/constants/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/el/constants/html.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/el/constants/react.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/el/constants/reflex.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/el/element.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/el/elements/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/el/precompile.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/event.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/middleware/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/middleware/hydrate_middleware.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/middleware/middleware.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/py.typed +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/style.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/utils/__init__.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/utils/path_ops.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/utils/telemetry.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/utils/types.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/utils/watch.py +0 -0
- {reflex-0.2.2a1 → reflex-0.2.3}/reflex/vars.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: reflex
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Web apps in pure Python.
|
|
5
5
|
Home-page: https://reflex.dev
|
|
6
6
|
License: Apache-2.0
|
|
@@ -67,7 +67,7 @@ Description-Content-Type: text/markdown
|
|
|
67
67
|
|
|
68
68
|
---
|
|
69
69
|
|
|
70
|
-
[English](README.md) | [简体中文](/docs/zh/zh_cn/README.md) | [繁體中文](/docs/zh/zh_tw/README.md)
|
|
70
|
+
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md)
|
|
71
71
|
|
|
72
72
|
---
|
|
73
73
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
26
|
-
[English](README.md) | [简体中文](/docs/zh/zh_cn/README.md) | [繁體中文](/docs/zh/zh_tw/README.md)
|
|
26
|
+
[English](https://github.com/reflex-dev/reflex/blob/main/README.md) | [简体中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_cn/README.md) | [繁體中文](https://github.com/reflex-dev/reflex/blob/main/docs/zh/zh_tw/README.md)
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "reflex"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.3"
|
|
4
4
|
description = "Web apps in pure Python."
|
|
5
5
|
license = "Apache-2.0"
|
|
6
6
|
authors = [
|
|
@@ -66,7 +66,7 @@ pre-commit = {version = "^3.2.1", python = ">=3.8,<4.0"}
|
|
|
66
66
|
selenium = "^4.10.0"
|
|
67
67
|
|
|
68
68
|
[tool.poetry.scripts]
|
|
69
|
-
reflex = "reflex.reflex:
|
|
69
|
+
reflex = "reflex.reflex:cli"
|
|
70
70
|
|
|
71
71
|
[build-system]
|
|
72
72
|
requires = ["poetry-core>=1.5.1"]
|
|
@@ -168,7 +168,8 @@ export const applyEvent = async (event, router, socket) => {
|
|
|
168
168
|
|
|
169
169
|
// Send the event to the server.
|
|
170
170
|
event.token = getToken();
|
|
171
|
-
event.router_data = (({ pathname, query }) => ({ pathname, query }))(router);
|
|
171
|
+
event.router_data = (({ pathname, query, asPath }) => ({ pathname, query, asPath }))(router);
|
|
172
|
+
|
|
172
173
|
if (socket) {
|
|
173
174
|
socket.emit("event", JSON.stringify(event));
|
|
174
175
|
return true;
|
|
@@ -382,6 +383,9 @@ export const preventDefault = (event) => {
|
|
|
382
383
|
* @returns The value.
|
|
383
384
|
*/
|
|
384
385
|
export const getRefValue = (ref) => {
|
|
386
|
+
if (!ref || !ref.current){
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
385
389
|
if (ref.current.type == "checkbox") {
|
|
386
390
|
return ref.current.checked;
|
|
387
391
|
} else {
|
|
@@ -36,6 +36,7 @@ from .event import window_alert as window_alert
|
|
|
36
36
|
from .middleware import Middleware as Middleware
|
|
37
37
|
from .model import Model as Model
|
|
38
38
|
from .model import session as session
|
|
39
|
+
from .page import page as page
|
|
39
40
|
from .route import route as route
|
|
40
41
|
from .state import ComputedVar as var
|
|
41
42
|
from .state import State as State
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import inspect
|
|
5
|
+
import os
|
|
5
6
|
from multiprocessing.pool import ThreadPool
|
|
6
7
|
from typing import (
|
|
7
8
|
Any,
|
|
@@ -34,15 +35,17 @@ from reflex.config import get_config
|
|
|
34
35
|
from reflex.event import Event, EventHandler, EventSpec
|
|
35
36
|
from reflex.middleware import HydrateMiddleware, Middleware
|
|
36
37
|
from reflex.model import Model
|
|
38
|
+
from reflex.page import (
|
|
39
|
+
DECORATED_PAGES,
|
|
40
|
+
)
|
|
37
41
|
from reflex.route import (
|
|
38
|
-
DECORATED_ROUTES,
|
|
39
42
|
catchall_in_route,
|
|
40
43
|
catchall_prefix,
|
|
41
44
|
get_route_args,
|
|
42
45
|
verify_route_validity,
|
|
43
46
|
)
|
|
44
47
|
from reflex.state import DefaultState, State, StateManager, StateUpdate
|
|
45
|
-
from reflex.utils import format, types
|
|
48
|
+
from reflex.utils import console, format, types
|
|
46
49
|
|
|
47
50
|
# Define custom types.
|
|
48
51
|
ComponentCallable = Callable[[], Component]
|
|
@@ -100,9 +103,29 @@ class App(Base):
|
|
|
100
103
|
|
|
101
104
|
Raises:
|
|
102
105
|
ValueError: If the event namespace is not provided in the config.
|
|
106
|
+
Also, if there are multiple client subclasses of rx.State(Subclasses of rx.State should consist
|
|
107
|
+
of the DefaultState and the client app state).
|
|
103
108
|
"""
|
|
104
109
|
super().__init__(*args, **kwargs)
|
|
110
|
+
state_subclasses = State.__subclasses__()
|
|
111
|
+
inferred_state = state_subclasses[-1]
|
|
112
|
+
is_testing_env = constants.PYTEST_CURRENT_TEST in os.environ
|
|
113
|
+
|
|
114
|
+
# Special case to allow test cases have multiple subclasses of rx.State.
|
|
115
|
+
if not is_testing_env:
|
|
116
|
+
# Only the default state and the client state should be allowed as subclasses.
|
|
117
|
+
if len(state_subclasses) > 2:
|
|
118
|
+
raise ValueError(
|
|
119
|
+
"rx.State has been subclassed multiple times. Only one subclass is allowed"
|
|
120
|
+
)
|
|
105
121
|
|
|
122
|
+
# verify that provided state is valid
|
|
123
|
+
if self.state not in [DefaultState, inferred_state]:
|
|
124
|
+
console.warn(
|
|
125
|
+
f"Using substate ({self.state.__name__}) as root state in `rx.App` is currently not supported."
|
|
126
|
+
f" Defaulting to root state: ({inferred_state.__name__})"
|
|
127
|
+
)
|
|
128
|
+
self.state = inferred_state
|
|
106
129
|
# Get the config
|
|
107
130
|
config = get_config()
|
|
108
131
|
|
|
@@ -414,14 +437,7 @@ class App(Base):
|
|
|
414
437
|
)
|
|
415
438
|
|
|
416
439
|
froute = format.format_route
|
|
417
|
-
|
|
418
|
-
not any(page.startswith("[[...") for page in self.pages)
|
|
419
|
-
):
|
|
420
|
-
self.pages[froute(constants.ROOT_404)] = component
|
|
421
|
-
if not any(
|
|
422
|
-
page.startswith("[...") or page.startswith("[[...") for page in self.pages
|
|
423
|
-
):
|
|
424
|
-
self.pages[froute(constants.SLUG_404)] = component
|
|
440
|
+
self.pages[froute(constants.SLUG_404)] = component
|
|
425
441
|
|
|
426
442
|
def setup_admin_dash(self):
|
|
427
443
|
"""Setup the admin dash."""
|
|
@@ -455,23 +471,23 @@ class App(Base):
|
|
|
455
471
|
)
|
|
456
472
|
task = progress.add_task("Compiling: ", total=len(self.pages))
|
|
457
473
|
|
|
458
|
-
|
|
474
|
+
# TODO: include all work done in progress indicator, not just self.pages
|
|
475
|
+
for render, kwargs in DECORATED_PAGES:
|
|
459
476
|
self.add_page(render, **kwargs)
|
|
460
477
|
|
|
461
478
|
# Get the env mode.
|
|
462
479
|
config = get_config()
|
|
463
480
|
|
|
464
|
-
# Empty the .web pages directory
|
|
465
|
-
compiler.purge_web_pages_dir()
|
|
466
|
-
|
|
467
481
|
# Store the compile results.
|
|
468
482
|
compile_results = []
|
|
469
483
|
|
|
470
484
|
# Compile the pages in parallel.
|
|
471
485
|
custom_components = set()
|
|
486
|
+
# TODO Anecdotally, processes=2 works 10% faster (cpu_count=12)
|
|
472
487
|
thread_pool = ThreadPool()
|
|
473
488
|
with progress:
|
|
474
489
|
for route, component in self.pages.items():
|
|
490
|
+
# TODO: this progress does not reflect actual threaded task completion
|
|
475
491
|
progress.advance(task)
|
|
476
492
|
component.add_style(self.style)
|
|
477
493
|
compile_results.append(
|
|
@@ -493,6 +509,8 @@ class App(Base):
|
|
|
493
509
|
# Get the results.
|
|
494
510
|
compile_results = [result.get() for result in compile_results]
|
|
495
511
|
|
|
512
|
+
# TODO the compile tasks below may also benefit from parallelization too
|
|
513
|
+
|
|
496
514
|
# Compile the custom components.
|
|
497
515
|
compile_results.append(compiler.compile_components(custom_components))
|
|
498
516
|
|
|
@@ -503,18 +521,18 @@ class App(Base):
|
|
|
503
521
|
compile_results.append(compiler.compile_theme(self.style))
|
|
504
522
|
|
|
505
523
|
# Compile the Tailwind config.
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
if config.tailwind is not None
|
|
510
|
-
else {}
|
|
524
|
+
if config.tailwind is not None:
|
|
525
|
+
config.tailwind["content"] = config.tailwind.get(
|
|
526
|
+
"content", constants.TAILWIND_CONTENT
|
|
511
527
|
)
|
|
512
|
-
|
|
528
|
+
compile_results.append(compiler.compile_tailwind(config.tailwind))
|
|
529
|
+
|
|
530
|
+
# Empty the .web pages directory
|
|
531
|
+
compiler.purge_web_pages_dir()
|
|
513
532
|
|
|
514
533
|
# Write the pages at the end to trigger the NextJS hot reload only once.
|
|
515
534
|
thread_pool = ThreadPool()
|
|
516
535
|
for output_path, code in compile_results:
|
|
517
|
-
compiler_utils.write_page(output_path, code)
|
|
518
536
|
thread_pool.apply_async(compiler_utils.write_page, args=(output_path, code))
|
|
519
537
|
thread_pool.close()
|
|
520
538
|
thread_pool.join()
|
|
@@ -647,9 +665,7 @@ def upload(app: App):
|
|
|
647
665
|
update = await app.postprocess(state, event, update)
|
|
648
666
|
# Send update to client
|
|
649
667
|
await asyncio.create_task(
|
|
650
|
-
app.event_namespace.emit( # type: ignore
|
|
651
|
-
str(constants.SocketEvent.EVENT), update.json(), to=sid
|
|
652
|
-
)
|
|
668
|
+
app.event_namespace.emit(str(constants.SocketEvent.EVENT), update.json(), to=sid) # type: ignore
|
|
653
669
|
)
|
|
654
670
|
# Set the state for the session.
|
|
655
671
|
app.state_manager.set_state(event.token, state)
|
|
@@ -101,25 +101,22 @@ class DataTable(Gridjs):
|
|
|
101
101
|
|
|
102
102
|
def _render(self) -> Tag:
|
|
103
103
|
if isinstance(self.data, Var):
|
|
104
|
-
self.
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if types.is_dataframe(type(self.data)):
|
|
121
|
-
self.columns = Var.create(list(self.data.columns.values.tolist())) # type: ignore
|
|
122
|
-
self.data = Var.create(format.format_dataframe_values(self.data)) # type: ignore
|
|
104
|
+
if types.is_dataframe(self.data.type_):
|
|
105
|
+
self.columns = BaseVar(
|
|
106
|
+
name=f"{self.data.name}.columns",
|
|
107
|
+
type_=List[Any],
|
|
108
|
+
state=self.data.state,
|
|
109
|
+
)
|
|
110
|
+
self.data = BaseVar(
|
|
111
|
+
name=f"{self.data.name}.data",
|
|
112
|
+
type_=List[List[Any]],
|
|
113
|
+
state=self.data.state,
|
|
114
|
+
)
|
|
115
|
+
else:
|
|
116
|
+
# If given a pandas df break up the data and columns
|
|
117
|
+
if types.is_dataframe(type(self.data)):
|
|
118
|
+
self.columns = Var.create(list(self.data.columns.values.tolist())) # type: ignore
|
|
119
|
+
self.data = Var.create(format.format_dataframe_values(self.data)) # type: ignore
|
|
123
120
|
|
|
124
121
|
# Render the table.
|
|
125
122
|
return super()._render()
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""Breadcrumb components."""
|
|
2
2
|
|
|
3
3
|
from reflex.components.component import Component
|
|
4
|
+
from reflex.components.layout.foreach import Foreach
|
|
4
5
|
from reflex.components.libs.chakra import ChakraComponent
|
|
6
|
+
from reflex.components.navigation.link import Link
|
|
5
7
|
from reflex.vars import Var
|
|
6
8
|
|
|
7
9
|
|
|
@@ -31,11 +33,18 @@ class Breadcrumb(ChakraComponent):
|
|
|
31
33
|
The breadcrumb component.
|
|
32
34
|
"""
|
|
33
35
|
if len(children) == 0:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
if isinstance(items, Var):
|
|
37
|
+
children = [
|
|
38
|
+
Foreach.create(
|
|
39
|
+
items,
|
|
40
|
+
lambda item: BreadcrumbItem.create(label=item[0], href=item[1]),
|
|
41
|
+
),
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
else:
|
|
45
|
+
children = []
|
|
46
|
+
for label, link in items or []:
|
|
47
|
+
children.append(BreadcrumbItem.create(label=label, href=link))
|
|
39
48
|
return super().create(*children, **props)
|
|
40
49
|
|
|
41
50
|
|
|
@@ -56,8 +65,22 @@ class BreadcrumbItem(ChakraComponent):
|
|
|
56
65
|
# The left and right margin applied to the separator
|
|
57
66
|
spacing: Var[str]
|
|
58
67
|
|
|
59
|
-
|
|
60
|
-
href:
|
|
68
|
+
@classmethod
|
|
69
|
+
def create(cls, *children, label=None, href=None, **props):
|
|
70
|
+
"""Create a Breadcrumb Item component.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
children: The children of the component.
|
|
74
|
+
label: The label used in the link. Defaults to None.
|
|
75
|
+
href: The URL of the link. Defaults to None.
|
|
76
|
+
props: The properties of the component.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
The BreadcrumbItem component
|
|
80
|
+
"""
|
|
81
|
+
if len(children) == 0:
|
|
82
|
+
children = [BreadcrumbLink.create(label or "", href=href or "")] # type: ignore
|
|
83
|
+
return super().create(*children, **props)
|
|
61
84
|
|
|
62
85
|
|
|
63
86
|
class BreadcrumbSeparator(ChakraComponent):
|
|
@@ -66,7 +89,7 @@ class BreadcrumbSeparator(ChakraComponent):
|
|
|
66
89
|
tag = "BreadcrumbSeparator"
|
|
67
90
|
|
|
68
91
|
|
|
69
|
-
class BreadcrumbLink(
|
|
92
|
+
class BreadcrumbLink(Link):
|
|
70
93
|
"""The breadcrumb link."""
|
|
71
94
|
|
|
72
95
|
tag = "BreadcrumbLink"
|
|
@@ -67,46 +67,48 @@ class Tag(Base):
|
|
|
67
67
|
Raises:
|
|
68
68
|
TypeError: If the prop is not a valid type.
|
|
69
69
|
"""
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
70
|
+
try:
|
|
71
|
+
# Handle var props.
|
|
72
|
+
if isinstance(prop, Var):
|
|
73
|
+
if not prop.is_local or prop.is_string:
|
|
74
|
+
return str(prop)
|
|
75
|
+
if types._issubclass(prop.type_, str):
|
|
76
|
+
return format.json_dumps(prop.full_name)
|
|
77
|
+
prop = prop.full_name
|
|
78
|
+
|
|
79
|
+
# Handle event props.
|
|
80
|
+
elif isinstance(prop, EventChain):
|
|
81
|
+
if prop.full_control:
|
|
82
|
+
# Full control component events.
|
|
83
|
+
event = format.format_full_control_event(prop)
|
|
84
|
+
else:
|
|
85
|
+
# All other events.
|
|
86
|
+
chain = ",".join(
|
|
87
|
+
[format.format_event(event) for event in prop.events]
|
|
88
|
+
)
|
|
89
|
+
event = f"Event([{chain}], {EVENT_ARG})"
|
|
90
|
+
prop = f"{EVENT_ARG} => {event}"
|
|
91
|
+
|
|
92
|
+
# Handle other types.
|
|
93
|
+
elif isinstance(prop, str):
|
|
94
|
+
if format.is_wrapped(prop, "{"):
|
|
95
|
+
return prop
|
|
96
|
+
return format.json_dumps(prop)
|
|
97
|
+
|
|
98
|
+
elif isinstance(prop, Figure):
|
|
99
|
+
prop = json.loads(to_json(prop))["data"] # type: ignore
|
|
100
|
+
|
|
101
|
+
# For dictionaries, convert any properties to strings.
|
|
102
|
+
elif isinstance(prop, dict):
|
|
103
|
+
prop = format.format_dict(prop)
|
|
104
|
+
|
|
83
105
|
else:
|
|
84
|
-
#
|
|
85
|
-
chain = ",".join([format.format_event(event) for event in prop.events])
|
|
86
|
-
event = f"Event([{chain}], {EVENT_ARG})"
|
|
87
|
-
prop = f"{EVENT_ARG} => {event}"
|
|
88
|
-
|
|
89
|
-
# Handle other types.
|
|
90
|
-
elif isinstance(prop, str):
|
|
91
|
-
if format.is_wrapped(prop, "{"):
|
|
92
|
-
return prop
|
|
93
|
-
return format.json_dumps(prop)
|
|
94
|
-
|
|
95
|
-
elif isinstance(prop, Figure):
|
|
96
|
-
prop = json.loads(to_json(prop))["data"] # type: ignore
|
|
97
|
-
|
|
98
|
-
# For dictionaries, convert any properties to strings.
|
|
99
|
-
elif isinstance(prop, dict):
|
|
100
|
-
prop = format.format_dict(prop)
|
|
101
|
-
|
|
102
|
-
else:
|
|
103
|
-
# Dump the prop as JSON.
|
|
104
|
-
try:
|
|
106
|
+
# Dump the prop as JSON.
|
|
105
107
|
prop = format.json_dumps(prop)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
except TypeError as e:
|
|
109
|
+
raise TypeError(
|
|
110
|
+
f"Could not format prop: {prop} of type {type(prop)}"
|
|
111
|
+
) from e
|
|
110
112
|
|
|
111
113
|
# Wrap the variable in braces.
|
|
112
114
|
assert isinstance(prop, str), "The prop must be a string."
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""Markdown component."""
|
|
2
|
+
|
|
3
|
+
import textwrap
|
|
4
|
+
from typing import Callable, Dict, List, Union
|
|
5
|
+
|
|
6
|
+
from reflex.compiler import utils
|
|
7
|
+
from reflex.components.component import Component
|
|
8
|
+
from reflex.components.datadisplay.list import ListItem, OrderedList, UnorderedList
|
|
9
|
+
from reflex.components.navigation import Link
|
|
10
|
+
from reflex.components.typography.heading import Heading
|
|
11
|
+
from reflex.components.typography.text import Text
|
|
12
|
+
from reflex.style import Style
|
|
13
|
+
from reflex.utils import types
|
|
14
|
+
from reflex.vars import BaseVar, ImportVar, Var
|
|
15
|
+
|
|
16
|
+
# Mapping from markdown tags to components.
|
|
17
|
+
components_by_tag: Dict[str, Callable] = {
|
|
18
|
+
"h1": Heading,
|
|
19
|
+
"h2": Heading,
|
|
20
|
+
"h3": Heading,
|
|
21
|
+
"h4": Heading,
|
|
22
|
+
"h5": Heading,
|
|
23
|
+
"h6": Heading,
|
|
24
|
+
"p": Text,
|
|
25
|
+
"ul": UnorderedList,
|
|
26
|
+
"ol": OrderedList,
|
|
27
|
+
"li": ListItem,
|
|
28
|
+
"a": Link,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Markdown(Component):
|
|
33
|
+
"""A markdown component."""
|
|
34
|
+
|
|
35
|
+
library = "react-markdown"
|
|
36
|
+
|
|
37
|
+
tag = "ReactMarkdown"
|
|
38
|
+
|
|
39
|
+
is_default = True
|
|
40
|
+
|
|
41
|
+
# Custom defined styles for the markdown elements.
|
|
42
|
+
custom_styles: Dict[str, Style] = {
|
|
43
|
+
k: Style(v)
|
|
44
|
+
for k, v in {
|
|
45
|
+
"h1": {
|
|
46
|
+
"as_": "h1",
|
|
47
|
+
"size": "2xl",
|
|
48
|
+
},
|
|
49
|
+
"h2": {
|
|
50
|
+
"as_": "h2",
|
|
51
|
+
"size": "xl",
|
|
52
|
+
},
|
|
53
|
+
"h3": {
|
|
54
|
+
"as_": "h3",
|
|
55
|
+
"size": "lg",
|
|
56
|
+
},
|
|
57
|
+
"h4": {
|
|
58
|
+
"as_": "h4",
|
|
59
|
+
"size": "md",
|
|
60
|
+
},
|
|
61
|
+
"h5": {
|
|
62
|
+
"as_": "h5",
|
|
63
|
+
"size": "sm",
|
|
64
|
+
},
|
|
65
|
+
"h6": {
|
|
66
|
+
"as_": "h6",
|
|
67
|
+
"size": "xs",
|
|
68
|
+
},
|
|
69
|
+
}.items()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@classmethod
|
|
73
|
+
def create(cls, *children, **props) -> Component:
|
|
74
|
+
"""Create a markdown component.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
children: The children of the component.
|
|
78
|
+
props: The properties of the component.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
The markdown component.
|
|
82
|
+
"""
|
|
83
|
+
assert len(children) == 1 and types._isinstance(
|
|
84
|
+
children[0], Union[str, Var]
|
|
85
|
+
), "Markdown component must have exactly one child containing the markdown source."
|
|
86
|
+
|
|
87
|
+
# Get the markdown source.
|
|
88
|
+
src = children[0]
|
|
89
|
+
if isinstance(src, str):
|
|
90
|
+
src = textwrap.dedent(src)
|
|
91
|
+
return super().create(src, **props)
|
|
92
|
+
|
|
93
|
+
def _get_imports(self):
|
|
94
|
+
from reflex.components.datadisplay.code import Code, CodeBlock
|
|
95
|
+
|
|
96
|
+
imports = super()._get_imports()
|
|
97
|
+
|
|
98
|
+
# Special markdown imports.
|
|
99
|
+
imports["remark-math"] = {ImportVar(tag="remarkMath", is_default=True)}
|
|
100
|
+
imports["remark-gfm"] = {ImportVar(tag="remarkGfm", is_default=True)}
|
|
101
|
+
imports["rehype-katex"] = {ImportVar(tag="rehypeKatex", is_default=True)}
|
|
102
|
+
imports["rehype-raw"] = {ImportVar(tag="rehypeRaw", is_default=True)}
|
|
103
|
+
imports[""] = {ImportVar(tag="katex/dist/katex.min.css")}
|
|
104
|
+
|
|
105
|
+
# Get the imports for each component.
|
|
106
|
+
for component in components_by_tag.values():
|
|
107
|
+
imports = utils.merge_imports(imports, component()._get_imports())
|
|
108
|
+
|
|
109
|
+
# Get the imports for the code components.
|
|
110
|
+
imports = utils.merge_imports(
|
|
111
|
+
imports, CodeBlock.create(theme="light")._get_imports()
|
|
112
|
+
)
|
|
113
|
+
imports = utils.merge_imports(imports, Code.create()._get_imports())
|
|
114
|
+
return imports
|
|
115
|
+
|
|
116
|
+
def _render(self):
|
|
117
|
+
from reflex.components.tags.tag import Tag
|
|
118
|
+
|
|
119
|
+
components = {
|
|
120
|
+
tag: f"{{({{node, ...props}}) => <{(component().tag)} {{...props}} {''.join(Tag(name='', props=Style(self.custom_styles.get(tag, {}))).format_props())} />}}"
|
|
121
|
+
for tag, component in components_by_tag.items()
|
|
122
|
+
}
|
|
123
|
+
components[
|
|
124
|
+
"code"
|
|
125
|
+
] = """{({node, inline, className, children, ...props}) =>
|
|
126
|
+
{
|
|
127
|
+
const match = (className || '').match(/language-(?<lang>.*)/);
|
|
128
|
+
return !inline ? (
|
|
129
|
+
<Prism
|
|
130
|
+
children={String(children).replace(/\n$/, '')}
|
|
131
|
+
language={match ? match[1] : ''}
|
|
132
|
+
theme={light}
|
|
133
|
+
{...props}
|
|
134
|
+
/>
|
|
135
|
+
) : (
|
|
136
|
+
<Code {...props}>
|
|
137
|
+
{children}
|
|
138
|
+
</Code>
|
|
139
|
+
);
|
|
140
|
+
}}""".replace(
|
|
141
|
+
"\n", " "
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
return (
|
|
145
|
+
super()
|
|
146
|
+
._render()
|
|
147
|
+
.add_props(
|
|
148
|
+
components=components,
|
|
149
|
+
remark_plugins=BaseVar(name="[remarkMath, remarkGfm]", type_=List[str]),
|
|
150
|
+
rehype_plugins=BaseVar(
|
|
151
|
+
name="[rehypeKatex, rehypeRaw]", type_=List[str]
|
|
152
|
+
),
|
|
153
|
+
)
|
|
154
|
+
.remove_props("custom_components")
|
|
155
|
+
)
|
|
@@ -165,12 +165,6 @@ class Config(Base):
|
|
|
165
165
|
# The environment mode.
|
|
166
166
|
env: constants.Env = constants.Env.DEV
|
|
167
167
|
|
|
168
|
-
# The path to the bun executable.
|
|
169
|
-
bun_path: str = constants.BUN_PATH
|
|
170
|
-
|
|
171
|
-
# Disable bun.
|
|
172
|
-
disable_bun: bool = False
|
|
173
|
-
|
|
174
168
|
# Additional frontend packages to install.
|
|
175
169
|
frontend_packages: List[str] = []
|
|
176
170
|
|