Update pc.form on_submit args (#1033)
This commit is contained in:
parent
98f1b30735
commit
e6a679d3a3
@ -94,6 +94,13 @@ class Component(Base, ABC):
|
|||||||
Raises:
|
Raises:
|
||||||
TypeError: If an invalid prop is passed.
|
TypeError: If an invalid prop is passed.
|
||||||
"""
|
"""
|
||||||
|
# Set the id and children initially.
|
||||||
|
initial_kwargs = {
|
||||||
|
"id": kwargs.get("id"),
|
||||||
|
"children": kwargs.get("children", []),
|
||||||
|
}
|
||||||
|
super().__init__(**initial_kwargs)
|
||||||
|
|
||||||
# Get the component fields, triggers, and props.
|
# Get the component fields, triggers, and props.
|
||||||
fields = self.get_fields()
|
fields = self.get_fields()
|
||||||
triggers = self.get_triggers()
|
triggers = self.get_triggers()
|
||||||
@ -264,17 +271,15 @@ class Component(Base, ABC):
|
|||||||
events=events, state_name=state_name, full_control=full_control
|
events=events, state_name=state_name, full_control=full_control
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
def get_triggers(self) -> Set[str]:
|
||||||
def get_triggers(cls) -> Set[str]:
|
|
||||||
"""Get the event triggers for the component.
|
"""Get the event triggers for the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The event triggers.
|
The event triggers.
|
||||||
"""
|
"""
|
||||||
return EVENT_TRIGGERS | set(cls.get_controlled_triggers())
|
return EVENT_TRIGGERS | set(self.get_controlled_triggers())
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
@ -488,7 +493,7 @@ class Component(Base, ABC):
|
|||||||
|
|
||||||
# Add the hook code for the children.
|
# Add the hook code for the children.
|
||||||
for child in self.children:
|
for child in self.children:
|
||||||
code.update(child.get_hooks())
|
code |= child.get_hooks()
|
||||||
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
@ -502,6 +507,20 @@ class Component(Base, ABC):
|
|||||||
return None
|
return None
|
||||||
return format.format_ref(self.id)
|
return format.format_ref(self.id)
|
||||||
|
|
||||||
|
def get_refs(self) -> Set[str]:
|
||||||
|
"""Get the refs for the children of the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The refs for the children.
|
||||||
|
"""
|
||||||
|
refs = set()
|
||||||
|
ref = self.get_ref()
|
||||||
|
if ref is not None:
|
||||||
|
refs.add(ref)
|
||||||
|
for child in self.children:
|
||||||
|
refs |= child.get_refs()
|
||||||
|
return refs
|
||||||
|
|
||||||
def get_custom_components(
|
def get_custom_components(
|
||||||
self, seen: Optional[Set[str]] = None
|
self, seen: Optional[Set[str]] = None
|
||||||
) -> Set[CustomComponent]:
|
) -> Set[CustomComponent]:
|
||||||
@ -565,7 +584,7 @@ class CustomComponent(Component):
|
|||||||
library = f"/{constants.COMPONENTS_PATH}"
|
library = f"/{constants.COMPONENTS_PATH}"
|
||||||
|
|
||||||
# The function that creates the component.
|
# The function that creates the component.
|
||||||
component_fn: Callable[..., Component]
|
component_fn: Callable[..., Component] = Component.create
|
||||||
|
|
||||||
# The props of the component.
|
# The props of the component.
|
||||||
props: Dict[str, Any] = {}
|
props: Dict[str, Any] = {}
|
||||||
|
@ -48,8 +48,7 @@ class Checkbox(ChakraComponent):
|
|||||||
# The spacing between the checkbox and its label text (0.5rem)
|
# The spacing between the checkbox and its label text (0.5rem)
|
||||||
spacing: Var[str]
|
spacing: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
|
@ -16,8 +16,7 @@ class CopyToClipboard(Component):
|
|||||||
# The text to copy when clicked.
|
# The text to copy when clicked.
|
||||||
text: Var[str]
|
text: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Set[str]:
|
||||||
def get_controlled_triggers(cls) -> Set[str]:
|
|
||||||
"""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:
|
||||||
|
@ -36,8 +36,7 @@ class Editable(ChakraComponent):
|
|||||||
# The initial value of the Editable in both edit and preview mode.
|
# The initial value of the Editable in both edit and preview mode.
|
||||||
default_value: Var[str]
|
default_value: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""Form components."""
|
"""Form components."""
|
||||||
|
|
||||||
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
|
||||||
@ -14,14 +14,19 @@ class Form(ChakraComponent):
|
|||||||
|
|
||||||
as_: Var[str] = "form" # type: ignore
|
as_: Var[str] = "form" # type: ignore
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Dict]:
|
||||||
def get_triggers(cls) -> Set[str]:
|
"""Get the event triggers that pass the component's value to the handler.
|
||||||
"""Get the event triggers for the component.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The event triggers.
|
A dict mapping the event trigger to the var that is passed to the handler.
|
||||||
"""
|
"""
|
||||||
return super().get_triggers() | {"on_submit"}
|
# Send all the input refs to the handler.
|
||||||
|
return {
|
||||||
|
"on_submit": {
|
||||||
|
ref[4:]: Var.create(f"{ref}.current.value", is_local=False)
|
||||||
|
for ref in self.get_refs()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class FormControl(ChakraComponent):
|
class FormControl(ChakraComponent):
|
||||||
@ -52,7 +57,7 @@ class FormControl(ChakraComponent):
|
|||||||
input=None,
|
input=None,
|
||||||
help_text=None,
|
help_text=None,
|
||||||
error_message=None,
|
error_message=None,
|
||||||
**props
|
**props,
|
||||||
) -> Component:
|
) -> Component:
|
||||||
"""Create a form control component.
|
"""Create a form control component.
|
||||||
|
|
||||||
|
@ -55,8 +55,7 @@ class Input(ChakraComponent):
|
|||||||
{"/utils/state": {ImportVar(tag="set_val")}},
|
{"/utils/state": {ImportVar(tag="set_val")}},
|
||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
|
@ -64,8 +64,7 @@ class NumberInput(ChakraComponent):
|
|||||||
# "outline" | "filled" | "flushed" | "unstyled"
|
# "outline" | "filled" | "flushed" | "unstyled"
|
||||||
variant: Var[str]
|
variant: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
|
@ -55,8 +55,7 @@ class PinInput(ChakraComponent):
|
|||||||
# "outline" | "flushed" | "filled" | "unstyled"
|
# "outline" | "flushed" | "filled" | "unstyled"
|
||||||
variant: Var[str]
|
variant: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
|
@ -23,8 +23,7 @@ class RadioGroup(ChakraComponent):
|
|||||||
# The default value.
|
# The default value.
|
||||||
default_value: Var[Any]
|
default_value: Var[Any]
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
|
@ -43,8 +43,7 @@ class RangeSlider(ChakraComponent):
|
|||||||
# The minimum distance between slider thumbs. Useful for preventing the thumbs from being too close together.
|
# The minimum distance between slider thumbs. Useful for preventing the thumbs from being too close together.
|
||||||
min_steps_between_thumbs: Var[int]
|
min_steps_between_thumbs: Var[int]
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
|
@ -48,8 +48,7 @@ class Select(ChakraComponent):
|
|||||||
# The size of the select.
|
# The size of the select.
|
||||||
size: Var[str]
|
size: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
|
@ -61,8 +61,7 @@ class Slider(ChakraComponent):
|
|||||||
# Maximum width of the slider.
|
# Maximum width of the slider.
|
||||||
max_w: Var[str]
|
max_w: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
|
@ -41,8 +41,7 @@ class Switch(ChakraComponent):
|
|||||||
# The color scheme of the switch (e.g. "blue", "green", "red", etc.)
|
# The color scheme of the switch (e.g. "blue", "green", "red", etc.)
|
||||||
color_scheme: Var[str]
|
color_scheme: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
|
@ -42,8 +42,7 @@ class TextArea(ChakraComponent):
|
|||||||
# "outline" | "filled" | "flushed" | "unstyled"
|
# "outline" | "filled" | "flushed" | "unstyled"
|
||||||
variant: Var[str]
|
variant: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
|
@ -80,8 +80,7 @@ class Upload(Component):
|
|||||||
# Create the component.
|
# Create the component.
|
||||||
return super().create(zone, on_drop=upload_file, **upload_props)
|
return super().create(zone, on_drop=upload_file, **upload_props)
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
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:
|
||||||
|
@ -17,10 +17,10 @@ class Cond(Component):
|
|||||||
cond: Var[Any]
|
cond: Var[Any]
|
||||||
|
|
||||||
# The component to render if the cond is true.
|
# The component to render if the cond is true.
|
||||||
comp1: Component
|
comp1: Component = Fragment.create()
|
||||||
|
|
||||||
# The component to render if the cond is false.
|
# The component to render if the cond is false.
|
||||||
comp2: Component
|
comp2: Component = Fragment.create()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(
|
def create(
|
||||||
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
from typing import Any, Callable, List
|
from typing import Any, Callable, List
|
||||||
|
|
||||||
from pynecone.components.component import Component
|
from pynecone.components.component import Component
|
||||||
|
from pynecone.components.layout.fragment import Fragment
|
||||||
from pynecone.components.tags import IterTag
|
from pynecone.components.tags import IterTag
|
||||||
from pynecone.vars import BaseVar, Var, get_unique_variable_name
|
from pynecone.vars import BaseVar, Var, get_unique_variable_name
|
||||||
|
|
||||||
@ -15,7 +16,7 @@ class Foreach(Component):
|
|||||||
iterable: Var[List]
|
iterable: Var[List]
|
||||||
|
|
||||||
# A function from the render args to the component.
|
# A function from the render args to the component.
|
||||||
render_fn: Callable
|
render_fn: Callable = Fragment.create
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, iterable: Var[List], render_fn: Callable, **props) -> Foreach:
|
def create(cls, iterable: Var[List], render_fn: Callable, **props) -> Foreach:
|
||||||
|
@ -35,8 +35,7 @@ class Avatar(ChakraComponent):
|
|||||||
# "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "full"
|
# "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "full"
|
||||||
size: Var[str]
|
size: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_triggers(self) -> Set[str]:
|
||||||
def get_triggers(cls) -> Set[str]:
|
|
||||||
"""Get the event triggers for the component.
|
"""Get the event triggers for the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -43,8 +43,7 @@ class Image(ChakraComponent):
|
|||||||
# The image srcset attribute.
|
# The image srcset attribute.
|
||||||
src_set: Var[str]
|
src_set: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_triggers(self) -> Set[str]:
|
||||||
def get_triggers(cls) -> Set[str]:
|
|
||||||
"""Get the event triggers for the component.
|
"""Get the event triggers for the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -52,8 +52,7 @@ class AlertDialog(ChakraComponent):
|
|||||||
# If true, the siblings of the modal will have `aria-hidden` set to true so that screen readers can only see the modal. This is commonly known as making the other elements **inert**
|
# If true, the siblings of the modal will have `aria-hidden` set to true so that screen readers can only see the modal. This is commonly known as making the other elements **inert**
|
||||||
use_inert: Var[bool]
|
use_inert: Var[bool]
|
||||||
|
|
||||||
@classmethod
|
def get_triggers(self) -> Set[str]:
|
||||||
def get_triggers(cls) -> Set[str]:
|
|
||||||
"""Get the event triggers for the component.
|
"""Get the event triggers for the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -58,8 +58,7 @@ class Drawer(ChakraComponent):
|
|||||||
# Variant of drawer
|
# Variant of drawer
|
||||||
variant: Var[str]
|
variant: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_triggers(self) -> Set[str]:
|
||||||
def get_triggers(cls) -> Set[str]:
|
|
||||||
"""Get the event triggers for the component.
|
"""Get the event triggers for the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -60,8 +60,7 @@ class Menu(ChakraComponent):
|
|||||||
# The CSS positioning strategy to use. ("fixed" | "absolute")
|
# The CSS positioning strategy to use. ("fixed" | "absolute")
|
||||||
strategy: Var[str]
|
strategy: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_triggers(self) -> Set[str]:
|
||||||
def get_triggers(cls) -> Set[str]:
|
|
||||||
"""Get the event triggers for the component.
|
"""Get the event triggers for the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -52,8 +52,7 @@ class Modal(ChakraComponent):
|
|||||||
# A11y: If true, the siblings of the modal will have `aria-hidden` set to true so that screen readers can only see the modal. This is commonly known as making the other elements **inert**
|
# A11y: If true, the siblings of the modal will have `aria-hidden` set to true so that screen readers can only see the modal. This is commonly known as making the other elements **inert**
|
||||||
use_inert: Var[bool]
|
use_inert: Var[bool]
|
||||||
|
|
||||||
@classmethod
|
def get_triggers(self) -> Set[str]:
|
||||||
def get_triggers(cls) -> Set[str]:
|
|
||||||
"""Get the event triggers for the component.
|
"""Get the event triggers for the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -75,8 +75,7 @@ class Popover(ChakraComponent):
|
|||||||
# The interaction that triggers the popover. hover - means the popover will open when you hover with mouse or focus with keyboard on the popover trigger click - means the popover will open on click or press Enter to Space on keyboard ("click" | "hover")
|
# The interaction that triggers the popover. hover - means the popover will open when you hover with mouse or focus with keyboard on the popover trigger click - means the popover will open on click or press Enter to Space on keyboard ("click" | "hover")
|
||||||
trigger: Var[str]
|
trigger: Var[str]
|
||||||
|
|
||||||
@classmethod
|
def get_triggers(self) -> Set[str]:
|
||||||
def get_triggers(cls) -> Set[str]:
|
|
||||||
"""Get the event triggers for the component.
|
"""Get the event triggers for the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -62,8 +62,7 @@ class Tooltip(ChakraComponent):
|
|||||||
# If true, the tooltip will wrap its children in a `<span/>` with `tabIndex=0`
|
# If true, the tooltip will wrap its children in a `<span/>` with `tabIndex=0`
|
||||||
should_wrap_children: Var[bool]
|
should_wrap_children: Var[bool]
|
||||||
|
|
||||||
@classmethod
|
def get_triggers(self) -> Set[str]:
|
||||||
def get_triggers(cls) -> Set[str]:
|
|
||||||
"""Get the event triggers for the component.
|
"""Get the event triggers for the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import re
|
|
||||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple, Union
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple, Union
|
||||||
|
|
||||||
from plotly.graph_objects import Figure
|
from plotly.graph_objects import Figure
|
||||||
@ -97,14 +96,10 @@ class Tag(Base):
|
|||||||
prop = json.loads(to_json(prop))["data"] # type: ignore
|
prop = json.loads(to_json(prop))["data"] # type: ignore
|
||||||
|
|
||||||
# For dictionaries, convert any properties to strings.
|
# For dictionaries, convert any properties to strings.
|
||||||
else:
|
elif isinstance(prop, dict):
|
||||||
if isinstance(prop, dict):
|
prop = format.format_dict(prop)
|
||||||
# Convert any var keys to strings.
|
|
||||||
prop = {
|
|
||||||
key: str(val) if isinstance(val, Var) else val
|
|
||||||
for key, val in prop.items()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
else:
|
||||||
# Dump the prop as JSON.
|
# Dump the prop as JSON.
|
||||||
try:
|
try:
|
||||||
prop = format.json_dumps(prop)
|
prop = format.json_dumps(prop)
|
||||||
@ -113,11 +108,6 @@ class Tag(Base):
|
|||||||
f"Could not format prop: {prop} of type {type(prop)}"
|
f"Could not format prop: {prop} of type {type(prop)}"
|
||||||
) from e
|
) from e
|
||||||
|
|
||||||
# This substitution is necessary to unwrap var values.
|
|
||||||
prop = re.sub('"{', "", prop)
|
|
||||||
prop = re.sub('}"', "", prop)
|
|
||||||
prop = re.sub('\\\\"', '"', prop)
|
|
||||||
|
|
||||||
# Wrap the variable in braces.
|
# Wrap the variable in braces.
|
||||||
assert isinstance(prop, str), "The prop must be a string."
|
assert isinstance(prop, str), "The prop must be a string."
|
||||||
return format.wrap(prop, "{", check_first=False)
|
return format.wrap(prop, "{", check_first=False)
|
||||||
|
@ -15,6 +15,7 @@ from pynecone import constants
|
|||||||
from pynecone.utils import types
|
from pynecone.utils import types
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from pynecone.components.component import ComponentStyle
|
||||||
from pynecone.event import EventChain, EventHandler, EventSpec
|
from pynecone.event import EventChain, EventHandler, EventSpec
|
||||||
|
|
||||||
WRAP_MAP = {
|
WRAP_MAP = {
|
||||||
@ -411,6 +412,33 @@ def format_ref(ref: str) -> str:
|
|||||||
return f"ref_{clean_ref}"
|
return f"ref_{clean_ref}"
|
||||||
|
|
||||||
|
|
||||||
|
def format_dict(prop: ComponentStyle) -> str:
|
||||||
|
"""Format a dict with vars potentially as values.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
prop: The dict to format.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The formatted dict.
|
||||||
|
"""
|
||||||
|
# Import here to avoid circular imports.
|
||||||
|
from pynecone.vars import Var
|
||||||
|
|
||||||
|
# Convert any var keys to strings.
|
||||||
|
prop = {key: str(val) if isinstance(val, Var) else val for key, val in prop.items()}
|
||||||
|
|
||||||
|
# Dump the dict to a string.
|
||||||
|
fprop = json_dumps(prop)
|
||||||
|
|
||||||
|
# This substitution is necessary to unwrap var values.
|
||||||
|
fprop = re.sub('"{', "", fprop)
|
||||||
|
fprop = re.sub('}"', "", fprop)
|
||||||
|
fprop = re.sub('\\\\"', '"', fprop)
|
||||||
|
|
||||||
|
# Return the formatted dict.
|
||||||
|
return fprop
|
||||||
|
|
||||||
|
|
||||||
def json_dumps(obj: Any) -> str:
|
def json_dumps(obj: Any) -> str:
|
||||||
"""Takes an object and returns a jsonified string.
|
"""Takes an object and returns a jsonified string.
|
||||||
|
|
||||||
|
@ -101,6 +101,9 @@ class Var(ABC):
|
|||||||
value = json.loads(to_json(value))["data"] # type: ignore
|
value = json.loads(to_json(value))["data"] # type: ignore
|
||||||
type_ = Figure
|
type_ = Figure
|
||||||
|
|
||||||
|
if isinstance(value, dict):
|
||||||
|
value = format.format_dict(value)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
name = value if isinstance(value, str) else json.dumps(value)
|
name = value if isinstance(value, str) else json.dumps(value)
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
|
@ -62,8 +62,7 @@ def component2() -> Type[Component]:
|
|||||||
# A test list prop.
|
# A test list prop.
|
||||||
arr: Var[List[str]]
|
arr: Var[List[str]]
|
||||||
|
|
||||||
@classmethod
|
def get_controlled_triggers(self) -> Dict[str, Var]:
|
||||||
def get_controlled_triggers(cls) -> Dict[str, Var]:
|
|
||||||
"""Test controlled triggers.
|
"""Test controlled triggers.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -307,8 +306,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() == dict()
|
assert component1().get_controlled_triggers() == dict()
|
||||||
assert set(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):
|
||||||
@ -318,8 +317,8 @@ def test_get_triggers(component1, component2):
|
|||||||
component1: A test component.
|
component1: A test component.
|
||||||
component2: A test component.
|
component2: A test component.
|
||||||
"""
|
"""
|
||||||
assert component1.get_triggers() == EVENT_TRIGGERS
|
assert component1().get_triggers() == EVENT_TRIGGERS
|
||||||
assert component2.get_triggers() == {"on_open", "on_close"} | EVENT_TRIGGERS
|
assert component2().get_triggers() == {"on_open", "on_close"} | EVENT_TRIGGERS
|
||||||
|
|
||||||
|
|
||||||
def test_create_custom_component(my_component):
|
def test_create_custom_component(my_component):
|
||||||
|
Loading…
Reference in New Issue
Block a user