[REF-3004] Use relative path to stylesheet for postcss-import compat (#3435)
* test_tailwind: include custom stylesheet * [REF-3004] Use relative path to stylesheet for postcss-import compat postcss-import balls all of the CSS up into a single file, which happens at compile time. So, replace the `@/` with `../public` so the import paths can be resolved relative to the `styles` directory. * test_compiler: fix compile_stylesheets expectations * Use constants.Dirs.PUBLIC instead of "public"
This commit is contained in:
parent
8df959dc43
commit
1f3fee598b
@ -25,6 +25,8 @@ def TailwindApp(
|
|||||||
paragraph_text: Text for the paragraph.
|
paragraph_text: Text for the paragraph.
|
||||||
paragraph_class_name: Tailwind class_name for the paragraph.
|
paragraph_class_name: Tailwind class_name for the paragraph.
|
||||||
"""
|
"""
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import reflex as rx
|
import reflex as rx
|
||||||
|
|
||||||
class UnusedState(rx.State):
|
class UnusedState(rx.State):
|
||||||
@ -35,10 +37,15 @@ def TailwindApp(
|
|||||||
rx.chakra.text(paragraph_text, class_name=paragraph_class_name),
|
rx.chakra.text(paragraph_text, class_name=paragraph_class_name),
|
||||||
rx.el.p(paragraph_text, class_name=paragraph_class_name),
|
rx.el.p(paragraph_text, class_name=paragraph_class_name),
|
||||||
rx.text(paragraph_text, as_="p", class_name=paragraph_class_name),
|
rx.text(paragraph_text, as_="p", class_name=paragraph_class_name),
|
||||||
|
rx.el.div("Test external stylesheet", class_name="external"),
|
||||||
id="p-content",
|
id="p-content",
|
||||||
)
|
)
|
||||||
|
|
||||||
app = rx.App(style={"font_family": "monospace"})
|
assets = Path(__file__).resolve().parent.parent / "assets"
|
||||||
|
assets.mkdir(exist_ok=True)
|
||||||
|
stylesheet = assets / "test_styles.css"
|
||||||
|
stylesheet.write_text(".external { color: rgba(0, 0, 255, 0.5) }")
|
||||||
|
app = rx.App(style={"font_family": "monospace"}, stylesheets=[stylesheet.name])
|
||||||
app.add_page(index)
|
app.add_page(index)
|
||||||
if tailwind_disabled:
|
if tailwind_disabled:
|
||||||
config = rx.config.get_config()
|
config = rx.config.get_config()
|
||||||
@ -107,3 +114,9 @@ def test_tailwind_app(tailwind_app: AppHarness, tailwind_disabled: bool):
|
|||||||
else:
|
else:
|
||||||
# expect "text-red-500" from tailwind utility class
|
# expect "text-red-500" from tailwind utility class
|
||||||
assert p.value_of_css_property("color") in TEXT_RED_500_COLOR
|
assert p.value_of_css_property("color") in TEXT_RED_500_COLOR
|
||||||
|
|
||||||
|
# Assert external stylesheet is applying rules
|
||||||
|
external = driver.find_elements(By.CLASS_NAME, "external")
|
||||||
|
assert len(external) == 1
|
||||||
|
for ext_div in external:
|
||||||
|
assert ext_div.value_of_css_property("color") == "rgba(0, 0, 255, 0.5)"
|
||||||
|
@ -169,7 +169,7 @@ def _compile_root_stylesheet(stylesheets: list[str]) -> str:
|
|||||||
raise FileNotFoundError(
|
raise FileNotFoundError(
|
||||||
f"The stylesheet file {stylesheet_full_path} does not exist."
|
f"The stylesheet file {stylesheet_full_path} does not exist."
|
||||||
)
|
)
|
||||||
stylesheet = f"@/{stylesheet.strip('/')}"
|
stylesheet = f"../{constants.Dirs.PUBLIC}/{stylesheet.strip('/')}"
|
||||||
sheets.append(stylesheet) if stylesheet not in sheets else None
|
sheets.append(stylesheet) if stylesheet not in sheets else None
|
||||||
return templates.STYLE.render(stylesheets=sheets)
|
return templates.STYLE.render(stylesheets=sheets)
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@ class Dirs(SimpleNamespace):
|
|||||||
UTILS = "utils"
|
UTILS = "utils"
|
||||||
# The name of the output static directory.
|
# The name of the output static directory.
|
||||||
STATIC = "_static"
|
STATIC = "_static"
|
||||||
|
# The name of the public html directory served at "/"
|
||||||
|
PUBLIC = "public"
|
||||||
# The name of the state file.
|
# The name of the state file.
|
||||||
STATE_PATH = "/".join([UTILS, "state"])
|
STATE_PATH = "/".join([UTILS, "state"])
|
||||||
# The name of the components file.
|
# The name of the components file.
|
||||||
@ -40,7 +42,7 @@ class Dirs(SimpleNamespace):
|
|||||||
# The directory where the utils file is located.
|
# The directory where the utils file is located.
|
||||||
WEB_UTILS = os.path.join(WEB, UTILS)
|
WEB_UTILS = os.path.join(WEB, UTILS)
|
||||||
# The directory where the assets are located.
|
# The directory where the assets are located.
|
||||||
WEB_ASSETS = os.path.join(WEB, "public")
|
WEB_ASSETS = os.path.join(WEB, PUBLIC)
|
||||||
# The env json file.
|
# The env json file.
|
||||||
ENV_JSON = os.path.join(WEB, "env.json")
|
ENV_JSON = os.path.join(WEB, "env.json")
|
||||||
# The reflex json file.
|
# The reflex json file.
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
"""Stub file for reflex/constants/base.py"""
|
|
||||||
# ------------------- DO NOT EDIT ----------------------
|
|
||||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
|
||||||
# ------------------------------------------------------
|
|
||||||
|
|
||||||
from typing import Any, Dict, Literal, Optional, Union, overload
|
|
||||||
from reflex.vars import Var, BaseVar, ComputedVar
|
|
||||||
from reflex.event import EventChain, EventHandler, EventSpec
|
|
||||||
from reflex.style import Style
|
|
||||||
import os
|
|
||||||
import platform
|
|
||||||
from enum import Enum
|
|
||||||
from importlib import metadata
|
|
||||||
from types import SimpleNamespace
|
|
||||||
from platformdirs import PlatformDirs
|
|
||||||
|
|
||||||
IS_WINDOWS = platform.system() == "Windows"
|
|
||||||
IS_WINDOWS_BUN_SUPPORTED_MACHINE = IS_WINDOWS and platform.machine() in [
|
|
||||||
"AMD64",
|
|
||||||
"x86_64",
|
|
||||||
]
|
|
||||||
|
|
||||||
class Dirs(SimpleNamespace):
|
|
||||||
WEB = ".web"
|
|
||||||
APP_ASSETS = "assets"
|
|
||||||
EXTERNAL_APP_ASSETS = "external"
|
|
||||||
UTILS = "utils"
|
|
||||||
STATIC = "_static"
|
|
||||||
STATE_PATH = "/".join([UTILS, "state"])
|
|
||||||
COMPONENTS_PATH = "/".join([UTILS, "components"])
|
|
||||||
CONTEXTS_PATH = "/".join([UTILS, "context"])
|
|
||||||
WEB_PAGES = os.path.join(WEB, "pages")
|
|
||||||
WEB_STATIC = os.path.join(WEB, STATIC)
|
|
||||||
WEB_UTILS = os.path.join(WEB, UTILS)
|
|
||||||
WEB_ASSETS = os.path.join(WEB, "public")
|
|
||||||
ENV_JSON = os.path.join(WEB, "env.json")
|
|
||||||
REFLEX_JSON = os.path.join(WEB, "reflex.json")
|
|
||||||
POSTCSS_JS = os.path.join(WEB, "postcss.config.js")
|
|
||||||
|
|
||||||
class Reflex(SimpleNamespace):
|
|
||||||
MODULE_NAME = "reflex"
|
|
||||||
VERSION = metadata.version(MODULE_NAME)
|
|
||||||
JSON = os.path.join(Dirs.WEB, "reflex.json")
|
|
||||||
_dir = os.environ.get("REFLEX_DIR", "")
|
|
||||||
DIR = _dir or PlatformDirs(MODULE_NAME, False).user_data_dir
|
|
||||||
ROOT_DIR = os.path.dirname(
|
|
||||||
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
||||||
)
|
|
||||||
|
|
||||||
class ReflexHostingCLI(SimpleNamespace):
|
|
||||||
MODULE_NAME = "reflex-hosting-cli"
|
|
||||||
|
|
||||||
class Templates(SimpleNamespace):
|
|
||||||
APP_TEMPLATES_ROUTE = "/app-templates"
|
|
||||||
DEFAULT = "blank"
|
|
||||||
|
|
||||||
class Dirs(SimpleNamespace):
|
|
||||||
BASE = os.path.join(Reflex.ROOT_DIR, Reflex.MODULE_NAME, ".templates")
|
|
||||||
WEB_TEMPLATE = os.path.join(BASE, "web")
|
|
||||||
JINJA_TEMPLATE = os.path.join(BASE, "jinja")
|
|
||||||
CODE = "code"
|
|
||||||
|
|
||||||
class Next(SimpleNamespace):
|
|
||||||
CONFIG_FILE = "next.config.js"
|
|
||||||
SITEMAP_CONFIG_FILE = os.path.join(Dirs.WEB, "next-sitemap.config.js")
|
|
||||||
NODE_MODULES = "node_modules"
|
|
||||||
PACKAGE_LOCK = "package-lock.json"
|
|
||||||
FRONTEND_LISTENING_REGEX = "Local:[\\s]+(.*)"
|
|
||||||
|
|
||||||
class ColorMode(SimpleNamespace):
|
|
||||||
NAME = "colorMode"
|
|
||||||
USE = "useColorMode"
|
|
||||||
TOGGLE = "toggleColorMode"
|
|
||||||
|
|
||||||
class Env(str, Enum):
|
|
||||||
DEV = "dev"
|
|
||||||
PROD = "prod"
|
|
||||||
|
|
||||||
class LogLevel(str, Enum):
|
|
||||||
DEBUG = "debug"
|
|
||||||
INFO = "info"
|
|
||||||
WARNING = "warning"
|
|
||||||
ERROR = "error"
|
|
||||||
CRITICAL = "critical"
|
|
||||||
|
|
||||||
POLLING_MAX_HTTP_BUFFER_SIZE = 1000 * 1000
|
|
||||||
|
|
||||||
class Ping(SimpleNamespace):
|
|
||||||
INTERVAL = 25
|
|
||||||
TIMEOUT = 120
|
|
||||||
|
|
||||||
COOKIES = "cookies"
|
|
||||||
LOCAL_STORAGE = "local_storage"
|
|
||||||
SKIP_COMPILE_ENV_VAR = "__REFLEX_SKIP_COMPILE"
|
|
||||||
ENV_MODE_ENV_VAR = "REFLEX_ENV_MODE"
|
|
||||||
PYTEST_CURRENT_TEST = "PYTEST_CURRENT_TEST"
|
|
||||||
RELOAD_CONFIG = "__REFLEX_RELOAD_CONFIG"
|
|
||||||
REFLEX_VAR_OPENING_TAG = "<reflex.Var>"
|
|
||||||
REFLEX_VAR_CLOSING_TAG = "</reflex.Var>"
|
|
@ -135,7 +135,7 @@ def test_compile_stylesheets(tmp_path, mocker):
|
|||||||
f"@import url('./tailwind.css'); \n"
|
f"@import url('./tailwind.css'); \n"
|
||||||
f"@import url('https://fonts.googleapis.com/css?family=Sofia&effect=neon|outline|emboss|shadow-multiple'); \n"
|
f"@import url('https://fonts.googleapis.com/css?family=Sofia&effect=neon|outline|emboss|shadow-multiple'); \n"
|
||||||
f"@import url('https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css'); \n"
|
f"@import url('https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css'); \n"
|
||||||
f"@import url('@/styles.css'); \n"
|
f"@import url('../public/styles.css'); \n"
|
||||||
f"@import url('https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css'); \n",
|
f"@import url('https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css'); \n",
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ def test_compile_stylesheets_exclude_tailwind(tmp_path, mocker):
|
|||||||
|
|
||||||
assert compiler.compile_root_stylesheet(stylesheets) == (
|
assert compiler.compile_root_stylesheet(stylesheets) == (
|
||||||
os.path.join(".web", "styles", "styles.css"),
|
os.path.join(".web", "styles", "styles.css"),
|
||||||
"@import url('@/styles.css'); \n",
|
"@import url('../public/styles.css'); \n",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user