Skip to content

Commit 4129b60

Browse files
committed
improve docs + simplify multiview
1 parent 9f74b5f commit 4129b60

File tree

4 files changed

+58
-31
lines changed

4 files changed

+58
-31
lines changed

src/idom/_option.py

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
"""
2+
Config Option
3+
=============
4+
"""
5+
16
from __future__ import annotations
27

38
import os

src/idom/core/vdom.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,15 @@ def vdom(
114114
import_source: _ImportSourceArg = None,
115115
) -> VdomDict:
116116
"""A helper function for creating VDOM dictionaries.
117+
117118
Parameters:
118119
tag:
119120
The type of element (e.g. 'div', 'h1', 'img')
120121
attributes_and_children:
121-
Attribute mappings followed by iterables of children for the element.
122-
The attributes **must** precede the children, though you may pass multiple
123-
sets of attributes, or children which will be merged into their respective
124-
parts of the model.
122+
Attribute mappings followed by iterables of children for the element. The
123+
attributes **must** precede the children, though you may pass multiple sets
124+
of attributes, or children which will be merged into their respective parts
125+
of the model.
125126
key:
126127
A string idicating the identity of a particular element. This is significant
127128
to preserve event handlers across updates - without a key, a re-render would
@@ -167,6 +168,7 @@ def __call__(
167168

168169
def make_vdom_constructor(tag: str, allow_children: bool = True) -> VdomDictConstructor:
169170
"""Return a constructor for VDOM dictionaries with the given tag name.
171+
170172
The resulting callable will have the same interface as :func:`vdom` but without its
171173
first ``tag`` argument.
172174
"""

src/idom/widgets/utils.py

+40-24
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
Widget Tools
33
============
44
"""
5+
from __future__ import annotations
56

6-
from typing import Any, Callable, Dict, Set, Tuple, TypeVar
7+
from typing import Any, Callable, Dict, Optional, Set, Tuple, TypeVar
78

89
from idom.core import hooks
910
from idom.core.component import ComponentConstructor, component
@@ -97,30 +98,36 @@ def _use_callable(initial_func: _FuncVar) -> Tuple[_FuncVar, Callable[[_Func], N
9798
return state[0], lambda new: state[1](lambda old: new)
9899

99100

100-
def multiview() -> Tuple["MultiViewMount", ComponentConstructor]:
101+
def multiview() -> Tuple[MultiViewMount, ComponentConstructor]:
101102
"""Dynamically add components to a layout on the fly
102103
103104
Since you can't change the component functions used to create a layout
104105
in an imperative manner, you can use ``multiview`` to do this so
105106
long as you set things up ahead of time.
106107
107-
Returns:
108-
A function for adding views and the root of the dynamic view
109-
110108
Examples:
111109
112110
.. code-block::
113111
114112
import idom
115113
116-
define, root = idom.widgets.multiview()
114+
mount, multiview = idom.widgets.multiview()
115+
116+
@idom.component
117+
def Hello():
118+
return idom.html.h1(["hello"])
117119
118-
@component
119-
def Hello(self, phrase):
120-
return idom.html.h1(["hello " + phrase])
120+
# auto static view ID
121+
mount.add("hello", Hello)
122+
# use the view ID to create the associate component instance
123+
hello_component_instance = multiview("hello")
121124
122-
add_hello = define(Hello)
123-
hello_world_view_id = add_hello("world")
125+
@idom.component
126+
def World():
127+
return idom.html.h1(["world"])
128+
129+
generated_view_id = mount.add(None, World)
130+
world_component_instance = multiview(generated_view_id)
124131
125132
Displaying ``root`` with the parameter ``view_id=hello_world_view_id`` will show
126133
the message 'hello world'. Usually though this is achieved by connecting to the
@@ -141,28 +148,37 @@ def MultiView(view_id: str) -> Any:
141148

142149

143150
class MultiViewMount:
151+
"""Mount point for :func:`multiview`"""
144152

145153
__slots__ = "_next_auto_id", "_views"
146154

147155
def __init__(self, views: Dict[str, ComponentConstructor]):
148156
self._next_auto_id = 0
149157
self._views = views
150158

151-
def remove(self, view_id: str) -> None:
152-
del self._views[view_id]
153-
154-
def __getitem__(self, view_id: str) -> Callable[[ComponentConstructor], str]:
155-
def mount(constructor: ComponentConstructor) -> str:
156-
self._views[view_id] = constructor
157-
return view_id
158-
159-
return mount
160-
161-
def __call__(self, constructor: ComponentConstructor) -> str:
162-
self._next_auto_id += 1
163-
view_id = str(self._next_auto_id)
159+
def add(self, view_id: Optional[str], constructor: ComponentConstructor) -> str:
160+
"""Add a component constructor
161+
162+
Parameters:
163+
view_id:
164+
The view ID the constructor will be associated with. If ``None`` then
165+
a view ID will be automatically generated.
166+
constructor:
167+
The component constructor to be mounted. It must accept no arguments.
168+
169+
Returns:
170+
The view ID that was assocaited with the component - most useful for
171+
auto-generated view IDs
172+
"""
173+
if view_id is None:
174+
self._next_auto_id += 1
175+
view_id = str(self._next_auto_id)
164176
self._views[view_id] = constructor
165177
return view_id
166178

179+
def remove(self, view_id: str) -> None:
180+
"""Remove a mounted component constructor given its view ID"""
181+
del self._views[view_id]
182+
167183
def __repr__(self) -> str:
168184
return f"{type(self).__name__}({self._views})"

tests/test_server/test_common/test_multiview.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@ def server_mount_point(request):
3030

3131

3232
def test_multiview_server(driver_get, driver, server_mount_point):
33-
manual_id = server_mount_point.mount["manually_set_id"](
34-
lambda: idom.html.h1({"id": "e1"}, ["e1"])
33+
manual_id = server_mount_point.mount.add(
34+
"manually_set_id",
35+
lambda: idom.html.h1({"id": "e1"}, ["e1"]),
36+
)
37+
auto_view_id = server_mount_point.mount.add(
38+
None,
39+
lambda: idom.html.h1({"id": "e2"}, ["e2"]),
3540
)
36-
auto_view_id = server_mount_point.mount(lambda: idom.html.h1({"id": "e2"}, ["e2"]))
3741

3842
driver_get({"view_id": manual_id})
3943
driver.find_element_by_id("e1")

0 commit comments

Comments
 (0)