Skip to content

Commit

Permalink
Changes
Browse files Browse the repository at this point in the history
  • Loading branch information
richard-to committed Dec 15, 2024
1 parent 613c5da commit 04907c9
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 82 deletions.
64 changes: 36 additions & 28 deletions mesop/component_helpers/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,29 @@ def __exit__(self, exc_type, exc_val, exc_tb):
runtime().context().set_node_tree_state(self.prev_node_tree_state)


class DetachedNodeTreeStateContextFactory:
def __init__(self, named_slots: dict[str, SlotMetadata]):
self.named_slots_accessed = set()
self.named_slots = named_slots
for named in self.named_slots:
DetachedNodeTreeStateContextFactory.__annotations__[named] = Callable

def __getattr__(self, name: str) -> Callable:
if name in self.named_slots:
return lambda: self._slot(name)
raise ValueError()

def _slot(self, name: str = ""):
if name in self.named_slots_accessed:
raise MesopDeveloperException(
f"Content for named slot '{name}' has already been set."
)
if name not in self.named_slots:
raise MesopDeveloperException(f"Slot name '{name}' does not exist.")
self.named_slots_accessed.add(name)
return DetachedNodeTreeStateContext(self.named_slots[name].node_tree_state)


T = TypeVar("T")
P = ParamSpec("P")

Expand All @@ -117,14 +140,12 @@ def __init__(self, fn: Callable[[], T]):
node_tree_state = runtime().context().get_node_tree_state()
self.prev_node_tree_state = node_tree_state

self.unnamed_slots_accessed = 0
self.unnamed_slots = [
SlotMetadata(node_slot=node_slot)
for node_slot in node_tree_state.node_slots()
if not node_slot.name
]

self.named_slots_accessed = set()
self.named_slots = {
node_slot.name: SlotMetadata(node_slot=node_slot)
for node_slot in node_tree_state.node_slots()
Expand All @@ -146,12 +167,21 @@ def __init__(self, fn: Callable[[], T]):
"Cannot mix named and unamed slots. Use one or the other when defining a composite component."
)

# If there is only one unnamed slot, use implicit node tree state context.
if len(self.unnamed_slots) == 1:
self.slot()
if len(self.unnamed_slots) > 1:
raise MesopDeveloperException(
"Only one unnamed child slot allowed defining a composite component."
)

# Since there is only one unnamed slot, use implicit node tree state context.
if self.unnamed_slots:
DetachedNodeTreeStateContext(self.unnamed_slots[0].node_tree_state)

self.named_node_factory = DetachedNodeTreeStateContextFactory(
self.named_slots
)

def __enter__(self):
return self
return self.named_node_factory

def __exit__(self, exc_type, exc_val, exc_tb): # type: ignore
for slot in reversed(self.unnamed_slots):
Expand All @@ -164,28 +194,6 @@ def __exit__(self, exc_type, exc_val, exc_tb): # type: ignore
runtime().context().set_current_node(self.prev_current_node)
runtime().context().clear_node_slots()

def slot(self, name: str = ""):
if name:
if name in self.named_slots_accessed:
raise MesopDeveloperException(
f"Content for named slot '{name}' has already been set."
)
if name not in self.named_slots:
raise MesopDeveloperException(f"Slot name '{name}' does not exist.")
self.named_slots_accessed.add(name)
return DetachedNodeTreeStateContext(
self.named_slots[name].node_tree_state
)
else:
self.unnamed_slots_accessed += 1
if self.unnamed_slots_accessed > len(self.unnamed_slots):
raise MesopDeveloperException(
f"Tried to set too many slots for this composite component. Expecting {len(self.unnamed_slots)} slot(s)."
)
return DetachedNodeTreeStateContext(
self.unnamed_slots[self.unnamed_slots_accessed - 1].node_tree_state
)

def _insert_slot_content(self, slot_metadata: SlotMetadata) -> None:
index = slot_metadata.node_slot.insertion_index
parent_node = slot_metadata.node_slot.parent_node
Expand Down
58 changes: 4 additions & 54 deletions mesop/examples/nested_slot.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,17 @@
def homepage():
with custom_card():
me.button("Hello")
with layout(color="yellow") as parent1:
with parent1.slot():
with custom_card():
with me.content_button():
me.text("Hello world")
with layout(color="black") as parent2:
with parent2.slot():
me.text("hello world2")
with parent2.slot():
with me.accordion():
with me.expansion_panel(
key="pie",
title="Pie",
description="Type of snack",
icon="pie_chart",
disabled=False,
hide_toggle=False,
):
me.text(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed augue ultricies, laoreet nunc eget, ultricies augue. In ornare bibendum mauris vel sodales. Donec ut interdum felis. Nulla facilisi. Morbi a laoreet turpis, sed posuere arcu. Nam nisi neque, molestie vitae euismod eu, sollicitudin eu lectus. Pellentesque orci metus, finibus id faucibus et, ultrices quis dui. Duis in augue ac metus tristique lacinia."
)
with parent1.slot():
me.text("nav")

with me.box(style=me.Style(margin=me.Margin.all(10))):
me.divider()

with layout_named(color="yellow") as parent1:
with parent1.slot(name="header"):
with parent1.header():
me.text("hello world")
with layout_named(color="black") as parent2:
with parent2.slot(name="header"):
with parent2.header():
me.text("hello world2")
with parent2.slot(name="footer"):
with parent2.footer():
with me.accordion():
with me.expansion_panel(
key="pie",
Expand All @@ -51,37 +28,10 @@ def homepage():
me.text(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed augue ultricies, laoreet nunc eget, ultricies augue. In ornare bibendum mauris vel sodales. Donec ut interdum felis. Nulla facilisi. Morbi a laoreet turpis, sed posuere arcu. Nam nisi neque, molestie vitae euismod eu, sollicitudin eu lectus. Pellentesque orci metus, finibus id faucibus et, ultrices quis dui. Duis in augue ac metus tristique lacinia."
)
with parent1.slot(name="footer"):
with parent1.footer():
me.text("nav")


@me.content_component
def layout(color):
with me.box(
style=me.Style(
color="green",
display="flex",
flex_direction="column",
background="red",
border=me.Border.all(me.BorderSide(width=10, style="solid", color=color)),
)
):
with me.box(
style=me.Style(
flex="1",
color="white",
background="blue",
border=me.Border.all(
me.BorderSide(width=10, style="solid", color="green")
),
)
):
me.slot()
me.text("ZZZZZZZ")
me.slot()
me.text("YYYYY")


@me.content_component
def layout_named(color):
with me.box(
Expand Down

0 comments on commit 04907c9

Please sign in to comment.