reflex 0.7.0a5__py3-none-any.whl → 0.7.1a2__py3-none-any.whl
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/.templates/web/components/reflex/radix_themes_color_mode_provider.js +3 -1
- reflex/__init__.py +1 -0
- reflex/__init__.pyi +1 -0
- reflex/app.py +255 -81
- reflex/base.py +4 -10
- reflex/compiler/compiler.py +46 -12
- reflex/compiler/templates.py +1 -2
- reflex/compiler/utils.py +23 -14
- reflex/components/base/bare.py +109 -16
- reflex/components/component.py +179 -124
- reflex/components/core/__init__.py +1 -0
- reflex/components/core/__init__.pyi +1 -0
- reflex/components/core/auto_scroll.py +111 -0
- reflex/components/core/auto_scroll.pyi +284 -0
- reflex/components/core/banner.py +40 -9
- reflex/components/core/banner.pyi +400 -87
- reflex/components/core/breakpoints.py +1 -1
- reflex/components/core/cond.py +0 -8
- reflex/components/core/foreach.py +12 -2
- reflex/components/core/html.pyi +200 -19
- reflex/components/core/match.py +4 -4
- reflex/components/core/sticky.pyi +874 -90
- reflex/components/core/upload.py +3 -5
- reflex/components/core/upload.pyi +2 -4
- reflex/components/datadisplay/code.py +36 -10
- reflex/components/datadisplay/code.pyi +1 -1
- reflex/components/datadisplay/dataeditor.py +1 -3
- reflex/components/datadisplay/dataeditor.pyi +1 -3
- reflex/components/el/elements/base.py +95 -17
- reflex/components/el/elements/base.pyi +278 -19
- reflex/components/el/elements/forms.py +124 -102
- reflex/components/el/elements/forms.pyi +2787 -365
- reflex/components/el/elements/inline.py +24 -15
- reflex/components/el/elements/inline.pyi +5655 -546
- reflex/components/el/elements/media.py +79 -95
- reflex/components/el/elements/media.pyi +5167 -565
- reflex/components/el/elements/metadata.py +19 -17
- reflex/components/el/elements/metadata.pyi +841 -89
- reflex/components/el/elements/other.py +3 -5
- reflex/components/el/elements/other.pyi +1404 -137
- reflex/components/el/elements/scripts.py +10 -13
- reflex/components/el/elements/scripts.pyi +634 -65
- reflex/components/el/elements/sectioning.pyi +3001 -286
- reflex/components/el/elements/tables.py +14 -35
- reflex/components/el/elements/tables.pyi +2029 -218
- reflex/components/el/elements/typography.py +10 -13
- reflex/components/el/elements/typography.pyi +3014 -297
- reflex/components/lucide/icon.py +22 -6
- reflex/components/markdown/markdown.py +30 -10
- reflex/components/markdown/markdown.pyi +3 -2
- reflex/components/plotly/plotly.py +1 -3
- reflex/components/plotly/plotly.pyi +1 -3
- reflex/components/radix/primitives/form.pyi +624 -93
- reflex/components/radix/themes/color_mode.py +1 -1
- reflex/components/radix/themes/color_mode.pyi +213 -31
- reflex/components/radix/themes/components/alert_dialog.pyi +199 -18
- reflex/components/radix/themes/components/badge.pyi +199 -18
- reflex/components/radix/themes/components/button.pyi +213 -31
- reflex/components/radix/themes/components/callout.pyi +1000 -95
- reflex/components/radix/themes/components/card.pyi +199 -18
- reflex/components/radix/themes/components/context_menu.py +79 -1
- reflex/components/radix/themes/components/context_menu.pyi +320 -1
- reflex/components/radix/themes/components/dialog.pyi +199 -18
- reflex/components/radix/themes/components/hover_card.pyi +199 -18
- reflex/components/radix/themes/components/icon_button.pyi +213 -31
- reflex/components/radix/themes/components/inset.pyi +199 -18
- reflex/components/radix/themes/components/popover.pyi +199 -18
- reflex/components/radix/themes/components/table.pyi +1437 -154
- reflex/components/radix/themes/components/text_area.py +2 -2
- reflex/components/radix/themes/components/text_area.pyi +201 -20
- reflex/components/radix/themes/components/text_field.py +1 -1
- reflex/components/radix/themes/components/text_field.pyi +444 -88
- reflex/components/radix/themes/layout/box.pyi +200 -19
- reflex/components/radix/themes/layout/center.pyi +199 -18
- reflex/components/radix/themes/layout/container.pyi +199 -18
- reflex/components/radix/themes/layout/flex.pyi +199 -18
- reflex/components/radix/themes/layout/grid.pyi +199 -18
- reflex/components/radix/themes/layout/list.pyi +604 -57
- reflex/components/radix/themes/layout/section.pyi +199 -18
- reflex/components/radix/themes/layout/spacer.pyi +199 -18
- reflex/components/radix/themes/layout/stack.pyi +597 -54
- reflex/components/radix/themes/typography/blockquote.pyi +200 -19
- reflex/components/radix/themes/typography/code.pyi +199 -18
- reflex/components/radix/themes/typography/heading.pyi +199 -18
- reflex/components/radix/themes/typography/link.pyi +238 -28
- reflex/components/radix/themes/typography/text.pyi +1394 -127
- reflex/components/react_player/react_player.py +1 -1
- reflex/components/react_player/react_player.pyi +1 -3
- reflex/components/sonner/toast.py +41 -12
- reflex/components/sonner/toast.pyi +20 -6
- reflex/components/tags/iter_tag.py +4 -0
- reflex/components/tags/tag.py +3 -3
- reflex/config.py +187 -28
- reflex/constants/__init__.py +2 -0
- reflex/constants/base.py +6 -0
- reflex/constants/compiler.py +9 -0
- reflex/constants/event.py +1 -0
- reflex/constants/installer.py +4 -5
- reflex/constants/utils.py +1 -3
- reflex/event.py +7 -16
- reflex/experimental/layout.pyi +597 -54
- reflex/py.typed +0 -0
- reflex/reflex.py +30 -41
- reflex/state.py +49 -44
- reflex/style.py +15 -22
- reflex/testing.py +2 -0
- reflex/utils/build.py +12 -0
- reflex/utils/console.py +4 -0
- reflex/utils/decorator.py +25 -0
- reflex/utils/exec.py +92 -34
- reflex/utils/format.py +35 -6
- reflex/utils/path_ops.py +16 -1
- reflex/utils/prerequisites.py +34 -8
- reflex/utils/processes.py +12 -13
- reflex/utils/serializers.py +20 -43
- reflex/utils/telemetry.py +4 -15
- reflex/utils/types.py +36 -66
- reflex/vars/base.py +53 -76
- reflex/vars/function.py +17 -5
- reflex/vars/number.py +1 -1
- reflex/vars/sequence.py +80 -4
- {reflex-0.7.0a5.dist-info → reflex-0.7.1a2.dist-info}/METADATA +4 -5
- {reflex-0.7.0a5.dist-info → reflex-0.7.1a2.dist-info}/RECORD +126 -122
- {reflex-0.7.0a5.dist-info → reflex-0.7.1a2.dist-info}/LICENSE +0 -0
- {reflex-0.7.0a5.dist-info → reflex-0.7.1a2.dist-info}/WHEEL +0 -0
- {reflex-0.7.0a5.dist-info → reflex-0.7.1a2.dist-info}/entry_points.txt +0 -0
reflex/compiler/compiler.py
CHANGED
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from datetime import datetime
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import TYPE_CHECKING, Dict, Iterable, Optional, Tuple, Type, Union
|
|
7
|
+
from typing import TYPE_CHECKING, Dict, Iterable, Optional, Sequence, Tuple, Type, Union
|
|
8
8
|
|
|
9
9
|
from reflex import constants
|
|
10
10
|
from reflex.compiler import templates, utils
|
|
@@ -78,6 +78,7 @@ def _compile_app(app_root: Component) -> str:
|
|
|
78
78
|
hooks=app_root._get_all_hooks(),
|
|
79
79
|
window_libraries=window_libraries,
|
|
80
80
|
render=app_root.render(),
|
|
81
|
+
dynamic_imports=app_root._get_all_dynamic_imports(),
|
|
81
82
|
)
|
|
82
83
|
|
|
83
84
|
|
|
@@ -507,7 +508,7 @@ def compile_tailwind(
|
|
|
507
508
|
The compiled Tailwind config.
|
|
508
509
|
"""
|
|
509
510
|
# Get the path for the output file.
|
|
510
|
-
output_path = get_web_dir() / constants.Tailwind.CONFIG
|
|
511
|
+
output_path = str((get_web_dir() / constants.Tailwind.CONFIG).absolute())
|
|
511
512
|
|
|
512
513
|
# Compile the config.
|
|
513
514
|
code = _compile_tailwind(config)
|
|
@@ -544,7 +545,47 @@ def purge_web_pages_dir():
|
|
|
544
545
|
|
|
545
546
|
|
|
546
547
|
if TYPE_CHECKING:
|
|
547
|
-
from reflex.app import UnevaluatedPage
|
|
548
|
+
from reflex.app import ComponentCallable, UnevaluatedPage
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
def _into_component_once(component: Component | ComponentCallable) -> Component | None:
|
|
552
|
+
"""Convert a component to a Component.
|
|
553
|
+
|
|
554
|
+
Args:
|
|
555
|
+
component: The component to convert.
|
|
556
|
+
|
|
557
|
+
Returns:
|
|
558
|
+
The converted component.
|
|
559
|
+
"""
|
|
560
|
+
if isinstance(component, Component):
|
|
561
|
+
return component
|
|
562
|
+
if isinstance(component, (Var, int, float, str)):
|
|
563
|
+
return Fragment.create(component)
|
|
564
|
+
if isinstance(component, Sequence):
|
|
565
|
+
return Fragment.create(*component)
|
|
566
|
+
return None
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
def into_component(component: Component | ComponentCallable) -> Component:
|
|
570
|
+
"""Convert a component to a Component.
|
|
571
|
+
|
|
572
|
+
Args:
|
|
573
|
+
component: The component to convert.
|
|
574
|
+
|
|
575
|
+
Returns:
|
|
576
|
+
The converted component.
|
|
577
|
+
|
|
578
|
+
Raises:
|
|
579
|
+
TypeError: If the component is not a Component.
|
|
580
|
+
"""
|
|
581
|
+
if (converted := _into_component_once(component)) is not None:
|
|
582
|
+
return converted
|
|
583
|
+
if (
|
|
584
|
+
callable(component)
|
|
585
|
+
and (converted := _into_component_once(component())) is not None
|
|
586
|
+
):
|
|
587
|
+
return converted
|
|
588
|
+
raise TypeError(f"Expected a Component, got {type(component)}")
|
|
548
589
|
|
|
549
590
|
|
|
550
591
|
def compile_unevaluated_page(
|
|
@@ -567,12 +608,7 @@ def compile_unevaluated_page(
|
|
|
567
608
|
The compiled component and whether state should be enabled.
|
|
568
609
|
"""
|
|
569
610
|
# Generate the component if it is a callable.
|
|
570
|
-
component = page.component
|
|
571
|
-
component = component if isinstance(component, Component) else component()
|
|
572
|
-
|
|
573
|
-
# unpack components that return tuples in an rx.fragment.
|
|
574
|
-
if isinstance(component, tuple):
|
|
575
|
-
component = Fragment.create(*component)
|
|
611
|
+
component = into_component(page.component)
|
|
576
612
|
|
|
577
613
|
component._add_style_recursive(style or {}, theme)
|
|
578
614
|
|
|
@@ -677,10 +713,8 @@ class ExecutorSafeFunctions:
|
|
|
677
713
|
The route, compiled component, and compiled page.
|
|
678
714
|
"""
|
|
679
715
|
component, enable_state = compile_unevaluated_page(
|
|
680
|
-
route, cls.UNCOMPILED_PAGES[route]
|
|
716
|
+
route, cls.UNCOMPILED_PAGES[route], cls.STATE, style, theme
|
|
681
717
|
)
|
|
682
|
-
component = component if isinstance(component, Component) else component()
|
|
683
|
-
component._add_style_recursive(style, theme)
|
|
684
718
|
return route, component, compile_page(route, component, cls.STATE)
|
|
685
719
|
|
|
686
720
|
@classmethod
|
reflex/compiler/templates.py
CHANGED
|
@@ -48,11 +48,10 @@ class ReflexJinjaEnvironment(Environment):
|
|
|
48
48
|
|
|
49
49
|
def __init__(self) -> None:
|
|
50
50
|
"""Set default environment."""
|
|
51
|
-
extensions = ["jinja2.ext.debug"]
|
|
52
51
|
super().__init__(
|
|
53
|
-
extensions=extensions,
|
|
54
52
|
trim_blocks=True,
|
|
55
53
|
lstrip_blocks=True,
|
|
54
|
+
auto_reload=False,
|
|
56
55
|
)
|
|
57
56
|
self.filters["json_dumps"] = json_dumps
|
|
58
57
|
self.filters["react_setter"] = lambda state: f"set{state.capitalize()}"
|
reflex/compiler/utils.py
CHANGED
|
@@ -10,16 +10,7 @@ from pathlib import Path
|
|
|
10
10
|
from typing import Any, Callable, Dict, Optional, Type, Union
|
|
11
11
|
from urllib.parse import urlparse
|
|
12
12
|
|
|
13
|
-
from
|
|
14
|
-
from reflex.utils.prerequisites import get_web_dir
|
|
15
|
-
from reflex.vars.base import Var
|
|
16
|
-
|
|
17
|
-
try:
|
|
18
|
-
from pydantic.v1.fields import ModelField
|
|
19
|
-
except ModuleNotFoundError:
|
|
20
|
-
from pydantic.fields import (
|
|
21
|
-
ModelField, # pyright: ignore [reportAttributeAccessIssue]
|
|
22
|
-
)
|
|
13
|
+
from pydantic.v1.fields import ModelField
|
|
23
14
|
|
|
24
15
|
from reflex import constants
|
|
25
16
|
from reflex.components.base import (
|
|
@@ -39,7 +30,10 @@ from reflex.istate.storage import Cookie, LocalStorage, SessionStorage
|
|
|
39
30
|
from reflex.state import BaseState, _resolve_delta
|
|
40
31
|
from reflex.style import Style
|
|
41
32
|
from reflex.utils import console, format, imports, path_ops
|
|
33
|
+
from reflex.utils.exec import is_in_app_harness
|
|
42
34
|
from reflex.utils.imports import ImportVar, ParsedImportDict
|
|
35
|
+
from reflex.utils.prerequisites import get_web_dir
|
|
36
|
+
from reflex.vars.base import Var
|
|
43
37
|
|
|
44
38
|
# To re-export this function.
|
|
45
39
|
merge_imports = imports.merge_imports
|
|
@@ -168,6 +162,22 @@ def get_import_dict(lib: str, default: str = "", rest: list[str] | None = None)
|
|
|
168
162
|
}
|
|
169
163
|
|
|
170
164
|
|
|
165
|
+
def save_error(error: Exception) -> str:
|
|
166
|
+
"""Save the error to a file.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
error: The error to save.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
The path of the saved error.
|
|
173
|
+
"""
|
|
174
|
+
timestamp = datetime.now().strftime("%Y-%m-%d__%H-%M-%S")
|
|
175
|
+
constants.Reflex.LOGS_DIR.mkdir(parents=True, exist_ok=True)
|
|
176
|
+
log_path = constants.Reflex.LOGS_DIR / f"error_{timestamp}.log"
|
|
177
|
+
traceback.TracebackException.from_exception(error).print(file=log_path.open("w+"))
|
|
178
|
+
return str(log_path)
|
|
179
|
+
|
|
180
|
+
|
|
171
181
|
def compile_state(state: Type[BaseState]) -> dict:
|
|
172
182
|
"""Compile the state of the app.
|
|
173
183
|
|
|
@@ -180,10 +190,7 @@ def compile_state(state: Type[BaseState]) -> dict:
|
|
|
180
190
|
try:
|
|
181
191
|
initial_state = state(_reflex_internal_init=True).dict(initial=True)
|
|
182
192
|
except Exception as e:
|
|
183
|
-
|
|
184
|
-
constants.Reflex.LOGS_DIR.mkdir(parents=True, exist_ok=True)
|
|
185
|
-
log_path = constants.Reflex.LOGS_DIR / f"state_compile_error_{timestamp}.log"
|
|
186
|
-
traceback.TracebackException.from_exception(e).print(file=log_path.open("w+"))
|
|
193
|
+
log_path = save_error(e)
|
|
187
194
|
console.warn(
|
|
188
195
|
f"Failed to compile initial state with computed vars. Error log saved to {log_path}"
|
|
189
196
|
)
|
|
@@ -510,6 +517,8 @@ def write_page(path: str | Path, code: str):
|
|
|
510
517
|
"""
|
|
511
518
|
path = Path(path)
|
|
512
519
|
path_ops.mkdir(path.parent)
|
|
520
|
+
if path.exists() and path.read_text(encoding="utf-8") == code:
|
|
521
|
+
return
|
|
513
522
|
path.write_text(code, encoding="utf-8")
|
|
514
523
|
|
|
515
524
|
|
reflex/components/base/bare.py
CHANGED
|
@@ -2,14 +2,54 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from typing import Any, Iterator
|
|
5
|
+
from typing import Any, Iterator, Sequence
|
|
6
6
|
|
|
7
|
-
from reflex.components.component import Component,
|
|
7
|
+
from reflex.components.component import BaseComponent, Component, ComponentStyle
|
|
8
8
|
from reflex.components.tags import Tag
|
|
9
9
|
from reflex.components.tags.tagless import Tagless
|
|
10
|
+
from reflex.config import PerformanceMode, environment
|
|
11
|
+
from reflex.utils import console
|
|
12
|
+
from reflex.utils.decorator import once
|
|
10
13
|
from reflex.utils.imports import ParsedImportDict
|
|
11
14
|
from reflex.vars import BooleanVar, ObjectVar, Var
|
|
12
|
-
from reflex.vars.base import VarData
|
|
15
|
+
from reflex.vars.base import GLOBAL_CACHE, VarData
|
|
16
|
+
from reflex.vars.sequence import LiteralStringVar
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@once
|
|
20
|
+
def get_performance_mode():
|
|
21
|
+
"""Get the performance mode.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
The performance mode.
|
|
25
|
+
"""
|
|
26
|
+
return environment.REFLEX_PERF_MODE.get()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def validate_str(value: str):
|
|
30
|
+
"""Validate a string value.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
value: The value to validate.
|
|
34
|
+
|
|
35
|
+
Raises:
|
|
36
|
+
ValueError: If the value is a Var and the performance mode is set to raise.
|
|
37
|
+
"""
|
|
38
|
+
perf_mode = get_performance_mode()
|
|
39
|
+
if perf_mode != PerformanceMode.OFF and value.startswith("reflex___state"):
|
|
40
|
+
if perf_mode == PerformanceMode.WARN:
|
|
41
|
+
console.warn(
|
|
42
|
+
f"Output includes {value!s} which will be displayed as a string. If you are calling `str` on a Var, consider using .to_string() instead."
|
|
43
|
+
)
|
|
44
|
+
elif perf_mode == PerformanceMode.RAISE:
|
|
45
|
+
raise ValueError(
|
|
46
|
+
f"Output includes {value!s} which will be displayed as a string. If you are calling `str` on a Var, consider using .to_string() instead."
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _components_from_var(var: Var) -> Sequence[BaseComponent]:
|
|
51
|
+
var_data = var._get_all_var_data()
|
|
52
|
+
return var_data.components if var_data else ()
|
|
13
53
|
|
|
14
54
|
|
|
15
55
|
class Bare(Component):
|
|
@@ -28,9 +68,14 @@ class Bare(Component):
|
|
|
28
68
|
The component.
|
|
29
69
|
"""
|
|
30
70
|
if isinstance(contents, Var):
|
|
71
|
+
if isinstance(contents, LiteralStringVar):
|
|
72
|
+
validate_str(contents._var_value)
|
|
31
73
|
return cls(contents=contents)
|
|
32
74
|
else:
|
|
75
|
+
if isinstance(contents, str):
|
|
76
|
+
validate_str(contents)
|
|
33
77
|
contents = str(contents) if contents is not None else ""
|
|
78
|
+
|
|
34
79
|
return cls(contents=contents)
|
|
35
80
|
|
|
36
81
|
def _get_all_hooks_internal(self) -> dict[str, VarData | None]:
|
|
@@ -40,8 +85,9 @@ class Bare(Component):
|
|
|
40
85
|
The hooks for the component.
|
|
41
86
|
"""
|
|
42
87
|
hooks = super()._get_all_hooks_internal()
|
|
43
|
-
if isinstance(self.contents,
|
|
44
|
-
|
|
88
|
+
if isinstance(self.contents, Var):
|
|
89
|
+
for component in _components_from_var(self.contents):
|
|
90
|
+
hooks |= component._get_all_hooks_internal()
|
|
45
91
|
return hooks
|
|
46
92
|
|
|
47
93
|
def _get_all_hooks(self) -> dict[str, VarData | None]:
|
|
@@ -51,18 +97,22 @@ class Bare(Component):
|
|
|
51
97
|
The hooks for the component.
|
|
52
98
|
"""
|
|
53
99
|
hooks = super()._get_all_hooks()
|
|
54
|
-
if isinstance(self.contents,
|
|
55
|
-
|
|
100
|
+
if isinstance(self.contents, Var):
|
|
101
|
+
for component in _components_from_var(self.contents):
|
|
102
|
+
hooks |= component._get_all_hooks()
|
|
56
103
|
return hooks
|
|
57
104
|
|
|
58
|
-
def _get_all_imports(self) -> ParsedImportDict:
|
|
105
|
+
def _get_all_imports(self, collapse: bool = False) -> ParsedImportDict:
|
|
59
106
|
"""Include the imports for the component.
|
|
60
107
|
|
|
108
|
+
Args:
|
|
109
|
+
collapse: Whether to collapse the imports.
|
|
110
|
+
|
|
61
111
|
Returns:
|
|
62
112
|
The imports for the component.
|
|
63
113
|
"""
|
|
64
|
-
imports = super()._get_all_imports()
|
|
65
|
-
if isinstance(self.contents,
|
|
114
|
+
imports = super()._get_all_imports(collapse=collapse)
|
|
115
|
+
if isinstance(self.contents, Var):
|
|
66
116
|
var_data = self.contents._get_all_var_data()
|
|
67
117
|
if var_data:
|
|
68
118
|
imports |= {k: list(v) for k, v in var_data.imports}
|
|
@@ -75,8 +125,9 @@ class Bare(Component):
|
|
|
75
125
|
The dynamic imports.
|
|
76
126
|
"""
|
|
77
127
|
dynamic_imports = super()._get_all_dynamic_imports()
|
|
78
|
-
if isinstance(self.contents,
|
|
79
|
-
|
|
128
|
+
if isinstance(self.contents, Var):
|
|
129
|
+
for component in _components_from_var(self.contents):
|
|
130
|
+
dynamic_imports |= component._get_all_dynamic_imports()
|
|
80
131
|
return dynamic_imports
|
|
81
132
|
|
|
82
133
|
def _get_all_custom_code(self) -> set[str]:
|
|
@@ -86,10 +137,24 @@ class Bare(Component):
|
|
|
86
137
|
The custom code.
|
|
87
138
|
"""
|
|
88
139
|
custom_code = super()._get_all_custom_code()
|
|
89
|
-
if isinstance(self.contents,
|
|
90
|
-
|
|
140
|
+
if isinstance(self.contents, Var):
|
|
141
|
+
for component in _components_from_var(self.contents):
|
|
142
|
+
custom_code |= component._get_all_custom_code()
|
|
91
143
|
return custom_code
|
|
92
144
|
|
|
145
|
+
def _get_all_app_wrap_components(self) -> dict[tuple[int, str], Component]:
|
|
146
|
+
"""Get the components that should be wrapped in the app.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
The components that should be wrapped in the app.
|
|
150
|
+
"""
|
|
151
|
+
app_wrap_components = super()._get_all_app_wrap_components()
|
|
152
|
+
if isinstance(self.contents, Var):
|
|
153
|
+
for component in _components_from_var(self.contents):
|
|
154
|
+
if isinstance(component, Component):
|
|
155
|
+
app_wrap_components |= component._get_all_app_wrap_components()
|
|
156
|
+
return app_wrap_components
|
|
157
|
+
|
|
93
158
|
def _get_all_refs(self) -> set[str]:
|
|
94
159
|
"""Get the refs for the children of the component.
|
|
95
160
|
|
|
@@ -97,8 +162,9 @@ class Bare(Component):
|
|
|
97
162
|
The refs for the children.
|
|
98
163
|
"""
|
|
99
164
|
refs = super()._get_all_refs()
|
|
100
|
-
if isinstance(self.contents,
|
|
101
|
-
|
|
165
|
+
if isinstance(self.contents, Var):
|
|
166
|
+
for component in _components_from_var(self.contents):
|
|
167
|
+
refs |= component._get_all_refs()
|
|
102
168
|
return refs
|
|
103
169
|
|
|
104
170
|
def _render(self) -> Tag:
|
|
@@ -108,6 +174,33 @@ class Bare(Component):
|
|
|
108
174
|
return Tagless(contents=f"{{{self.contents!s}}}")
|
|
109
175
|
return Tagless(contents=str(self.contents))
|
|
110
176
|
|
|
177
|
+
def _add_style_recursive(
|
|
178
|
+
self, style: ComponentStyle, theme: Component | None = None
|
|
179
|
+
) -> Component:
|
|
180
|
+
"""Add style to the component and its children.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
style: The style to add.
|
|
184
|
+
theme: The theme to add.
|
|
185
|
+
|
|
186
|
+
Returns:
|
|
187
|
+
The component with the style added.
|
|
188
|
+
"""
|
|
189
|
+
new_self = super()._add_style_recursive(style, theme)
|
|
190
|
+
|
|
191
|
+
are_components_touched = False
|
|
192
|
+
|
|
193
|
+
if isinstance(self.contents, Var):
|
|
194
|
+
for component in _components_from_var(self.contents):
|
|
195
|
+
if isinstance(component, Component):
|
|
196
|
+
component._add_style_recursive(style, theme)
|
|
197
|
+
are_components_touched = True
|
|
198
|
+
|
|
199
|
+
if are_components_touched:
|
|
200
|
+
GLOBAL_CACHE.clear()
|
|
201
|
+
|
|
202
|
+
return new_self
|
|
203
|
+
|
|
111
204
|
def _get_vars(
|
|
112
205
|
self, include_children: bool = False, ignore_ids: set[int] | None = None
|
|
113
206
|
) -> Iterator[Var]:
|