|
5 | 5 |
|
6 | 6 | from __future__ import annotations
|
7 | 7 |
|
8 |
| -from typing import Any, Dict, Iterable, List, Mapping, Optional, Sequence, Tuple, Union |
| 8 | +from typing import Any, Iterable, List, Mapping, Optional, Sequence, Tuple, Union |
9 | 9 |
|
10 | 10 | from fastjsonschema import compile as compile_json_schema
|
11 | 11 | from mypy_extensions import TypedDict
|
@@ -119,10 +119,9 @@ def vdom(
|
119 | 119 | tag:
|
120 | 120 | The type of element (e.g. 'div', 'h1', 'img')
|
121 | 121 | attributes_and_children:
|
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. |
| 122 | + An optional attribute mapping followed by any number of children or |
| 123 | + iterables of children. The attribute mapping **must** precede the children, |
| 124 | + or children which will be merged into their respective parts of the model. |
126 | 125 | key:
|
127 | 126 | A string idicating the identity of a particular element. This is significant
|
128 | 127 | to preserve event handlers across updates - without a key, a re-render would
|
@@ -201,26 +200,22 @@ def constructor(
|
201 | 200 |
|
202 | 201 |
|
203 | 202 | def coalesce_attributes_and_children(
|
204 |
| - attributes_and_children: _AttributesAndChildrenArg, |
205 |
| -) -> Tuple[Dict[str, Any], List[Any]]: |
206 |
| - attributes: Dict[str, Any] = {} |
207 |
| - children: List[Any] = [] |
| 203 | + values: Sequence[Any], |
| 204 | +) -> Tuple[Mapping[str, Any], List[Any]]: |
| 205 | + if not values: |
| 206 | + return {}, [] |
| 207 | + |
| 208 | + children_or_iterables: Sequence[Any] |
| 209 | + attributes, *children_or_iterables = values |
| 210 | + if not isinstance(attributes, Mapping) or "tagName" in attributes: |
| 211 | + attributes = {} |
| 212 | + children_or_iterables = values |
208 | 213 |
|
209 |
| - began_children = False |
210 |
| - for argument in attributes_and_children: |
211 |
| - if isinstance(argument, Mapping): |
212 |
| - if "tagName" not in argument: |
213 |
| - if began_children: |
214 |
| - raise ValueError("Attribute dictionaries should precede children.") |
215 |
| - attributes.update(argument) |
216 |
| - else: |
217 |
| - children.append(argument) |
218 |
| - began_children = True |
219 |
| - elif not isinstance(argument, str) and isinstance(argument, Iterable): |
220 |
| - children.extend(argument) |
221 |
| - began_children = True |
| 214 | + children: List[Any] = [] |
| 215 | + for child in children_or_iterables: |
| 216 | + if isinstance(child, (str, Mapping)) or not hasattr(child, "__iter__"): |
| 217 | + children.append(child) |
222 | 218 | else:
|
223 |
| - children.append(argument) |
224 |
| - began_children = True |
| 219 | + children.extend(child) |
225 | 220 |
|
226 | 221 | return attributes, children
|
0 commit comments