|
22 | 22 | Sequence, |
23 | 23 | ) |
24 | 24 | from datetime import datetime |
| 25 | +from itertools import chain |
25 | 26 | from pathlib import Path |
26 | 27 | from timeit import default_timer as timer |
27 | 28 | from types import SimpleNamespace |
@@ -238,10 +239,6 @@ def default_error_boundary(*children: Component, **props) -> Component: |
238 | 239 | ) |
239 | 240 |
|
240 | 241 |
|
241 | | -class OverlayFragment(Fragment): |
242 | | - """Alias for Fragment, used to wrap the overlay_component.""" |
243 | | - |
244 | | - |
245 | 242 | @dataclasses.dataclass(frozen=True) |
246 | 243 | class UploadFile(StarletteUploadFile): |
247 | 244 | """A file uploaded to the server. |
@@ -369,6 +366,11 @@ class App(MiddlewareMixin, LifespanMixin): |
369 | 366 | ) |
370 | 367 | ) |
371 | 368 |
|
| 369 | + # Extra app wraps to be applied to the whole app. |
| 370 | + extra_app_wraps: dict[tuple[int, str], Callable[[bool], Component | None]] = ( |
| 371 | + dataclasses.field(default_factory=dict) |
| 372 | + ) |
| 373 | + |
372 | 374 | # Components to add to the head of every page. |
373 | 375 | head_components: list[Component] = dataclasses.field(default_factory=list) |
374 | 376 |
|
@@ -1031,25 +1033,31 @@ def _should_compile(self) -> bool: |
1031 | 1033 | # By default, compile the app. |
1032 | 1034 | return True |
1033 | 1035 |
|
1034 | | - def _add_overlay_to_component(self, component: Component) -> Component: |
1035 | | - if self.overlay_component is None: |
1036 | | - return component |
1037 | | - |
| 1036 | + def _add_overlay_to_component( |
| 1037 | + self, component: Component, overlay_component: Component |
| 1038 | + ) -> Component: |
1038 | 1039 | children = component.children |
1039 | | - overlay_component = self._generate_component(self.overlay_component) |
1040 | 1040 |
|
1041 | 1041 | if children[0] == overlay_component: |
1042 | 1042 | return component |
1043 | 1043 |
|
1044 | | - # recreate OverlayFragment with overlay_component as first child |
1045 | | - return OverlayFragment.create(overlay_component, *children) |
| 1044 | + return Fragment.create(overlay_component, *children) |
1046 | 1045 |
|
1047 | 1046 | def _setup_overlay_component(self): |
1048 | 1047 | """If a State is not used and no overlay_component is specified, do not render the connection modal.""" |
1049 | | - if self._state is None and self.overlay_component is default_overlay_component: |
1050 | | - self.overlay_component = None |
| 1048 | + if self.overlay_component is None: |
| 1049 | + return |
| 1050 | + console.deprecate( |
| 1051 | + feature_name="overlay_component", |
| 1052 | + reason="Use `extra_app_wraps` to add the overlay component instead.", |
| 1053 | + deprecation_version="0.8.2", |
| 1054 | + removal_version="0.9.0", |
| 1055 | + ) |
| 1056 | + overlay_component = self._generate_component(self.overlay_component) |
1051 | 1057 | for k, component in self._pages.items(): |
1052 | | - self._pages[k] = self._add_overlay_to_component(component) |
| 1058 | + self._pages[k] = self._add_overlay_to_component( |
| 1059 | + component, overlay_component |
| 1060 | + ) |
1053 | 1061 |
|
1054 | 1062 | def _setup_sticky_badge(self): |
1055 | 1063 | """Add the sticky badge to the app.""" |
@@ -1261,7 +1269,10 @@ def memoized_toast_provider(): |
1261 | 1269 | app_wrappers[(1, "ToasterProvider")] = toast_provider |
1262 | 1270 |
|
1263 | 1271 | # Add the app wraps to the app. |
1264 | | - for key, app_wrap in self.app_wraps.items(): |
| 1272 | + for key, app_wrap in chain( |
| 1273 | + self.app_wraps.items(), self.extra_app_wraps.items() |
| 1274 | + ): |
| 1275 | + # If the app wrap is a callable, generate the component |
1265 | 1276 | component = app_wrap(self._state is not None) |
1266 | 1277 | if component is not None: |
1267 | 1278 | app_wrappers[key] = component |
|
0 commit comments