17
17
EventHandlerMapping ,
18
18
EventHandlerType ,
19
19
ImportSourceDict ,
20
- VdomAttributesAndChildren ,
20
+ Key ,
21
+ VdomChild ,
21
22
VdomDict ,
22
23
VdomJson ,
23
24
)
@@ -129,43 +130,47 @@ def is_vdom(value: Any) -> bool:
129
130
130
131
def vdom (
131
132
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 ,
133
+ / ,
134
+ * children : VdomChild ,
135
+ key : Key | None = None ,
136
+ event_handlers : EventHandlerMapping | None = None ,
137
+ import_source : ImportSourceDict | None = None ,
138
+ ** attributes : Any ,
136
139
) -> VdomDict :
137
140
"""A helper function for creating VDOM dictionaries.
138
141
139
142
Parameters:
140
143
tag:
141
144
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.
145
+ children:
146
+ String, compoennts, or other VDOM elements that are this element's children.
146
147
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.
148
+ A string or integer idicating the identity of a particular element. This is
149
+ significant to preserve event handlers across updates - without a key, a
150
+ re-render would cause these handlers to be deleted, but with a key, they
151
+ would be redirected to any newly defined handlers.
151
152
event_handlers:
152
- Maps event types to coroutines that are responsible for handling those events.
153
+ Maps event types to coroutines that are responsible for handling those
154
+ events.
153
155
import_source:
154
156
(subject to change) specifies javascript that, when evaluated returns a
155
157
React component.
158
+ attributes:
159
+ Remaining attributes of this element.
156
160
"""
157
161
model : VdomDict = {"tagName" : tag }
158
162
159
- attributes , children = coalesce_attributes_and_children (attributes_and_children )
160
163
attributes , event_handlers = separate_attributes_and_event_handlers (
161
- attributes , event_handlers or {}
164
+ attributes , event_handlers
162
165
)
163
166
164
167
if attributes :
168
+ if "cls" in attributes :
169
+ attributes ["class" ] = attributes .pop ("cls" )
165
170
model ["attributes" ] = attributes
166
171
167
172
if children :
168
- model ["children" ] = children
173
+ model ["children" ] = flatten_children ( children )
169
174
170
175
if event_handlers :
171
176
model ["eventHandlers" ] = event_handlers
@@ -179,17 +184,6 @@ def vdom(
179
184
return model
180
185
181
186
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
187
def make_vdom_constructor (
194
188
tag : str , allow_children : bool = True
195
189
) -> _VdomDictConstructor :
@@ -199,19 +193,8 @@ def make_vdom_constructor(
199
193
first ``tag`` argument.
200
194
"""
201
195
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
- )
196
+ def constructor (* args : Any , ** kwargs : Any ) -> VdomDict :
197
+ model = vdom (* args , ** kwargs )
215
198
if not allow_children and "children" in model :
216
199
raise TypeError (f"{ tag !r} nodes cannot have children." )
217
200
return model
@@ -232,35 +215,24 @@ def constructor(
232
215
return constructor
233
216
234
217
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 :
218
+ def flatten_children (children : Sequence [VdomChild ]) -> Sequence [VdomChild ]:
219
+ child_list : list [VdomChild ] = []
220
+ for child in children :
249
221
if _is_single_child (child ):
250
- children .append (child )
222
+ child_list .append (child )
251
223
else :
252
- children .extend (child )
253
-
254
- return attributes , children
224
+ child_list .extend (child )
225
+ return child_list
255
226
256
227
257
228
def separate_attributes_and_event_handlers (
258
- attributes : Mapping [str , Any ], event_handlers : EventHandlerMapping
229
+ attributes : Mapping [str , Any ],
230
+ event_handlers : EventHandlerMapping | None = None ,
259
231
) -> Tuple [Dict [str , Any ], EventHandlerDict ]:
260
232
separated_attributes = {}
261
233
separated_event_handlers : Dict [str , List [EventHandlerType ]] = {}
262
234
263
- for k , v in event_handlers .items ():
235
+ for k , v in ( event_handlers or {}) .items ():
264
236
separated_event_handlers [k ] = [v ]
265
237
266
238
for k , v in attributes .items ():
@@ -339,3 +311,17 @@ def _is_single_child(value: Any) -> bool:
339
311
class _EllipsisRepr :
340
312
def __repr__ (self ) -> str :
341
313
return "..."
314
+
315
+
316
+ class _VdomDictConstructor (Protocol ):
317
+ def __call__ (
318
+ self ,
319
+ tag : str ,
320
+ / ,
321
+ * children : VdomChild ,
322
+ key : str | int | None = None ,
323
+ event_handlers : EventHandlerMapping | None = None ,
324
+ import_source : ImportSourceDict | None = None ,
325
+ ** attributes : Any ,
326
+ ) -> VdomDict :
327
+ ...
0 commit comments