Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
20 changes: 16 additions & 4 deletions reflex/components/base/bare.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,17 +141,29 @@ def _get_all_custom_code(self) -> set[str]:
custom_code |= component._get_all_custom_code()
return custom_code

def _get_all_app_wrap_components(self) -> dict[tuple[int, str], Component]:
def _get_all_app_wrap_components(
self, *, ignore_ids: set[int] | None = None
) -> dict[tuple[int, str], Component]:
"""Get the components that should be wrapped in the app.

Args:
ignore_ids: The ids to ignore when collecting components.

Returns:
The components that should be wrapped in the app.
"""
app_wrap_components = super()._get_all_app_wrap_components()
ignore_ids = ignore_ids or set()
app_wrap_components = super()._get_all_app_wrap_components(
ignore_ids=ignore_ids
)
if isinstance(self.contents, Var):
for component in _components_from_var(self.contents):
if isinstance(component, Component):
app_wrap_components |= component._get_all_app_wrap_components()
component_id = id(component)
if isinstance(component, Component) and component_id not in ignore_ids:
ignore_ids.add(component_id)
app_wrap_components |= component._get_all_app_wrap_components(
ignore_ids=ignore_ids
)
return app_wrap_components

def _get_all_refs(self) -> set[str]:
Expand Down
36 changes: 30 additions & 6 deletions reflex/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -1976,24 +1976,38 @@ def _get_app_wrap_components() -> dict[tuple[int, str], Component]:
"""
return {}

def _get_all_app_wrap_components(self) -> dict[tuple[int, str], Component]:
def _get_all_app_wrap_components(
self, *, ignore_ids: set[int] | None = None
) -> dict[tuple[int, str], Component]:
"""Get the app wrap components for the component and its children.

Args:
ignore_ids: A set of component IDs to ignore. Used to avoid duplicates.

Returns:
The app wrap components.
"""
ignore_ids = ignore_ids or set()
# Store the components in a set to avoid duplicates.
components = self._get_app_wrap_components()

for component in tuple(components.values()):
components.update(component._get_all_app_wrap_components())
component_id = id(component)
if component_id in ignore_ids:
continue
ignore_ids.add(component_id)
components.update(
component._get_all_app_wrap_components(ignore_ids=ignore_ids)
)

# Add the app wrap components for the children.
for child in self.children:
child_id = id(child)
# Skip BaseComponent and StatefulComponent children.
if not isinstance(child, Component):
if not isinstance(child, Component) or child_id in ignore_ids:
continue
components.update(child._get_all_app_wrap_components())
ignore_ids.add(child_id)
components.update(child._get_all_app_wrap_components(ignore_ids=ignore_ids))

# Return the components.
return components
Expand Down Expand Up @@ -2206,13 +2220,23 @@ def get_component(self) -> Component:
component._add_style_recursive(style)
return component

def _get_all_app_wrap_components(self) -> dict[tuple[int, str], Component]:
def _get_all_app_wrap_components(
self, *, ignore_ids: set[int] | None = None
) -> dict[tuple[int, str], Component]:
"""Get the app wrap components for the custom component.

Args:
ignore_ids: A set of IDs to ignore to avoid infinite recursion.

Returns:
The app wrap components.
"""
return self.get_component()._get_all_app_wrap_components()
ignore_ids = ignore_ids or set()
component = self.get_component()
if id(component) in ignore_ids:
return {}
ignore_ids.add(id(component))
return self.get_component()._get_all_app_wrap_components(ignore_ids=ignore_ids)


CUSTOM_COMPONENTS: dict[str, CustomComponent] = {}
Expand Down