Skip to content

Commit d0d50b5

Browse files
committed
Add support for named slots
1 parent a51cc45 commit d0d50b5

File tree

13 files changed

+1111
-51
lines changed

13 files changed

+1111
-51
lines changed

docs/components/index.md

+90-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def scaffold(url: str):
4848
me.slot()
4949
```
5050

51-
Now other components can re-use this scaffold component:
51+
Now other components can re-use this `scaffold` component:
5252

5353
```python
5454
def page1():
@@ -58,6 +58,95 @@ def page1():
5858

5959
This is similar to Angular's [Content Projection](https://angular.io/guide/content-projection).
6060

61+
### Advanced content component usage
62+
63+
#### Multi-slot projection
64+
65+
Mesop supports multi-slot projection using named slots.
66+
67+
Here is an example:
68+
69+
```python
70+
@me.slotclass
71+
class LayoutSlots:
72+
header: me.NamedSlot
73+
content: me.NamedSlot
74+
footer: me.NamedSlot
75+
76+
@me.content_component(named_slots=LayoutSlots)
77+
def layout():
78+
with me.box(style=me.Style(background="black")):
79+
me.slot("header")
80+
with me.box(style=me.Style(background="white")):
81+
me.slot("content")
82+
with me.box(style=me.Style(background="black")):
83+
me.slot("footer")
84+
```
85+
86+
Now other components can re-use this `layout` component:
87+
88+
```python
89+
def page1():
90+
with layout() as c:
91+
with c.header():
92+
me.text("Header")
93+
with c.content():
94+
me.text("Content")
95+
with c.footer():
96+
me.text("Footer")
97+
```
98+
99+
#### Composed content components
100+
101+
Content components can also use other content components, but you need to be careful since
102+
slot rendering cannot be deferred to the parent component.
103+
104+
???+ failure "Slot rendering cannot be deferred by setting another slot."
105+
106+
```python
107+
@me.content_component
108+
def inner():
109+
me.slot()
110+
111+
@me.content_component
112+
def outer():
113+
with inner():
114+
me.slot()
115+
```
116+
117+
???+ success "Content components can use content components so long as the slots get rendered by the parent content component."
118+
119+
```python
120+
@me.content_component
121+
def header(background_color: str):
122+
with me.box(style=me.Style(background=background_color)):
123+
me.slot()
124+
125+
126+
@me.content_component
127+
def footer(background_color: str):
128+
with me.box(style=me.Style(background=background_color)):
129+
me.slot()
130+
131+
132+
@me.content_component()
133+
def content_layout():
134+
with header(background_color="black"):
135+
me.text("Header")
136+
with me.box(style=me.Style(background="white")):
137+
me.slot()
138+
with footer(background_color="red")
139+
me.text("Footer")
140+
```
141+
142+
Now other components can re-use this `content_layout` component:
143+
144+
```python
145+
def page1():
146+
with content_layout():
147+
me.text("Content")
148+
```
149+
61150
## Component Key
62151

63152
Every native component in Mesop accepts a `key` argument which is a component identifier. This is used by Mesop to tell [Angular whether to reuse the DOM element](https://angular.io/api/core/TrackByFunction#description).

mesop/__init__.py

+6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
from mesop.component_helpers import (
2626
Style as Style,
2727
)
28+
from mesop.component_helpers.helper import (
29+
NamedSlot as NamedSlot,
30+
)
2831
from mesop.component_helpers.helper import (
2932
component as component,
3033
)
@@ -34,6 +37,9 @@
3437
from mesop.component_helpers.helper import (
3538
slot as slot,
3639
)
40+
from mesop.component_helpers.helper import (
41+
slotclass as slotclass,
42+
)
3743
from mesop.components.accordion.accordion import accordion as accordion
3844
from mesop.components.audio.audio import audio as audio
3945
from mesop.components.autocomplete.autocomplete import (

mesop/component_helpers/BUILD

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ py_test(
2929
srcs = ["helper_test.py"],
3030
deps = [
3131
":component_helpers",
32+
"//mesop/runtime",
3233
"//mesop/server",
3334
] + THIRD_PARTY_PY_PYTEST,
3435
)

0 commit comments

Comments
 (0)