Skip to content

Commit 1fd9b66

Browse files
committed
Improved type hints for reactpy.html
1 parent 3c6abe6 commit 1fd9b66

File tree

2 files changed

+277
-10
lines changed

2 files changed

+277
-10
lines changed

src/reactpy/_html.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22

33
from collections.abc import Sequence
4-
from typing import TYPE_CHECKING, ClassVar
4+
from typing import TYPE_CHECKING, ClassVar, overload
55

66
from reactpy.core.vdom import custom_vdom_constructor, make_vdom_constructor
77

@@ -176,6 +176,14 @@ class SvgConstructor:
176176

177177
__cache__: ClassVar[dict[str, VdomDictConstructor]] = {}
178178

179+
@overload
180+
def __call__(
181+
self, attributes: VdomAttributes, /, *children: VdomChildren
182+
) -> VdomDict: ...
183+
184+
@overload
185+
def __call__(self, *children: VdomChildren) -> VdomDict: ...
186+
179187
def __call__(
180188
self, *attributes_and_children: VdomAttributes | VdomChildren
181189
) -> VdomDict:
@@ -261,6 +269,7 @@ def __getattr__(self, value: str) -> VdomDictConstructor:
261269
tspan: VdomDictConstructor
262270
use: VdomDictConstructor
263271
view: VdomDictConstructor
272+
svg: VdomDictConstructor
264273

265274

266275
class HtmlConstructor:
@@ -277,6 +286,7 @@ class HtmlConstructor:
277286
__cache__: ClassVar[dict[str, VdomDictConstructor]] = {
278287
"script": custom_vdom_constructor(_script),
279288
"fragment": custom_vdom_constructor(_fragment),
289+
"svg": SvgConstructor(),
280290
}
281291

282292
def __getattr__(self, value: str) -> VdomDictConstructor:
@@ -410,7 +420,7 @@ def __getattr__(self, value: str) -> VdomDictConstructor:
410420
# Special Case: SVG elements
411421
# Since SVG elements have a different set of allowed children, they are
412422
# separated into a different constructor, and are accessed via `html.svg.example()`
413-
svg: SvgConstructor = SvgConstructor()
423+
svg: SvgConstructor
414424

415425

416426
html = HtmlConstructor()

src/reactpy/types.py

Lines changed: 265 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
from typing import (
1010
TYPE_CHECKING,
1111
Any,
12+
Awaitable,
1213
Callable,
1314
Generic,
1415
Literal,
1516
NamedTuple,
1617
Protocol,
1718
TypeVar,
19+
overload,
1820
runtime_checkable,
1921
)
2022

@@ -92,14 +94,254 @@ async def __aexit__(
9294
"""Clean up the view after its final render"""
9395

9496

95-
VdomAttributes = dict[str, Any]
96-
"""Describes the attributes of a :class:`VdomDict`"""
97-
98-
VdomChild: TypeAlias = "ComponentType | VdomDict | str | None | Any"
99-
"""A single child element of a :class:`VdomDict`"""
100-
101-
VdomChildren: TypeAlias = "Sequence[VdomChild] | VdomChild"
102-
"""Describes a series of :class:`VdomChild` elements"""
97+
EventFunc = Callable[[dict[str, Any]], Awaitable[None] | None]
98+
99+
# TODO: It's probably better to break this one attributes dict down into what each specific
100+
# HTML node's attributes can be, and make sure those types are resolved correctly within `HtmlConstructor`
101+
VdomAttributes = TypedDict(
102+
"VdomAttributes",
103+
{
104+
"dangerouslySetInnerHTML": dict[str, str],
105+
"suppressContentEditableWarning": bool,
106+
"suppressHydrationWarning": bool,
107+
"style": dict[str, str | int | float],
108+
"accessKey": str,
109+
"aria-": None,
110+
"autoCapitalize": str,
111+
"className": str,
112+
"contentEditable": bool,
113+
"data-": None,
114+
"dir": Literal["ltr", "rtl"],
115+
"draggable": bool,
116+
"enterKeyHint": str,
117+
"htmlFor": str,
118+
"hidden": bool | str,
119+
"id": str,
120+
"is": str,
121+
"inputMode": str,
122+
"itemProp": str,
123+
"lang": str,
124+
"onAnimationEnd": EventFunc,
125+
"onAnimationEndCapture": EventFunc,
126+
"onAnimationIteration": EventFunc,
127+
"onAnimationIterationCapture": EventFunc,
128+
"onAnimationStart": EventFunc,
129+
"onAnimationStartCapture": EventFunc,
130+
"onAuxClick": EventFunc,
131+
"onAuxClickCapture": EventFunc,
132+
"onBeforeInput": EventFunc,
133+
"onBeforeInputCapture": EventFunc,
134+
"onBlur": EventFunc,
135+
"onBlurCapture": EventFunc,
136+
"onClick": EventFunc,
137+
"onClickCapture": EventFunc,
138+
"onCompositionStart": EventFunc,
139+
"onCompositionStartCapture": EventFunc,
140+
"onCompositionEnd": EventFunc,
141+
"onCompositionEndCapture": EventFunc,
142+
"onCompositionUpdate": EventFunc,
143+
"onCompositionUpdateCapture": EventFunc,
144+
"onContextMenu": EventFunc,
145+
"onContextMenuCapture": EventFunc,
146+
"onCopy": EventFunc,
147+
"onCopyCapture": EventFunc,
148+
"onCut": EventFunc,
149+
"onCutCapture": EventFunc,
150+
"onDoubleClick": EventFunc,
151+
"onDoubleClickCapture": EventFunc,
152+
"onDrag": EventFunc,
153+
"onDragCapture": EventFunc,
154+
"onDragEnd": EventFunc,
155+
"onDragEndCapture": EventFunc,
156+
"onDragEnter": EventFunc,
157+
"onDragEnterCapture": EventFunc,
158+
"onDragOver": EventFunc,
159+
"onDragOverCapture": EventFunc,
160+
"onDragStart": EventFunc,
161+
"onDragStartCapture": EventFunc,
162+
"onDrop": EventFunc,
163+
"onDropCapture": EventFunc,
164+
"onFocus": EventFunc,
165+
"onFocusCapture": EventFunc,
166+
"onGotPointerCapture": EventFunc,
167+
"onGotPointerCaptureCapture": EventFunc,
168+
"onKeyDown": EventFunc,
169+
"onKeyDownCapture": EventFunc,
170+
"onKeyPress": EventFunc,
171+
"onKeyPressCapture": EventFunc,
172+
"onKeyUp": EventFunc,
173+
"onKeyUpCapture": EventFunc,
174+
"onLostPointerCapture": EventFunc,
175+
"onLostPointerCaptureCapture": EventFunc,
176+
"onMouseDown": EventFunc,
177+
"onMouseDownCapture": EventFunc,
178+
"onMouseEnter": EventFunc,
179+
"onMouseLeave": EventFunc,
180+
"onMouseMove": EventFunc,
181+
"onMouseMoveCapture": EventFunc,
182+
"onMouseOut": EventFunc,
183+
"onMouseOutCapture": EventFunc,
184+
"onMouseUp": EventFunc,
185+
"onMouseUpCapture": EventFunc,
186+
"onPointerCancel": EventFunc,
187+
"onPointerCancelCapture": EventFunc,
188+
"onPointerDown": EventFunc,
189+
"onPointerDownCapture": EventFunc,
190+
"onPointerEnter": EventFunc,
191+
"onPointerLeave": EventFunc,
192+
"onPointerMove": EventFunc,
193+
"onPointerMoveCapture": EventFunc,
194+
"onPointerOut": EventFunc,
195+
"onPointerOutCapture": EventFunc,
196+
"onPointerUp": EventFunc,
197+
"onPointerUpCapture": EventFunc,
198+
"onPaste": EventFunc,
199+
"onPasteCapture": EventFunc,
200+
"onScroll": EventFunc,
201+
"onScrollCapture": EventFunc,
202+
"onSelect": EventFunc,
203+
"onSelectCapture": EventFunc,
204+
"onTouchCancel": EventFunc,
205+
"onTouchCancelCapture": EventFunc,
206+
"onTouchEnd": EventFunc,
207+
"onTouchEndCapture": EventFunc,
208+
"onTouchMove": EventFunc,
209+
"onTouchMoveCapture": EventFunc,
210+
"onTouchStart": EventFunc,
211+
"onTouchStartCapture": EventFunc,
212+
"onTransitionEnd": EventFunc,
213+
"onTransitionEndCapture": EventFunc,
214+
"onWheel": EventFunc,
215+
"onWheelCapture": EventFunc,
216+
"role": str,
217+
"slot": str,
218+
"spellCheck": bool | None,
219+
"tabIndex": int,
220+
"title": str,
221+
"translate": Literal["yes", "no"],
222+
"onReset": EventFunc,
223+
"onResetCapture": EventFunc,
224+
"onSubmit": EventFunc,
225+
"onSubmitCapture": EventFunc,
226+
"formAction": str | Callable,
227+
"checked": bool,
228+
"value": str,
229+
"defaultChecked": bool,
230+
"defaultValue": str,
231+
"accept": str,
232+
"alt": str,
233+
"capture": str,
234+
"autoComplete": str,
235+
"autoFocus": bool,
236+
"dirname": str,
237+
"disabled": bool,
238+
"form": str,
239+
"formEnctype": str,
240+
"formMethod": str,
241+
"formNoValidate": str,
242+
"formTarget": str,
243+
"height": str,
244+
"list": str,
245+
"max": int,
246+
"maxLength": int,
247+
"min": int,
248+
"minLength": int,
249+
"multiple": bool,
250+
"name": str,
251+
"onChange": EventFunc,
252+
"onChangeCapture": EventFunc,
253+
"onInput": EventFunc,
254+
"onInputCapture": EventFunc,
255+
"onInvalid": EventFunc,
256+
"onInvalidCapture": EventFunc,
257+
"pattern": str,
258+
"placeholder": str,
259+
"readOnly": bool,
260+
"required": bool,
261+
"size": int,
262+
"src": str,
263+
"step": int | Literal["any"],
264+
"type": str,
265+
"width": str,
266+
"label": str,
267+
"cols": int,
268+
"rows": int,
269+
"wrap": Literal["hard", "soft", "off"],
270+
"rel": str,
271+
"precedence": str,
272+
"media": str,
273+
"onError": EventFunc,
274+
"onLoad": EventFunc,
275+
"as": str,
276+
"imageSrcSet": str,
277+
"imageSizes": str,
278+
"sizes": str,
279+
"href": str,
280+
"crossOrigin": str,
281+
"referrerPolicy": str,
282+
"fetchPriority": str,
283+
"hrefLang": str,
284+
"integrity": str,
285+
"blocking": str,
286+
"async": bool,
287+
"noModule": bool,
288+
"nonce": str,
289+
"referrer": str,
290+
"defer": str,
291+
"onToggle": EventFunc,
292+
"onToggleCapture": EventFunc,
293+
"onLoadCapture": EventFunc,
294+
"onErrorCapture": EventFunc,
295+
"onAbort": EventFunc,
296+
"onAbortCapture": EventFunc,
297+
"onCanPlay": EventFunc,
298+
"onCanPlayCapture": EventFunc,
299+
"onCanPlayThrough": EventFunc,
300+
"onCanPlayThroughCapture": EventFunc,
301+
"onDurationChange": EventFunc,
302+
"onDurationChangeCapture": EventFunc,
303+
"onEmptied": EventFunc,
304+
"onEmptiedCapture": EventFunc,
305+
"onEncrypted": EventFunc,
306+
"onEncryptedCapture": EventFunc,
307+
"onEnded": EventFunc,
308+
"onEndedCapture": EventFunc,
309+
"onLoadedData": EventFunc,
310+
"onLoadedDataCapture": EventFunc,
311+
"onLoadedMetadata": EventFunc,
312+
"onLoadedMetadataCapture": EventFunc,
313+
"onLoadStart": EventFunc,
314+
"onLoadStartCapture": EventFunc,
315+
"onPause": EventFunc,
316+
"onPauseCapture": EventFunc,
317+
"onPlay": EventFunc,
318+
"onPlayCapture": EventFunc,
319+
"onPlaying": EventFunc,
320+
"onPlayingCapture": EventFunc,
321+
"onProgress": EventFunc,
322+
"onProgressCapture": EventFunc,
323+
"onRateChange": EventFunc,
324+
"onRateChangeCapture": EventFunc,
325+
"onResize": EventFunc,
326+
"onResizeCapture": EventFunc,
327+
"onSeeked": EventFunc,
328+
"onSeekedCapture": EventFunc,
329+
"onSeeking": EventFunc,
330+
"onSeekingCapture": EventFunc,
331+
"onStalled": EventFunc,
332+
"onStalledCapture": EventFunc,
333+
"onSuspend": EventFunc,
334+
"onSuspendCapture": EventFunc,
335+
"onTimeUpdate": EventFunc,
336+
"onTimeUpdateCapture": EventFunc,
337+
"onVolumeChange": EventFunc,
338+
"onVolumeChangeCapture": EventFunc,
339+
"onWaiting": EventFunc,
340+
"onWaitingCapture": EventFunc,
341+
},
342+
total=False,
343+
extra_items=Any,
344+
)
103345

104346

105347
class _VdomDictOptional(TypedDict, total=False):
@@ -118,6 +360,13 @@ class VdomDict(_VdomDictRequired, _VdomDictOptional):
118360
"""A :ref:`VDOM` dictionary"""
119361

120362

363+
VdomChild: TypeAlias = "ComponentType | VdomDict | str | None | Any"
364+
"""A single child element of a :class:`VdomDict`"""
365+
366+
VdomChildren: TypeAlias = "Sequence[VdomChild] | VdomChild"
367+
"""Describes a series of :class:`VdomChild` elements"""
368+
369+
121370
class ImportSourceDict(TypedDict):
122371
source: str
123372
fallback: Any
@@ -194,6 +443,14 @@ class EventHandlerType(Protocol):
194443
class VdomDictConstructor(Protocol):
195444
"""Standard function for constructing a :class:`VdomDict`"""
196445

446+
@overload
447+
def __call__(
448+
self, attributes: VdomAttributes, /, *children: VdomChildren
449+
) -> VdomDict: ...
450+
451+
@overload
452+
def __call__(self, *children: VdomChildren) -> VdomDict: ...
453+
197454
def __call__(
198455
self, *attributes_and_children: VdomAttributes | VdomChildren
199456
) -> VdomDict: ...

0 commit comments

Comments
 (0)