add type hinting to dataeditor events
This commit is contained in:
parent
f39e8c9667
commit
725f146381
@ -5,6 +5,8 @@ from __future__ import annotations
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
|
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
|
||||||
|
|
||||||
|
from typing_extensions import TypedDict
|
||||||
|
|
||||||
from reflex.base import Base
|
from reflex.base import Base
|
||||||
from reflex.components.component import Component, NoSSRComponent
|
from reflex.components.component import Component, NoSSRComponent
|
||||||
from reflex.components.literals import LiteralRowMarker
|
from reflex.components.literals import LiteralRowMarker
|
||||||
@ -120,6 +122,78 @@ def on_edit_spec(pos, data: dict[str, Any]):
|
|||||||
return [pos, data]
|
return [pos, data]
|
||||||
|
|
||||||
|
|
||||||
|
class Bounds(TypedDict):
|
||||||
|
"""The bounds of the group header."""
|
||||||
|
|
||||||
|
x: int
|
||||||
|
y: int
|
||||||
|
width: int
|
||||||
|
height: int
|
||||||
|
|
||||||
|
|
||||||
|
class CompatSelection(TypedDict):
|
||||||
|
"""The selection."""
|
||||||
|
|
||||||
|
items: list
|
||||||
|
|
||||||
|
|
||||||
|
class Rectangle(TypedDict):
|
||||||
|
"""The bounds of the group header."""
|
||||||
|
|
||||||
|
x: int
|
||||||
|
y: int
|
||||||
|
width: int
|
||||||
|
height: int
|
||||||
|
|
||||||
|
|
||||||
|
class GridSelectionCurrent(TypedDict):
|
||||||
|
"""The current selection."""
|
||||||
|
|
||||||
|
cell: list[int]
|
||||||
|
range: Rectangle
|
||||||
|
rangeStack: list[Rectangle]
|
||||||
|
|
||||||
|
|
||||||
|
class GridSelection(TypedDict):
|
||||||
|
"""The grid selection."""
|
||||||
|
|
||||||
|
current: Optional[GridSelectionCurrent]
|
||||||
|
columns: CompatSelection
|
||||||
|
rows: CompatSelection
|
||||||
|
|
||||||
|
|
||||||
|
class GroupHeaderClickedEventArgs(TypedDict):
|
||||||
|
"""The arguments for the group header clicked event."""
|
||||||
|
|
||||||
|
kind: str
|
||||||
|
group: str
|
||||||
|
location: list[int]
|
||||||
|
bounds: Bounds
|
||||||
|
isEdge: bool
|
||||||
|
shiftKey: bool
|
||||||
|
ctrlKey: bool
|
||||||
|
metaKey: bool
|
||||||
|
isTouch: bool
|
||||||
|
localEventX: int
|
||||||
|
localEventY: int
|
||||||
|
button: int
|
||||||
|
buttons: int
|
||||||
|
scrollEdge: list[int]
|
||||||
|
|
||||||
|
|
||||||
|
class GridCell(TypedDict):
|
||||||
|
"""The grid cell."""
|
||||||
|
|
||||||
|
span: Optional[List[int]]
|
||||||
|
|
||||||
|
|
||||||
|
class GridColumn(TypedDict):
|
||||||
|
"""The grid column."""
|
||||||
|
|
||||||
|
title: str
|
||||||
|
group: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
class DataEditor(NoSSRComponent):
|
class DataEditor(NoSSRComponent):
|
||||||
"""The DataEditor Component."""
|
"""The DataEditor Component."""
|
||||||
|
|
||||||
@ -238,10 +312,12 @@ class DataEditor(NoSSRComponent):
|
|||||||
on_group_header_clicked: EventHandler[on_edit_spec]
|
on_group_header_clicked: EventHandler[on_edit_spec]
|
||||||
|
|
||||||
# Fired when a group header is right-clicked.
|
# Fired when a group header is right-clicked.
|
||||||
on_group_header_context_menu: EventHandler[lambda grp_idx, data: [grp_idx, data]]
|
on_group_header_context_menu: EventHandler[
|
||||||
|
identity_event(int, GroupHeaderClickedEventArgs)
|
||||||
|
]
|
||||||
|
|
||||||
# Fired when a group header is renamed.
|
# Fired when a group header is renamed.
|
||||||
on_group_header_renamed: EventHandler[lambda idx, val: [idx, val]]
|
on_group_header_renamed: EventHandler[identity_event(str, str)]
|
||||||
|
|
||||||
# Fired when a header is clicked.
|
# Fired when a header is clicked.
|
||||||
on_header_clicked: EventHandler[identity_event(Tuple[int, int])]
|
on_header_clicked: EventHandler[identity_event(Tuple[int, int])]
|
||||||
@ -250,16 +326,16 @@ class DataEditor(NoSSRComponent):
|
|||||||
on_header_context_menu: EventHandler[identity_event(Tuple[int, int])]
|
on_header_context_menu: EventHandler[identity_event(Tuple[int, int])]
|
||||||
|
|
||||||
# Fired when a header menu item is clicked.
|
# Fired when a header menu item is clicked.
|
||||||
on_header_menu_click: EventHandler[lambda col, pos: [col, pos]]
|
on_header_menu_click: EventHandler[identity_event(int, Rectangle)]
|
||||||
|
|
||||||
# Fired when an item is hovered.
|
# Fired when an item is hovered.
|
||||||
on_item_hovered: EventHandler[identity_event(Tuple[int, int])]
|
on_item_hovered: EventHandler[identity_event(Tuple[int, int])]
|
||||||
|
|
||||||
# Fired when a selection is deleted.
|
# Fired when a selection is deleted.
|
||||||
on_delete: EventHandler[lambda selection: [selection]]
|
on_delete: EventHandler[identity_event(GridSelection)]
|
||||||
|
|
||||||
# Fired when editing is finished.
|
# Fired when editing is finished.
|
||||||
on_finished_editing: EventHandler[lambda new_value, movement: [new_value, movement]]
|
on_finished_editing: EventHandler[identity_event(Optional[GridCell], list[int])]
|
||||||
|
|
||||||
# Fired when a row is appended.
|
# Fired when a row is appended.
|
||||||
on_row_appended: EventHandler[empty_event]
|
on_row_appended: EventHandler[empty_event]
|
||||||
@ -268,7 +344,7 @@ class DataEditor(NoSSRComponent):
|
|||||||
on_selection_cleared: EventHandler[empty_event]
|
on_selection_cleared: EventHandler[empty_event]
|
||||||
|
|
||||||
# Fired when a column is resized.
|
# Fired when a column is resized.
|
||||||
on_column_resize: EventHandler[lambda col, width: [col, width]]
|
on_column_resize: EventHandler[identity_event(GridColumn, int, int)]
|
||||||
|
|
||||||
def add_imports(self) -> ImportDict:
|
def add_imports(self) -> ImportDict:
|
||||||
"""Add imports for the component.
|
"""Add imports for the component.
|
||||||
|
@ -25,7 +25,7 @@ from typing import (
|
|||||||
overload,
|
overload,
|
||||||
)
|
)
|
||||||
|
|
||||||
from typing_extensions import ParamSpec, get_args, get_origin
|
from typing_extensions import ParamSpec, Protocol, get_args, get_origin
|
||||||
|
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.utils import console, format
|
from reflex.utils import console, format
|
||||||
@ -468,33 +468,97 @@ prevent_default = EventChain(events=[], args_spec=empty_event).prevent_default
|
|||||||
|
|
||||||
|
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
U = TypeVar("U")
|
||||||
|
|
||||||
|
|
||||||
def identity_event(event_type: Type[T]) -> Callable[[Var[T]], Tuple[Var[T]]]:
|
# def identity_event(event_type: Type[T]) -> Callable[[Var[T]], Tuple[Var[T]]]:
|
||||||
|
# """A helper function that returns the input event as output.
|
||||||
|
|
||||||
|
# Args:
|
||||||
|
# event_type: The type of the event.
|
||||||
|
|
||||||
|
# Returns:
|
||||||
|
# A function that returns the input event as output.
|
||||||
|
# """
|
||||||
|
|
||||||
|
# def inner(ev: Var[T]) -> Tuple[Var[T]]:
|
||||||
|
# return (ev,)
|
||||||
|
|
||||||
|
# inner.__signature__ = inspect.signature(inner).replace( # type: ignore
|
||||||
|
# parameters=[
|
||||||
|
# inspect.Parameter(
|
||||||
|
# "ev",
|
||||||
|
# kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
||||||
|
# annotation=Var[event_type],
|
||||||
|
# )
|
||||||
|
# ],
|
||||||
|
# return_annotation=Tuple[Var[event_type]],
|
||||||
|
# )
|
||||||
|
# inner.__annotations__["ev"] = Var[event_type]
|
||||||
|
# inner.__annotations__["return"] = Tuple[Var[event_type]]
|
||||||
|
|
||||||
|
# return inner
|
||||||
|
|
||||||
|
|
||||||
|
class IdentityEventReturn(Generic[T], Protocol):
|
||||||
|
"""Protocol for an identity event return."""
|
||||||
|
|
||||||
|
def __call__(self, *values: Var[T]) -> Tuple[Var[T], ...]:
|
||||||
|
"""Return the input values.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
*values: The values to return.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The input values.
|
||||||
|
"""
|
||||||
|
return values
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def identity_event(event_type: Type[T], /) -> Callable[[Var[T]], Tuple[Var[T]]]: ... # type: ignore
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def identity_event(
|
||||||
|
event_type_1: Type[T], event_type2: Type[U], /
|
||||||
|
) -> Callable[[Var[T], Var[U]], Tuple[Var[T], Var[U]]]: ...
|
||||||
|
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def identity_event(*event_types: Type[T]) -> IdentityEventReturn[T]: ...
|
||||||
|
|
||||||
|
|
||||||
|
def identity_event(*event_types: Type[T]) -> IdentityEventReturn[T]: # type: ignore
|
||||||
"""A helper function that returns the input event as output.
|
"""A helper function that returns the input event as output.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
event_type: The type of the event.
|
*event_types: The types of the events.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A function that returns the input event as output.
|
A function that returns the input event as output.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def inner(ev: Var[T]) -> Tuple[Var[T]]:
|
def inner(*values: Var[T]) -> Tuple[Var[T], ...]:
|
||||||
return (ev,)
|
return values
|
||||||
|
|
||||||
|
inner_type = tuple(Var[event_type] for event_type in event_types)
|
||||||
|
return_annotation = Tuple[inner_type] # type: ignore
|
||||||
|
|
||||||
inner.__signature__ = inspect.signature(inner).replace( # type: ignore
|
inner.__signature__ = inspect.signature(inner).replace( # type: ignore
|
||||||
parameters=[
|
parameters=[
|
||||||
inspect.Parameter(
|
inspect.Parameter(
|
||||||
"ev",
|
f"ev_{i}",
|
||||||
kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
||||||
annotation=Var[event_type],
|
annotation=Var[event_type],
|
||||||
)
|
)
|
||||||
|
for i, event_type in enumerate(event_types)
|
||||||
],
|
],
|
||||||
return_annotation=Tuple[Var[event_type]],
|
return_annotation=return_annotation,
|
||||||
)
|
)
|
||||||
inner.__annotations__["ev"] = Var[event_type]
|
for i, event_type in enumerate(event_types):
|
||||||
inner.__annotations__["return"] = Tuple[Var[event_type]]
|
inner.__annotations__[f"ev_{i}"] = Var[event_type]
|
||||||
|
inner.__annotations__["return"] = return_annotation
|
||||||
|
|
||||||
return inner
|
return inner
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user