Skip to content

Commit

Permalink
Merge branch 'main' into lendemor/improve_triggers_api
Browse files Browse the repository at this point in the history
  • Loading branch information
Lendemor committed Sep 21, 2023
2 parents 9af5b0f + 0cd7242 commit 2450e1a
Show file tree
Hide file tree
Showing 24 changed files with 781 additions and 538 deletions.
96 changes: 85 additions & 11 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ alembic = "^1.11.1"
platformdirs = "^3.10.0"
distro = {version = "^1.8.0", platform = "linux"}
python-engineio = "!=4.6.0"
wrapt = "^1.15.0"
packaging = "^23.1"

[tool.poetry.group.dev.dependencies]
pytest = "^7.1.2"
Expand Down
2 changes: 2 additions & 0 deletions reflex/.templates/jinja/web/pages/component.js.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{% import 'web/pages/utils.js.jinja2' as utils %}
{{utils.render(component.render())}}
3 changes: 1 addition & 2 deletions reflex/.templates/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
},
"devDependencies": {
"autoprefixer": "^10.4.14",
"postcss": "^8.4.24",
"tailwindcss": "^3.3.2"
"postcss": "^8.4.24"
}
}
6 changes: 4 additions & 2 deletions reflex/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
)
from reflex.state import DefaultState, State, StateManager, StateUpdate
from reflex.utils import console, format, prerequisites, types
from reflex.vars import ImportVar

# Define custom types.
ComponentCallable = Callable[[], Component]
Expand Down Expand Up @@ -508,7 +509,7 @@ def setup_admin_dash(self):

admin.mount_to(self.api)

def get_frontend_packages(self, imports: Dict[str, str]):
def get_frontend_packages(self, imports: Dict[str, set[ImportVar]]):
"""Gets the frontend packages to be installed and filters out the unnecessary ones.
Args:
Expand All @@ -519,13 +520,14 @@ def get_frontend_packages(self, imports: Dict[str, str]):
"""
page_imports = {
i
for i in imports
for i, tags in imports.items()
if i not in compiler.DEFAULT_IMPORTS.keys()
and i != "focus-visible/dist/focus-visible"
and "next" not in i
and not i.startswith("/")
and not i.startswith(".")
and i != ""
and any(tag.install for tag in tags)
}
frontend_packages = get_config().frontend_packages
_frontend_packages = []
Expand Down
20 changes: 19 additions & 1 deletion reflex/compiler/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from reflex import constants
from reflex.compiler import templates, utils
from reflex.components.component import Component, ComponentStyle, CustomComponent
from reflex.config import get_config
from reflex.state import State
from reflex.utils import imports
from reflex.vars import ImportVar
Expand Down Expand Up @@ -148,7 +149,12 @@ def _compile_root_stylesheet(stylesheets: List[str]) -> str:
Raises:
FileNotFoundError: If a specified stylesheet in assets directory does not exist.
"""
sheets = [constants.TAILWIND_ROOT_STYLE_PATH]
# Add tailwind css if enabled.
sheets = (
[constants.TAILWIND_ROOT_STYLE_PATH]
if get_config().tailwind is not None
else []
)
for stylesheet in stylesheets:
if not utils.is_valid_url(stylesheet):
# check if stylesheet provided exists.
Expand All @@ -164,6 +170,18 @@ def _compile_root_stylesheet(stylesheets: List[str]) -> str:
return templates.STYLE.render(stylesheets=sheets)


def _compile_component(component: Component) -> str:
"""Compile a single component.
Args:
component: The component to compile.
Returns:
The compiled component.
"""
return templates.COMPONENT.render(component=component)


def _compile_components(components: Set[CustomComponent]) -> str:
"""Compile the components.
Expand Down
3 changes: 3 additions & 0 deletions reflex/compiler/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ def get_template(name: str) -> Template:
# Template for Tailwind config.
TAILWIND_CONFIG = get_template("web/tailwind.config.js.jinja2")

# Template to render a component tag.
COMPONENT = get_template("web/pages/component.js.jinja2")

# Code to render a single NextJS page.
PAGE = get_template("web/pages/index.js.jinja2")

Expand Down
11 changes: 6 additions & 5 deletions reflex/compiler/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from reflex.state import Cookie, LocalStorage, State
from reflex.style import Style
from reflex.utils import format, imports, path_ops
from reflex.vars import ImportVar, NoRenderImportVar
from reflex.vars import ImportVar

# To re-export this function.
merge_imports = imports.merge_imports
Expand All @@ -42,8 +42,8 @@ def compile_import_statement(fields: Set[ImportVar]) -> Tuple[str, Set[str]]:
default: default library. When install "import def from library".
rest: rest of libraries. When install "import {rest1, rest2} from library"
"""
# ignore the NoRenderImportVar fields during compilation
fields = {field for field in fields if not isinstance(field, NoRenderImportVar)}
# ignore the ImportVar fields with render=False during compilation
fields = {field for field in fields if field.render}

# Check for default imports.
defaults = {field for field in fields if field.is_default}
Expand Down Expand Up @@ -91,8 +91,9 @@ def compile_imports(imports: imports.ImportDict) -> List[dict]:
import_dicts = []
for lib, fields in imports.items():
default, rest = compile_import_statement(fields)
# prevent lib from being rendered on the page if all imports are NoRenderImportVar
if all({isinstance(f, NoRenderImportVar) for f in fields}): # type: ignore

# prevent lib from being rendered on the page if all imports are non rendered kind
if all({not f.render for f in fields}): # type: ignore
continue

if not lib:
Expand Down
24 changes: 15 additions & 9 deletions reflex/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
)
from reflex.style import Style
from reflex.utils import console, format, imports, types
from reflex.vars import BaseVar, ImportVar, NoRenderImportVar, Var
from reflex.vars import BaseVar, ImportVar, Var


class Component(Base, ABC):
Expand Down Expand Up @@ -364,7 +364,9 @@ def __str__(self) -> str:
Returns:
The code to render the component.
"""
return format.json_dumps(self.render())
from reflex.compiler.compiler import _compile_component

return _compile_component(self)

def _render(self) -> Tag:
"""Define how to render the component in React.
Expand Down Expand Up @@ -592,13 +594,16 @@ def get_dynamic_imports(self) -> Set[str]:
# Return the dynamic imports
return dynamic_imports

def _get_dependencies_imports(self):
return {
dep: {ImportVar(tag=None, render=False)} for dep in self.lib_dependencies
}

def _get_imports(self) -> imports.ImportDict:
imports = {}
if self.library is not None and self.tag is not None:
imports[self.library] = {self.import_var}
for dep in self.lib_dependencies:
imports[dep] = {NoRenderImportVar()} # type: ignore
return imports
return {**imports, **self._get_dependencies_imports()}

def get_imports(self) -> imports.ImportDict:
"""Get all the libraries and fields that are used by the component.
Expand Down Expand Up @@ -916,10 +921,11 @@ class NoSSRComponent(Component):
def _get_imports(self):
imports = {"next/dynamic": {ImportVar(tag="dynamic", is_default=True)}}

for dep in [self.library, *self.lib_dependencies]:
imports[dep] = {NoRenderImportVar()} # type: ignore

return imports
return {
**imports,
self.library: {ImportVar(tag=None, render=False)},
**self._get_dependencies_imports(),
}

def _get_dynamic_imports(self) -> str:
opts_fragment = ", { ssr: false });"
Expand Down
11 changes: 1 addition & 10 deletions reflex/components/tags/tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,7 @@ def format_props(self) -> List:
Returns:
The formatted props list.
"""
# If there are no props, return an empty string.
if len(self.props) == 0:
return []

# Format all the props.
return [
f"{name}={format.format_prop(prop)}"
for name, prop in sorted(self.props.items())
if prop is not None
] + [str(prop) for prop in self.special_props]
return format.format_props(*self.special_props, **self.props)

def add_props(self, **kwargs: Optional[Any]) -> Tag:
"""Add props to the tag.
Expand Down
65 changes: 36 additions & 29 deletions reflex/components/typography/markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,6 @@ class Markdown(Component):

library = "react-markdown@^8.0.7"

lib_dependencies: List[str] = [
"rehype-katex@^6.0.3",
"remark-math@^5.1.1",
"rehype-raw@^6.1.1",
"remark-gfm@^3.0.1",
]

tag = "ReactMarkdown"

is_default = True
Expand Down Expand Up @@ -98,16 +91,21 @@ def create(cls, *children, **props) -> Component:
return super().create(src, **props)

def _get_imports(self):
# Import here to avoid circular imports.
from reflex.components.datadisplay.code import Code, CodeBlock

imports = super()._get_imports()

# Special markdown imports.
imports["remark-math"] = {ImportVar(tag="remarkMath", is_default=True)}
imports["remark-gfm"] = {ImportVar(tag="remarkGfm", is_default=True)}
imports["rehype-katex"] = {ImportVar(tag="rehypeKatex", is_default=True)}
imports["rehype-raw"] = {ImportVar(tag="rehypeRaw", is_default=True)}
imports[""] = {ImportVar(tag="katex/dist/katex.min.css")}
imports.update(
{
"": {ImportVar(tag="katex/dist/katex.min.css")},
"rehype-katex@^6.0.3": {ImportVar(tag="rehypeKatex", is_default=True)},
"remark-math@^5.1.1": {ImportVar(tag="remarkMath", is_default=True)},
"rehype-raw@^6.1.1": {ImportVar(tag="rehypeRaw", is_default=True)},
"remark-gfm@^3.0.1": {ImportVar(tag="remarkGfm", is_default=True)},
}
)

# Get the imports for each component.
for component in components_by_tag.values():
Expand All @@ -121,30 +119,39 @@ def _get_imports(self):
return imports

def _render(self):
# Import here to avoid circular imports.
from reflex.components.datadisplay.code import Code, CodeBlock
from reflex.components.tags.tag import Tag

def format_props(tag):
return "".join(
Tag(
name="", props=Style(self.custom_styles.get(tag, {}))
).format_props()
)

components = {
tag: f"{{({{node, ...props}}) => <{(component().tag)} {{...props}} {''.join(Tag(name='', props=Style(self.custom_styles.get(tag, {}))).format_props())} />}}"
tag: f"{{({{node, ...props}}) => <{(component().tag)} {{...props}} {format_props(tag)} />}}"
for tag, component in components_by_tag.items()
}
components[
"code"
] = """{({node, inline, className, children, ...props}) =>
{
const match = (className || '').match(/language-(?<lang>.*)/);
return !inline ? (
<Prism
children={String(children).replace(/\n$/, '')}
language={match ? match[1] : ''}
theme={light}
{...props}
/>
) : (
<Code {...props}>
{children}
</Code>
);
}}""".replace(
] = f"""{{({{node, inline, className, children, ...props}}) => {{
const match = (className || '').match(/language-(?<lang>.*)/);
return !inline ? (
<{CodeBlock().tag}
children={{String(children).replace(/\n$/, '')}}
language={{match ? match[1] : ''}}
style={{light}}
{{...props}}
{format_props("pre")}
/>
) : (
<{Code.create().tag} {{...props}} {format_props("code")}>
{{children}}
</{Code.create().tag}>
);
}}}}""".replace(
"\n", " "
)

Expand Down
2 changes: 1 addition & 1 deletion reflex/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class Config:
cors_allowed_origins: List[str] = ["*"]

# Tailwind config.
tailwind: Optional[Dict[str, Any]] = None
tailwind: Optional[Dict[str, Any]] = {}

# Timeout when launching the gunicorn server. TODO(rename this to backend_timeout?)
timeout: int = 120
Expand Down
2 changes: 2 additions & 0 deletions reflex/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ def get_fnm_name() -> str | None:
TAILWIND_CONTENT = ["./pages/**/*.{js,ts,jsx,tsx}"]
# Relative tailwind style path to root stylesheet in STYLES_DIR.
TAILWIND_ROOT_STYLE_PATH = "./tailwind.css"
# The Tailwindcss version
TAILWIND_VERSION = "tailwindcss@^3.3.2"
# The NextJS config file
NEXT_CONFIG_FILE = "next.config.js"
# The sitemap config file.
Expand Down
Loading

0 comments on commit 2450e1a

Please sign in to comment.