1717 EventHandlerMapping ,
1818 EventHandlerType ,
1919 ImportSourceDict ,
20- VdomAttributesAndChildren ,
20+ Key ,
21+ VdomChild ,
2122 VdomDict ,
23+ VdomDictConstructor ,
2224 VdomJson ,
2325)
2426
@@ -129,43 +131,47 @@ def is_vdom(value: Any) -> bool:
129131
130132def vdom (
131133 tag : str ,
132- * attributes_and_children : VdomAttributesAndChildren ,
133- key : str | int | None = None ,
134- event_handlers : Optional [EventHandlerMapping ] = None ,
135- import_source : Optional [ImportSourceDict ] = None ,
134+ / ,
135+ * children : VdomChild ,
136+ key : Key | None = None ,
137+ event_handlers : EventHandlerMapping | None = None ,
138+ import_source : ImportSourceDict | None = None ,
139+ ** attributes : Any ,
136140) -> VdomDict :
137141 """A helper function for creating VDOM dictionaries.
138142
139143 Parameters:
140144 tag:
141145 The type of element (e.g. 'div', 'h1', 'img')
142- attributes_and_children:
143- An optional attribute mapping followed by any number of children or
144- iterables of children. The attribute mapping **must** precede the children,
145- or children which will be merged into their respective parts of the model.
146+ children:
147+ String, compoennts, or other VDOM elements that are this element's children.
146148 key:
147- A string idicating the identity of a particular element. This is significant
148- to preserve event handlers across updates - without a key, a re-render would
149- cause these handlers to be deleted, but with a key, they would be redirected
150- to any newly defined handlers.
149+ A string or integer idicating the identity of a particular element. This is
150+ significant to preserve event handlers across updates - without a key, a
151+ re-render would cause these handlers to be deleted, but with a key, they
152+ would be redirected to any newly defined handlers.
151153 event_handlers:
152- Maps event types to coroutines that are responsible for handling those events.
154+ Maps event types to coroutines that are responsible for handling those
155+ events.
153156 import_source:
154157 (subject to change) specifies javascript that, when evaluated returns a
155158 React component.
159+ attributes:
160+ Remaining attributes of this element.
156161 """
157162 model : VdomDict = {"tagName" : tag }
158163
159- attributes , children = coalesce_attributes_and_children (attributes_and_children )
160164 attributes , event_handlers = separate_attributes_and_event_handlers (
161- attributes , event_handlers or {}
165+ attributes , event_handlers
162166 )
163167
164168 if attributes :
169+ if "cls" in attributes :
170+ attributes ["class" ] = attributes .pop ("cls" )
165171 model ["attributes" ] = attributes
166172
167173 if children :
168- model ["children" ] = children
174+ model ["children" ] = flatten_children ( children )
169175
170176 if event_handlers :
171177 model ["eventHandlers" ] = event_handlers
@@ -179,39 +185,15 @@ def vdom(
179185 return model
180186
181187
182- class _VdomDictConstructor (Protocol ):
183- def __call__ (
184- self ,
185- * attributes_and_children : VdomAttributesAndChildren ,
186- key : str | int | None = ...,
187- event_handlers : Optional [EventHandlerMapping ] = ...,
188- import_source : Optional [ImportSourceDict ] = ...,
189- ) -> VdomDict :
190- ...
191-
192-
193- def make_vdom_constructor (
194- tag : str , allow_children : bool = True
195- ) -> _VdomDictConstructor :
188+ def make_vdom_constructor (tag : str , allow_children : bool = True ) -> VdomDictConstructor :
196189 """Return a constructor for VDOM dictionaries with the given tag name.
197190
198191 The resulting callable will have the same interface as :func:`vdom` but without its
199192 first ``tag`` argument.
200193 """
201194
202- def constructor (
203- * attributes_and_children : VdomAttributesAndChildren ,
204- key : str | int | None = None ,
205- event_handlers : Optional [EventHandlerMapping ] = None ,
206- import_source : Optional [ImportSourceDict ] = None ,
207- ) -> VdomDict :
208- model = vdom (
209- tag ,
210- * attributes_and_children ,
211- key = key ,
212- event_handlers = event_handlers ,
213- import_source = import_source ,
214- )
195+ def constructor (* args : Any , ** kwargs : Any ) -> VdomDict :
196+ model = vdom (tag , * args , ** kwargs )
215197 if not allow_children and "children" in model :
216198 raise TypeError (f"{ tag !r} nodes cannot have children." )
217199 return model
@@ -232,35 +214,24 @@ def constructor(
232214 return constructor
233215
234216
235- def coalesce_attributes_and_children (
236- values : Sequence [Any ],
237- ) -> Tuple [Mapping [str , Any ], List [Any ]]:
238- if not values :
239- return {}, []
240-
241- children_or_iterables : Sequence [Any ]
242- attributes , * children_or_iterables = values
243- if not _is_attributes (attributes ):
244- attributes = {}
245- children_or_iterables = values
246-
247- children : List [Any ] = []
248- for child in children_or_iterables :
217+ def flatten_children (children : Sequence [VdomChild ]) -> Sequence [VdomChild ]:
218+ child_list : list [VdomChild ] = []
219+ for child in children :
249220 if _is_single_child (child ):
250- children .append (child )
221+ child_list .append (child )
251222 else :
252- children .extend (child )
253-
254- return attributes , children
223+ child_list .extend (child )
224+ return child_list
255225
256226
257227def separate_attributes_and_event_handlers (
258- attributes : Mapping [str , Any ], event_handlers : EventHandlerMapping
228+ attributes : Mapping [str , Any ],
229+ event_handlers : EventHandlerMapping | None = None ,
259230) -> Tuple [Dict [str , Any ], EventHandlerDict ]:
260231 separated_attributes = {}
261232 separated_event_handlers : Dict [str , List [EventHandlerType ]] = {}
262233
263- for k , v in event_handlers .items ():
234+ for k , v in ( event_handlers or {}) .items ():
264235 separated_event_handlers [k ] = [v ]
265236
266237 for k , v in attributes .items ():
0 commit comments