Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyi_hashes.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"reflex/components/radix/primitives/progress.pyi": "c62a0c44e0d440701174fcca93bf8fbe",
"reflex/components/radix/primitives/slider.pyi": "10196fb967c9cde3860a930a526b6c51",
"reflex/components/radix/themes/__init__.pyi": "a15f9464ad99f248249ffa8e6deea4cf",
"reflex/components/radix/themes/base.pyi": "a3c3c3b72fd3d8f1e38990e5c461b682",
"reflex/components/radix/themes/base.pyi": "8487120ce233ad4a81cb8d03a004d7f2",
"reflex/components/radix/themes/color_mode.pyi": "e18fe42952d10f5733f3baf4789c4bb5",
"reflex/components/radix/themes/components/__init__.pyi": "87bb9ffff641928562da1622d2ca5993",
"reflex/components/radix/themes/components/alert_dialog.pyi": "8e1dde62450296310a116ed066bd51e3",
Expand Down
66 changes: 0 additions & 66 deletions reflex/.templates/jinja/web/tailwind.config.js.jinja2
Comment thread
adhami3310 marked this conversation as resolved.

This file was deleted.

1 change: 0 additions & 1 deletion reflex/.templates/web/postcss.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module.exports = {
plugins: {
"postcss-import": {},
tailwindcss: {},
autoprefixer: {},
},
};
6 changes: 0 additions & 6 deletions reflex/.templates/web/styles/tailwind.css

This file was deleted.

50 changes: 30 additions & 20 deletions reflex/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from pathlib import Path
from timeit import default_timer as timer
from types import SimpleNamespace
from typing import TYPE_CHECKING, Any, BinaryIO, get_args, get_type_hints
from typing import TYPE_CHECKING, Any, BinaryIO, ParamSpec, get_args, get_type_hints

from fastapi import FastAPI, HTTPException, Request
from fastapi import UploadFile as FastAPIUploadFile
Expand Down Expand Up @@ -308,6 +308,9 @@ def merged_with(self, other: UnevaluatedPage) -> UnevaluatedPage:
)


P = ParamSpec("P")


@dataclasses.dataclass()
class App(MiddlewareMixin, LifespanMixin):
"""The main Reflex app that encapsulates the backend and frontend.
Expand Down Expand Up @@ -599,10 +602,12 @@ def __call__(self) -> FastAPI:
compile_future = concurrent.futures.ThreadPoolExecutor(max_workers=1).submit(
self._compile
)
compile_future.add_done_callback(

def callback(f: concurrent.futures.Future):
# Force background compile errors to print eagerly
lambda f: f.result()
)
return f.result()

compile_future.add_done_callback(callback)
# Wait for the compile to finish in prod mode to ensure all optional endpoints are mounted.
if is_prod_mode():
compile_future.result()
Expand Down Expand Up @@ -961,11 +966,6 @@ def _get_frontend_packages(self, imports: dict[str, set[ImportVar]]):
frontend_packages = get_config().frontend_packages
_frontend_packages = []
for package in frontend_packages:
if package in (get_config().tailwind or {}).get("plugins", []):
console.warn(
f"Tailwind packages are inferred from 'plugins', remove `{package}` from `frontend_packages`"
)
continue
if package in page_imports:
console.warn(
f"React packages and their dependencies are inferred from Component.library and Component.lib_dependencies, remove `{package}` from `frontend_packages`"
Expand Down Expand Up @@ -1312,6 +1312,17 @@ def memoized_toast_provider():
),
)

for plugin in config.plugins:
for static_file_path, content in plugin.get_static_assets():
resulting_path = (
Path.cwd() / prerequisites.get_web_dir() / static_file_path
)
resulting_path.parent.mkdir(parents=True, exist_ok=True)
if isinstance(content, str):
resulting_path.write_text(content)
else:
resulting_path.write_bytes(content)

executor = ExecutorType.get_executor_from_environment()

for route, component in zip(self._pages, page_components, strict=True):
Expand All @@ -1320,9 +1331,13 @@ def memoized_toast_provider():
ExecutorSafeFunctions.STATE = self._state

with console.timing("Compile to Javascript"), executor as executor:
result_futures: list[concurrent.futures.Future[tuple[str, str]]] = []
result_futures: list[concurrent.futures.Future[tuple[str, str] | None]] = []

def _submit_work(fn: Callable[..., tuple[str, str]], *args, **kwargs):
def _submit_work(
fn: Callable[P, tuple[str, str] | None],
*args: P.args,
**kwargs: P.kwargs,
):
f = executor.submit(fn, *args, **kwargs)
f.add_done_callback(lambda _: progress.advance(task))
result_futures.append(f)
Expand All @@ -1340,19 +1355,14 @@ def _submit_work(fn: Callable[..., tuple[str, str]], *args, **kwargs):
# Compile the theme.
_submit_work(compile_theme, self.style)

# Compile the Tailwind config.
if config.tailwind is not None:
config.tailwind["content"] = config.tailwind.get(
"content", constants.Tailwind.CONTENT
)
_submit_work(compiler.compile_tailwind, config.tailwind)
else:
_submit_work(compiler.remove_tailwind_from_postcss)
for plugin in config.plugins:
plugin.pre_compile(add_task=_submit_work)

# Wait for all compilation tasks to complete.
compile_results.extend(
future.result()
result
for future in concurrent.futures.as_completed(result_futures)
if (result := future.result()) is not None
)

app_root = self._app_root(app_wrappers=app_wrappers)
Expand Down
66 changes: 6 additions & 60 deletions reflex/compiler/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,12 @@ def _compile_root_stylesheet(stylesheets: list[str]) -> str:
Raises:
FileNotFoundError: If a specified stylesheet in assets directory does not exist.
"""
# Add tailwind css if enabled.
sheets = (
[constants.Tailwind.ROOT_STYLE_PATH]
if get_config().tailwind is not None
else []
)
# Add stylesheets from plugins.
sheets = [
sheet
for plugin in get_config().plugins
for sheet in plugin.get_stylesheet_paths()
] + ["@radix-ui/themes/styles.css"]

failed_to_import_sass = False
assets_app_path = Path.cwd() / constants.Dirs.APP_ASSETS
Expand Down Expand Up @@ -437,22 +437,6 @@ def get_shared_components_recursive(component: BaseComponent):
)


def _compile_tailwind(
config: dict,
) -> str:
"""Compile the Tailwind config.

Args:
config: The Tailwind config.

Returns:
The compiled Tailwind config.
"""
return templates.TAILWIND_CONFIG.render(
**config,
)


def compile_document_root(
head_components: list[Component],
html_lang: str | None = None,
Expand Down Expand Up @@ -599,44 +583,6 @@ def compile_stateful_components(
return output_path, code, page_components


def compile_tailwind(
config: dict,
):
"""Compile the Tailwind config.

Args:
config: The Tailwind config.

Returns:
The compiled Tailwind config.
"""
# Get the path for the output file.
output_path = str((get_web_dir() / constants.Tailwind.CONFIG).absolute())

# Compile the config.
code = _compile_tailwind(config)
return output_path, code


def remove_tailwind_from_postcss() -> tuple[str, str]:
"""If tailwind is not to be used, remove it from postcss.config.js.

Returns:
The path and code of the compiled postcss.config.js.
"""
# Get the path for the output file.
output_path = str(get_web_dir() / constants.Dirs.POSTCSS_JS)

code = [
line
for line in Path(output_path).read_text().splitlines(keepends=True)
if "tailwindcss: " not in line
]

# Compile the config.
return output_path, "".join(code)


def purge_web_pages_dir():
"""Empty out .web/pages directory."""
if not is_prod_mode() and environment.REFLEX_PERSIST_WEB_DIR.get():
Expand Down
15 changes: 12 additions & 3 deletions reflex/compiler/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ def get_template(name: str) -> Template:
return ReflexJinjaEnvironment().get_template(name=name)


def from_string(source: str) -> Template:
"""Get render function that work with a template.

Args:
source: The template source.

Returns:
A render function.
"""
return ReflexJinjaEnvironment().from_string(source=source)


# Template for the Reflex config file.
RXCONFIG = get_template("app/rxconfig.py.jinja2")

Expand All @@ -113,9 +125,6 @@ def get_template(name: str) -> Template:
# Template for the context file.
CONTEXT = get_template("web/utils/context.js.jinja2")

# 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")

Expand Down
11 changes: 1 addition & 10 deletions reflex/components/radix/themes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from reflex.components import Component
from reflex.components.core.breakpoints import Responsive
from reflex.components.tags import Tag
from reflex.config import get_config
from reflex.utils.imports import ImportDict, ImportVar
from reflex.vars.base import Var

Expand Down Expand Up @@ -239,17 +238,9 @@ def add_imports(self) -> ImportDict | list[ImportDict]:
Returns:
The import dict.
"""
_imports: ImportDict = {
return {
"$/utils/theme.js": [ImportVar(tag="theme", is_default=True)],
}
if get_config().tailwind is None:
# When tailwind is disabled, import the radix-ui styles directly because they will
# not be included in the tailwind.css file.
_imports[""] = ImportVar(
tag="@radix-ui/themes/styles.css",
install=False,
)
return _imports

def _render(self, props: dict[str, Any] | None = None) -> Tag:
tag = super()._render(props)
Expand Down
8 changes: 8 additions & 0 deletions reflex/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
from reflex import constants
from reflex.base import Base
from reflex.constants.base import LogLevel
from reflex.plugins.base import Plugin
from reflex.plugins.tailwind_v3 import TailwindV3Plugin
from reflex.utils import console
from reflex.utils.exceptions import ConfigError, EnvironmentVarValueError
from reflex.utils.types import (
Expand Down Expand Up @@ -888,6 +890,9 @@ class Config: # pyright: ignore [reportIncompatibleVariableOverride]
# Extra overlay function to run after the app is built. Formatted such that `from path_0.path_1... import path[-1]`, and calling it with no arguments would work. For example, "reflex.components.moment.moment".
extra_overlay_function: str | None = None

# List of plugins to use in the app.
plugins: list[Plugin] = []

def __init__(self, *args, **kwargs):
"""Initialize the config values.

Expand Down Expand Up @@ -917,6 +922,9 @@ def __init__(self, *args, **kwargs):
self._non_default_attributes.update(kwargs)
self._replace_defaults(**kwargs)

if self.tailwind is not None:
self.plugins.append(TailwindV3Plugin())

if (
self.state_manager_mode == constants.StateManagerMode.REDIS
and not self.redis_url
Expand Down
2 changes: 0 additions & 2 deletions reflex/constants/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
RouteVar,
)
from .state import StateManagerMode
from .style import Tailwind

__all__ = [
"ALEMBIC_CONFIG",
Expand Down Expand Up @@ -113,6 +112,5 @@
"RouteVar",
"SocketEvent",
"StateManagerMode",
"Tailwind",
"Templates",
]
16 changes: 0 additions & 16 deletions reflex/constants/style.py

This file was deleted.

Loading
Loading