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

View File

@ -1,6 +1,6 @@
"""A checkbox component.""" """A checkbox component."""
from typing import Set from typing import Dict
from pynecone.components.component import EVENT_ARG from pynecone.components.component import EVENT_ARG
from pynecone.components.libs.chakra import ChakraComponent from pynecone.components.libs.chakra import ChakraComponent
@ -46,22 +46,15 @@ class Checkbox(ChakraComponent):
spacing: Var[str] spacing: Var[str]
@classmethod @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. """Get the event triggers that pass the component's value to the handler.
Returns: 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.target.checked,
@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
class CheckboxGroup(ChakraComponent): class CheckboxGroup(ChakraComponent):

View File

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

View File

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

View File

@ -1,9 +1,10 @@
"""A number input component.""" """A number input component."""
from typing import Set from typing import Dict
from pynecone.components.component import Component from pynecone.components.component import Component
from pynecone.components.libs.chakra import ChakraComponent from pynecone.components.libs.chakra import ChakraComponent
from pynecone.event import EVENT_ARG
from pynecone.var import Var from pynecone.var import Var
@ -64,13 +65,15 @@ class NumberInput(ChakraComponent):
variant: Var[str] variant: Var[str]
@classmethod @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. """Get the event triggers that pass the component's value to the handler.
Returns: 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 @classmethod
def create(cls, *children, **props) -> Component: def create(cls, *children, **props) -> Component:

View File

@ -1,9 +1,10 @@
"""A pin input component.""" """A pin input component."""
from typing import Set from typing import Dict
from pynecone.components.component import Component from pynecone.components.component import Component
from pynecone.components.libs.chakra import ChakraComponent from pynecone.components.libs.chakra import ChakraComponent
from pynecone.event import EVENT_ARG
from pynecone.var import Var from pynecone.var import Var
@ -55,13 +56,16 @@ class PinInput(ChakraComponent):
variant: Var[str] variant: Var[str]
@classmethod @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. """Get the event triggers that pass the component's value to the handler.
Returns: 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 @classmethod
def create(cls, *children, **props) -> Component: def create(cls, *children, **props) -> Component:

View File

@ -1,13 +1,14 @@
"""A radio component.""" """A radio component."""
from typing import Any, List, Set from typing import Any, Dict, List
from pynecone import utils from pynecone import utils
from pynecone.components.component import Component from pynecone.components.component import Component
from pynecone.components.layout.foreach import Foreach from pynecone.components.layout.foreach import Foreach
from pynecone.components.libs.chakra import ChakraComponent from pynecone.components.libs.chakra import ChakraComponent
from pynecone.components.typography.text import Text from pynecone.components.typography.text import Text
from pynecone.event import EVENT_ARG
from pynecone.var import Var from pynecone.var import Var
@ -20,13 +21,15 @@ class RadioGroup(ChakraComponent):
value: Var[Any] value: Var[Any]
@classmethod @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. """Get the event triggers that pass the component's value to the handler.
Returns: 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 @classmethod
def create(cls, *children, **props) -> Component: def create(cls, *children, **props) -> Component:

View File

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

View File

@ -1,6 +1,6 @@
"""A select component.""" """A select component."""
from typing import Any, List, Set from typing import Any, Dict, List
from pynecone import utils from pynecone import utils
from pynecone.components.component import EVENT_ARG, Component from pynecone.components.component import EVENT_ARG, Component
@ -46,22 +46,15 @@ class Select(ChakraComponent):
variant: Var[str] variant: Var[str]
@classmethod @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. """Get the event triggers that pass the component's value to the handler.
Returns: 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.target.value,
@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
@classmethod @classmethod
def create(cls, *children, **props) -> Component: def create(cls, *children, **props) -> Component:

View File

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

View File

@ -1,5 +1,5 @@
"""A switch component.""" """A switch component."""
from typing import Set from typing import Dict
from pynecone.components.component import EVENT_ARG from pynecone.components.component import EVENT_ARG
from pynecone.components.libs.chakra import ChakraComponent from pynecone.components.libs.chakra import ChakraComponent
@ -39,19 +39,12 @@ class Switch(ChakraComponent):
placeholder: Var[str] placeholder: Var[str]
@classmethod @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. """Get the event triggers that pass the component's value to the handler.
Returns: 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.target.checked,
@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

View File

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

View File

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

View File

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