Add head components to app (#1868)
This commit is contained in:
parent
8231993e5a
commit
89404e0b4a
@ -114,6 +114,9 @@ class App(Base):
|
|||||||
# The async server name space
|
# The async server name space
|
||||||
event_namespace: Optional[EventNamespace] = None
|
event_namespace: Optional[EventNamespace] = None
|
||||||
|
|
||||||
|
# Components to add to the head of every page.
|
||||||
|
head_components: List[Component] = []
|
||||||
|
|
||||||
# A component that is present on every page.
|
# A component that is present on every page.
|
||||||
overlay_component: Optional[
|
overlay_component: Optional[
|
||||||
Union[Component, ComponentCallable]
|
Union[Component, ComponentCallable]
|
||||||
@ -401,6 +404,12 @@ class App(Base):
|
|||||||
|
|
||||||
# Add script tags if given
|
# Add script tags if given
|
||||||
if script_tags:
|
if script_tags:
|
||||||
|
console.deprecate(
|
||||||
|
feature_name="Passing script tags to add_page",
|
||||||
|
reason="Add script components as children to the page component instead",
|
||||||
|
deprecation_version="v0.2.9",
|
||||||
|
removal_version="v0.2.11",
|
||||||
|
)
|
||||||
component.children.extend(script_tags)
|
component.children.extend(script_tags)
|
||||||
|
|
||||||
# Add the page.
|
# Add the page.
|
||||||
@ -629,7 +638,7 @@ class App(Base):
|
|||||||
compile_results.append(compiler.compile_root_stylesheet(self.stylesheets))
|
compile_results.append(compiler.compile_root_stylesheet(self.stylesheets))
|
||||||
|
|
||||||
# Compile the root document.
|
# Compile the root document.
|
||||||
compile_results.append(compiler.compile_document_root())
|
compile_results.append(compiler.compile_document_root(self.head_components))
|
||||||
|
|
||||||
# Compile the theme.
|
# Compile the theme.
|
||||||
compile_results.append(compiler.compile_theme(self.style))
|
compile_results.append(compiler.compile_theme(self.style))
|
||||||
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Set, Tuple, Type
|
from typing import Type
|
||||||
|
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.compiler import templates, utils
|
from reflex.compiler import templates, utils
|
||||||
@ -121,7 +121,7 @@ def _compile_page(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def compile_root_stylesheet(stylesheets: List[str]) -> Tuple[str, str]:
|
def compile_root_stylesheet(stylesheets: list[str]) -> tuple[str, str]:
|
||||||
"""Compile the root stylesheet.
|
"""Compile the root stylesheet.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -137,7 +137,7 @@ def compile_root_stylesheet(stylesheets: List[str]) -> Tuple[str, str]:
|
|||||||
return output_path, code
|
return output_path, code
|
||||||
|
|
||||||
|
|
||||||
def _compile_root_stylesheet(stylesheets: List[str]) -> str:
|
def _compile_root_stylesheet(stylesheets: list[str]) -> str:
|
||||||
"""Compile the root stylesheet.
|
"""Compile the root stylesheet.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -182,7 +182,7 @@ def _compile_component(component: Component) -> str:
|
|||||||
return templates.COMPONENT.render(component=component)
|
return templates.COMPONENT.render(component=component)
|
||||||
|
|
||||||
|
|
||||||
def _compile_components(components: Set[CustomComponent]) -> str:
|
def _compile_components(components: set[CustomComponent]) -> str:
|
||||||
"""Compile the components.
|
"""Compile the components.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -226,9 +226,12 @@ def _compile_tailwind(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def compile_document_root() -> Tuple[str, str]:
|
def compile_document_root(head_components: list[Component]) -> tuple[str, str]:
|
||||||
"""Compile the document root.
|
"""Compile the document root.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
head_components: The components to include in the head.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The path and code of the compiled document root.
|
The path and code of the compiled document root.
|
||||||
"""
|
"""
|
||||||
@ -236,13 +239,14 @@ def compile_document_root() -> Tuple[str, str]:
|
|||||||
output_path = utils.get_page_path(constants.DOCUMENT_ROOT)
|
output_path = utils.get_page_path(constants.DOCUMENT_ROOT)
|
||||||
|
|
||||||
# Create the document root.
|
# Create the document root.
|
||||||
document_root = utils.create_document_root()
|
document_root = utils.create_document_root(head_components)
|
||||||
|
|
||||||
# Compile the document root.
|
# Compile the document root.
|
||||||
code = _compile_document_root(document_root)
|
code = _compile_document_root(document_root)
|
||||||
return output_path, code
|
return output_path, code
|
||||||
|
|
||||||
|
|
||||||
def compile_theme(style: ComponentStyle) -> Tuple[str, str]:
|
def compile_theme(style: ComponentStyle) -> tuple[str, str]:
|
||||||
"""Compile the theme.
|
"""Compile the theme.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -261,9 +265,7 @@ def compile_theme(style: ComponentStyle) -> Tuple[str, str]:
|
|||||||
return output_path, code
|
return output_path, code
|
||||||
|
|
||||||
|
|
||||||
def compile_contexts(
|
def compile_contexts(state: Type[State]) -> tuple[str, str]:
|
||||||
state: Type[State],
|
|
||||||
) -> Tuple[str, str]:
|
|
||||||
"""Compile the initial state / context.
|
"""Compile the initial state / context.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -279,10 +281,8 @@ def compile_contexts(
|
|||||||
|
|
||||||
|
|
||||||
def compile_page(
|
def compile_page(
|
||||||
path: str,
|
path: str, component: Component, state: Type[State]
|
||||||
component: Component,
|
) -> tuple[str, str]:
|
||||||
state: Type[State],
|
|
||||||
) -> Tuple[str, str]:
|
|
||||||
"""Compile a single page.
|
"""Compile a single page.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -301,7 +301,7 @@ def compile_page(
|
|||||||
return output_path, code
|
return output_path, code
|
||||||
|
|
||||||
|
|
||||||
def compile_components(components: Set[CustomComponent]):
|
def compile_components(components: set[CustomComponent]):
|
||||||
"""Compile the custom components.
|
"""Compile the custom components.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from typing import Any, Dict, List, Optional, Set, Tuple, Type
|
from typing import Any, Type
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
from pydantic.fields import ModelField
|
from pydantic.fields import ModelField
|
||||||
@ -31,7 +31,7 @@ from reflex.vars import ImportVar
|
|||||||
merge_imports = imports.merge_imports
|
merge_imports = imports.merge_imports
|
||||||
|
|
||||||
|
|
||||||
def compile_import_statement(fields: Set[ImportVar]) -> Tuple[str, Set[str]]:
|
def compile_import_statement(fields: set[ImportVar]) -> tuple[str, set[str]]:
|
||||||
"""Compile an import statement.
|
"""Compile an import statement.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -79,7 +79,7 @@ def validate_imports(imports: imports.ImportDict):
|
|||||||
used_tags[import_name] = lib
|
used_tags[import_name] = lib
|
||||||
|
|
||||||
|
|
||||||
def compile_imports(imports: imports.ImportDict) -> List[dict]:
|
def compile_imports(imports: imports.ImportDict) -> list[dict]:
|
||||||
"""Compile an import dict.
|
"""Compile an import dict.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -112,7 +112,7 @@ def compile_imports(imports: imports.ImportDict) -> List[dict]:
|
|||||||
return import_dicts
|
return import_dicts
|
||||||
|
|
||||||
|
|
||||||
def get_import_dict(lib: str, default: str = "", rest: Optional[Set] = None) -> Dict:
|
def get_import_dict(lib: str, default: str = "", rest: set[str] | None = None) -> dict:
|
||||||
"""Get dictionary for import template.
|
"""Get dictionary for import template.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -130,7 +130,7 @@ def get_import_dict(lib: str, default: str = "", rest: Optional[Set] = None) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def compile_state(state: Type[State]) -> Dict:
|
def compile_state(state: Type[State]) -> dict:
|
||||||
"""Compile the state of the app.
|
"""Compile the state of the app.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -225,7 +225,7 @@ def compile_client_storage(state: Type[State]) -> dict[str, dict]:
|
|||||||
|
|
||||||
def compile_custom_component(
|
def compile_custom_component(
|
||||||
component: CustomComponent,
|
component: CustomComponent,
|
||||||
) -> Tuple[dict, imports.ImportDict]:
|
) -> tuple[dict, imports.ImportDict]:
|
||||||
"""Compile a custom component.
|
"""Compile a custom component.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -258,14 +258,18 @@ def compile_custom_component(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_document_root() -> Component:
|
def create_document_root(head_components: list[Component] | None = None) -> Component:
|
||||||
"""Create the document root.
|
"""Create the document root.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
head_components: The components to add to the head.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The document root.
|
The document root.
|
||||||
"""
|
"""
|
||||||
|
head_components = head_components or []
|
||||||
return Html.create(
|
return Html.create(
|
||||||
DocumentHead.create(),
|
DocumentHead.create(*head_components),
|
||||||
Body.create(
|
Body.create(
|
||||||
ColorModeScript.create(),
|
ColorModeScript.create(),
|
||||||
Main.create(),
|
Main.create(),
|
||||||
@ -274,7 +278,7 @@ def create_document_root() -> Component:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def create_theme(style: ComponentStyle) -> Dict:
|
def create_theme(style: ComponentStyle) -> dict:
|
||||||
"""Create the base style for the app.
|
"""Create the base style for the app.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -350,11 +354,11 @@ def get_components_path() -> str:
|
|||||||
return os.path.join(constants.WEB_UTILS_DIR, "components" + constants.JS_EXT)
|
return os.path.join(constants.WEB_UTILS_DIR, "components" + constants.JS_EXT)
|
||||||
|
|
||||||
|
|
||||||
def get_asset_path(filename: Optional[str] = None) -> str:
|
def get_asset_path(filename: str | None = None) -> str:
|
||||||
"""Get the path for an asset.
|
"""Get the path for an asset.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
filename: Optional, if given, is added to the root path of assets dir.
|
filename: If given, is added to the root path of assets dir.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The path of the asset.
|
The path of the asset.
|
||||||
@ -366,7 +370,7 @@ def get_asset_path(filename: Optional[str] = None) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def add_meta(
|
def add_meta(
|
||||||
page: Component, title: str, image: str, description: str, meta: List[Dict]
|
page: Component, title: str, image: str, description: str, meta: list[dict]
|
||||||
) -> Component:
|
) -> Component:
|
||||||
"""Add metadata to a page.
|
"""Add metadata to a page.
|
||||||
|
|
||||||
@ -406,7 +410,7 @@ def write_page(path: str, code: str):
|
|||||||
f.write(code)
|
f.write(code)
|
||||||
|
|
||||||
|
|
||||||
def empty_dir(path: str, keep_files: Optional[List[str]] = None):
|
def empty_dir(path: str, keep_files: list[str] | None = None):
|
||||||
"""Remove all files and folders in a directory except for the keep_files.
|
"""Remove all files and folders in a directory except for the keep_files.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -189,3 +189,22 @@ def test_compile_nonexistent_stylesheet(tmp_path, mocker):
|
|||||||
|
|
||||||
with pytest.raises(FileNotFoundError):
|
with pytest.raises(FileNotFoundError):
|
||||||
compiler.compile_root_stylesheet(stylesheets)
|
compiler.compile_root_stylesheet(stylesheets)
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_document_root():
|
||||||
|
"""Test that the document root is created correctly."""
|
||||||
|
# Test with no components.
|
||||||
|
root = utils.create_document_root()
|
||||||
|
assert isinstance(root, utils.Html)
|
||||||
|
assert isinstance(root.children[0], utils.DocumentHead)
|
||||||
|
# No children in head.
|
||||||
|
assert len(root.children[0].children) == 0
|
||||||
|
|
||||||
|
# Test with components.
|
||||||
|
comps = [
|
||||||
|
utils.NextScript.create(src="foo.js"),
|
||||||
|
utils.NextScript.create(src="bar.js"),
|
||||||
|
]
|
||||||
|
root = utils.create_document_root(head_components=comps) # type: ignore
|
||||||
|
# Two children in head.
|
||||||
|
assert len(root.children[0].children) == 2
|
||||||
|
Loading…
Reference in New Issue
Block a user