Add keypress event handlers (#523)

This commit is contained in:
Nikhil Rao 2023-02-12 13:12:57 -08:00 committed by GitHub
parent 8de2163d84
commit 0bd8f6acfc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 101 additions and 117 deletions

View File

@ -166,7 +166,8 @@ class Component(Base, ABC):
ValueError: If the value is not a valid event chain.
"""
# Check if the trigger is a controlled event.
is_controlled_event = event_trigger in self.get_controlled_triggers()
controlled_triggers = self.get_controlled_triggers()
is_controlled_event = event_trigger in controlled_triggers
# If it's an event chain var, return it.
if isinstance(value, Var):
@ -174,7 +175,7 @@ class Component(Base, ABC):
raise ValueError(f"Invalid event chain: {value}")
return value
arg = self.get_controlled_value()
arg = controlled_triggers.get(event_trigger, EVENT_ARG)
# If the input is a single event handler, wrap it in a list.
if isinstance(value, EventHandler):
@ -231,25 +232,16 @@ class Component(Base, ABC):
Returns:
The event triggers.
"""
return EVENT_TRIGGERS | cls.get_controlled_triggers()
return EVENT_TRIGGERS | set(cls.get_controlled_triggers())
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Get the event triggers that pass the component's value to the handler.
Returns:
The controlled event triggers.
A dict mapping the event trigger to the var that is passed to the handler.
"""
return set()
@classmethod
def get_controlled_value(cls) -> Var:
"""Get the var that is passed to the event handler for controlled triggers.
Returns:
The controlled value.
"""
return EVENT_ARG
return {}
@classmethod
def get_alias(cls) -> Optional[str]:

View File

@ -1,6 +1,6 @@
"""A checkbox component."""
from typing import Set
from typing import Dict
from pynecone.components.component import EVENT_ARG
from pynecone.components.libs.chakra import ChakraComponent
@ -46,22 +46,15 @@ class Checkbox(ChakraComponent):
spacing: Var[str]
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Get the event triggers that pass the component's value to the handler.
Returns:
The controlled event triggers.
A dict mapping the event trigger to the var that is passed to the handler.
"""
return {"on_change"}
@classmethod
def get_controlled_value(cls) -> Var:
"""Get the var that is passed to the event handler for controlled triggers.
Returns:
The controlled value.
"""
return EVENT_ARG.target.checked
return {
"on_change": EVENT_ARG.target.checked,
}
class CheckboxGroup(ChakraComponent):

View File

@ -1,8 +1,9 @@
"""An editable component."""
from typing import Set
from typing import Dict
from pynecone.components.libs.chakra import ChakraComponent
from pynecone.event import EVENT_ARG
from pynecone.var import Var
@ -36,17 +37,17 @@ class Editable(ChakraComponent):
default_value: Var[str]
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Get the event triggers that pass the component's value to the handler.
Returns:
The controlled event triggers.
A dict mapping the event trigger to the var that is passed to the handler.
"""
return {
"on_change",
"on_edit",
"on_submit",
"on_cancel",
"on_change": EVENT_ARG,
"on_edit": EVENT_ARG,
"on_submit": EVENT_ARG,
"on_cancel": EVENT_ARG,
}

View File

@ -1,6 +1,6 @@
"""An input component."""
from typing import Set
from typing import Dict
from pynecone.components.component import EVENT_ARG
from pynecone.components.libs.chakra import ChakraComponent
@ -49,22 +49,20 @@ class Input(ChakraComponent):
size: Var[str]
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Get the event triggers that pass the component's value to the handler.
Returns:
The controlled event triggers.
A dict mapping the event trigger to the var that is passed to the handler.
"""
return {"on_change", "on_focus", "on_blur"}
@classmethod
def get_controlled_value(cls) -> Var:
"""Get the var that is passed to the event handler for controlled triggers.
Returns:
The controlled value.
"""
return EVENT_ARG.target.value
return {
"on_change": EVENT_ARG.target.value,
"on_focus": EVENT_ARG.target.value,
"on_blur": EVENT_ARG.target.value,
"on_key_down": EVENT_ARG.key,
"on_key_press": EVENT_ARG.key,
"on_key_up": EVENT_ARG.key,
}
class InputGroup(ChakraComponent):

View File

@ -1,9 +1,10 @@
"""A number input component."""
from typing import Set
from typing import Dict
from pynecone.components.component import Component
from pynecone.components.libs.chakra import ChakraComponent
from pynecone.event import EVENT_ARG
from pynecone.var import Var
@ -64,13 +65,15 @@ class NumberInput(ChakraComponent):
variant: Var[str]
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Get the event triggers that pass the component's value to the handler.
Returns:
The controlled event triggers.
A dict mapping the event trigger to the var that is passed to the handler.
"""
return {"on_change"}
return {
"on_change": EVENT_ARG,
}
@classmethod
def create(cls, *children, **props) -> Component:

View File

@ -1,9 +1,10 @@
"""A pin input component."""
from typing import Set
from typing import Dict
from pynecone.components.component import Component
from pynecone.components.libs.chakra import ChakraComponent
from pynecone.event import EVENT_ARG
from pynecone.var import Var
@ -55,13 +56,16 @@ class PinInput(ChakraComponent):
variant: Var[str]
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Get the event triggers that pass the component's value to the handler.
Returns:
The controlled event triggers.
A dict mapping the event trigger to the var that is passed to the handler.
"""
return {"on_change", "on_complete"}
return {
"on_change": EVENT_ARG,
"on_complete": EVENT_ARG,
}
@classmethod
def create(cls, *children, **props) -> Component:

View File

@ -1,13 +1,14 @@
"""A radio component."""
from typing import Any, List, Set
from typing import Any, Dict, List
from pynecone import utils
from pynecone.components.component import Component
from pynecone.components.layout.foreach import Foreach
from pynecone.components.libs.chakra import ChakraComponent
from pynecone.components.typography.text import Text
from pynecone.event import EVENT_ARG
from pynecone.var import Var
@ -20,13 +21,15 @@ class RadioGroup(ChakraComponent):
value: Var[Any]
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Get the event triggers that pass the component's value to the handler.
Returns:
The controlled event triggers.
A dict mapping the event trigger to the var that is passed to the handler.
"""
return {"on_change"}
return {
"on_change": EVENT_ARG,
}
@classmethod
def create(cls, *children, **props) -> Component:

View File

@ -1,9 +1,10 @@
"""A range slider component."""
from typing import List, Set
from typing import Dict, List
from pynecone.components.component import Component
from pynecone.components.libs.chakra import ChakraComponent
from pynecone.event import EVENT_ARG
from pynecone.var import Var
@ -43,16 +44,16 @@ class RangeSlider(ChakraComponent):
min_steps_between_thumbs: Var[int]
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Get the event triggers that pass the component's value to the handler.
Returns:
The controlled event triggers.
A dict mapping the event trigger to the var that is passed to the handler.
"""
return {
"on_change",
"on_change_end",
"on_change_start",
"on_change": EVENT_ARG,
"on_change_end": EVENT_ARG,
"on_change_start": EVENT_ARG,
}
@classmethod

View File

@ -1,6 +1,6 @@
"""A select component."""
from typing import Any, List, Set
from typing import Any, Dict, List
from pynecone import utils
from pynecone.components.component import EVENT_ARG, Component
@ -46,22 +46,15 @@ class Select(ChakraComponent):
variant: Var[str]
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Get the event triggers that pass the component's value to the handler.
Returns:
The controlled event triggers.
A dict mapping the event trigger to the var that is passed to the handler.
"""
return {"on_change"}
@classmethod
def get_controlled_value(cls) -> Var:
"""Get the var that is passed to the event handler for controlled triggers.
Returns:
The controlled value.
"""
return EVENT_ARG.target.value
return {
"on_change": EVENT_ARG.target.value,
}
@classmethod
def create(cls, *children, **props) -> Component:

View File

@ -1,9 +1,10 @@
"""A slider component."""
from typing import Set
from typing import Dict
from pynecone.components.component import Component
from pynecone.components.libs.chakra import ChakraComponent
from pynecone.event import EVENT_ARG
from pynecone.var import Var
@ -43,16 +44,16 @@ class Slider(ChakraComponent):
min_steps_between_thumbs: Var[int]
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Get the event triggers that pass the component's value to the handler.
Returns:
The controlled event triggers.
A dict mapping the event trigger to the var that is passed to the handler.
"""
return {
"on_change",
"on_change_end",
"on_change_start",
"on_change": EVENT_ARG,
"on_change_end": EVENT_ARG,
"on_change_start": EVENT_ARG,
}
@classmethod

View File

@ -1,5 +1,5 @@
"""A switch component."""
from typing import Set
from typing import Dict
from pynecone.components.component import EVENT_ARG
from pynecone.components.libs.chakra import ChakraComponent
@ -39,19 +39,12 @@ class Switch(ChakraComponent):
placeholder: Var[str]
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Get the event triggers that pass the component's value to the handler.
Returns:
The controlled event triggers.
A dict mapping the event trigger to the var that is passed to the handler.
"""
return {"on_change"}
@classmethod
def get_controlled_value(cls) -> Var:
"""Get the var that is passed to the event handler for controlled triggers.
Returns:
The controlled value.
"""
return EVENT_ARG.target.checked
return {
"on_change": EVENT_ARG.target.checked,
}

View File

@ -1,6 +1,6 @@
"""A textarea component."""
from typing import Set
from typing import Dict
from pynecone.components.component import EVENT_ARG
from pynecone.components.libs.chakra import ChakraComponent
@ -43,19 +43,17 @@ class TextArea(ChakraComponent):
variant: Var[str]
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Get the event triggers that pass the component's value to the handler.
Returns:
The controlled event triggers.
A dict mapping the event trigger to the var that is passed to the handler.
"""
return {"on_change", "on_focus", "on_blur"}
@classmethod
def get_controlled_value(cls) -> Var:
"""Get the var that is passed to the event handler for controlled triggers.
Returns:
The controlled value.
"""
return EVENT_ARG.target.value
return {
"on_change": EVENT_ARG.target.value,
"on_focus": EVENT_ARG.target.value,
"on_blur": EVENT_ARG.target.value,
"on_key_down": EVENT_ARG.key,
"on_key_press": EVENT_ARG.key,
"on_key_up": EVENT_ARG.key,
}

View File

@ -115,6 +115,7 @@ class FrontendEvent(Base):
"""A Javascript event."""
target: Target = Target()
key: str = ""
# The default event argument.

View File

@ -1,10 +1,10 @@
from typing import List, Set, Type
from typing import Dict, List, Type
import pytest
from pynecone.components.component import Component, CustomComponent, ImportDict
from pynecone.components.layout.box import Box
from pynecone.event import EVENT_TRIGGERS, EventHandler
from pynecone.event import EVENT_ARG, EVENT_TRIGGERS, EventHandler
from pynecone.state import State
from pynecone.style import Style
from pynecone.var import Var
@ -61,13 +61,16 @@ def component2() -> Type[Component]:
arr: Var[List[str]]
@classmethod
def get_controlled_triggers(cls) -> Set[str]:
def get_controlled_triggers(cls) -> Dict[str, Var]:
"""Test controlled triggers.
Returns:
Test controlled triggers.
"""
return {"on_open", "on_close"}
return {
"on_open": EVENT_ARG,
"on_close": EVENT_ARG,
}
def _get_imports(self) -> ImportDict:
return {"react-redux": {"connect"}}
@ -269,8 +272,8 @@ def test_get_controlled_triggers(component1, component2):
component1: A test component.
component2: A test component.
"""
assert component1.get_controlled_triggers() == set()
assert component2.get_controlled_triggers() == {"on_open", "on_close"}
assert component1.get_controlled_triggers() == dict()
assert set(component2.get_controlled_triggers()) == {"on_open", "on_close"}
def test_get_triggers(component1, component2):