Radix callout high level api (#2409)
This commit is contained in:
parent
c8693851fe
commit
a92abbb0ce
@ -1 +1,3 @@
|
|||||||
"""Namespace for components provided by @radix-ui packages."""
|
"""Namespace for components provided by @radix-ui packages."""
|
||||||
|
|
||||||
|
from . import primitives, themes
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
"""Radix accordion components."""
|
"""Radix accordion components."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Any, Dict, Literal
|
from typing import Any, Dict, Literal
|
||||||
|
|
||||||
from reflex.components.base.fragment import Fragment
|
from reflex.components.base.fragment import Fragment
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
"""Radix form component."""
|
"""Radix form component."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from typing import Any, Dict, Iterator, Literal
|
from typing import Any, Dict, Iterator, Literal
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
"""Progress."""
|
"""Progress."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
"""Radix slider components."""
|
"""Radix slider components."""
|
||||||
|
|
||||||
from typing import Any, Dict, Literal
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any, Dict, List, Literal
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
|
from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
|
||||||
@ -23,9 +25,9 @@ class SliderRoot(SliderComponent):
|
|||||||
tag = "Root"
|
tag = "Root"
|
||||||
alias = "RadixSliderRoot"
|
alias = "RadixSliderRoot"
|
||||||
|
|
||||||
default_value: Var[list[int]]
|
default_value: Var[List[int]]
|
||||||
|
|
||||||
value: Var[list[int]]
|
value: Var[List[int]]
|
||||||
|
|
||||||
name: Var[str]
|
name: Var[str]
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ from typing import Any, Dict, Literal, Optional, Union, overload
|
|||||||
from reflex.vars import Var, BaseVar, ComputedVar
|
from reflex.vars import Var, BaseVar, ComputedVar
|
||||||
from reflex.event import EventChain, EventHandler, EventSpec
|
from reflex.event import EventChain, EventHandler, EventSpec
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from typing import Any, Dict, Literal
|
from typing import Any, Dict, List, Literal
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
|
from reflex.components.radix.primitives.base import RadixPrimitiveComponentWithClassName
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
@ -104,8 +104,8 @@ class SliderRoot(SliderComponent):
|
|||||||
def create( # type: ignore
|
def create( # type: ignore
|
||||||
cls,
|
cls,
|
||||||
*children,
|
*children,
|
||||||
default_value: Optional[Union[Var[list[int]], list[int]]] = None,
|
default_value: Optional[Union[Var[List[int]], List[int]]] = None,
|
||||||
value: Optional[Union[Var[list[int]], list[int]]] = None,
|
value: Optional[Union[Var[List[int]], List[int]]] = None,
|
||||||
name: Optional[Union[Var[str], str]] = None,
|
name: Optional[Union[Var[str], str]] = None,
|
||||||
disabled: Optional[Union[Var[bool], bool]] = None,
|
disabled: Optional[Union[Var[bool], bool]] = None,
|
||||||
orientation: Optional[
|
orientation: Optional[
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
"""Interactive components provided by @radix-ui/themes."""
|
"""Interactive components provided by @radix-ui/themes."""
|
||||||
from typing import Literal
|
from typing import Literal, Union
|
||||||
|
|
||||||
|
import reflex as rx
|
||||||
from reflex import el
|
from reflex import el
|
||||||
|
from reflex.components.component import Component
|
||||||
|
from reflex.components.radix.themes.components.icons import Icon
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
|
|
||||||
from ..base import (
|
from ..base import (
|
||||||
CommonMarginProps,
|
CommonMarginProps,
|
||||||
LiteralAccentColor,
|
LiteralAccentColor,
|
||||||
LiteralRadius,
|
|
||||||
LiteralVariant,
|
LiteralVariant,
|
||||||
RadixThemesComponent,
|
RadixThemesComponent,
|
||||||
)
|
)
|
||||||
@ -33,9 +35,6 @@ class CalloutRoot(el.Div, CommonMarginProps, RadixThemesComponent):
|
|||||||
# Whether to render the button with higher contrast color against background
|
# Whether to render the button with higher contrast color against background
|
||||||
high_contrast: Var[bool]
|
high_contrast: Var[bool]
|
||||||
|
|
||||||
# Override theme radius for button: "none" | "small" | "medium" | "large" | "full"
|
|
||||||
radius: Var[LiteralRadius]
|
|
||||||
|
|
||||||
|
|
||||||
class CalloutIcon(el.Div, CommonMarginProps, RadixThemesComponent):
|
class CalloutIcon(el.Div, CommonMarginProps, RadixThemesComponent):
|
||||||
"""Trigger an action or event, such as submitting a form or displaying a dialog."""
|
"""Trigger an action or event, such as submitting a form or displaying a dialog."""
|
||||||
@ -47,3 +46,35 @@ class CalloutText(el.P, CommonMarginProps, RadixThemesComponent):
|
|||||||
"""Trigger an action or event, such as submitting a form or displaying a dialog."""
|
"""Trigger an action or event, such as submitting a form or displaying a dialog."""
|
||||||
|
|
||||||
tag = "Callout.Text"
|
tag = "Callout.Text"
|
||||||
|
|
||||||
|
|
||||||
|
class Callout(CalloutRoot):
|
||||||
|
"""High level wrapper for the Callout component."""
|
||||||
|
|
||||||
|
# The text of the callout.
|
||||||
|
text: Var[str]
|
||||||
|
|
||||||
|
# The icon of the callout.
|
||||||
|
icon: Var[str]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(cls, text: Union[str, Var[str]], **props) -> Component:
|
||||||
|
"""Create a callout component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
text: The text of the callout.
|
||||||
|
**props: The properties of the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The callout component.
|
||||||
|
"""
|
||||||
|
return CalloutRoot.create(
|
||||||
|
CalloutIcon.create(Icon.create(tag=props["icon"]))
|
||||||
|
if "icon" in props
|
||||||
|
else rx.fragment(),
|
||||||
|
CalloutText.create(text),
|
||||||
|
**props,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
callout = Callout.create
|
||||||
|
@ -7,13 +7,15 @@ from typing import Any, Dict, Literal, Optional, Union, overload
|
|||||||
from reflex.vars import Var, BaseVar, ComputedVar
|
from reflex.vars import Var, BaseVar, ComputedVar
|
||||||
from reflex.event import EventChain, EventHandler, EventSpec
|
from reflex.event import EventChain, EventHandler, EventSpec
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from typing import Literal
|
from typing import Literal, Union
|
||||||
|
import reflex as rx
|
||||||
from reflex import el
|
from reflex import el
|
||||||
|
from reflex.components.component import Component
|
||||||
|
from reflex.components.radix.themes.components.icons import Icon
|
||||||
from reflex.vars import Var
|
from reflex.vars import Var
|
||||||
from ..base import (
|
from ..base import (
|
||||||
CommonMarginProps,
|
CommonMarginProps,
|
||||||
LiteralAccentColor,
|
LiteralAccentColor,
|
||||||
LiteralRadius,
|
|
||||||
LiteralVariant,
|
LiteralVariant,
|
||||||
RadixThemesComponent,
|
RadixThemesComponent,
|
||||||
)
|
)
|
||||||
@ -98,12 +100,6 @@ class CalloutRoot(el.Div, CommonMarginProps, RadixThemesComponent):
|
|||||||
]
|
]
|
||||||
] = None,
|
] = None,
|
||||||
high_contrast: Optional[Union[Var[bool], bool]] = None,
|
high_contrast: Optional[Union[Var[bool], bool]] = None,
|
||||||
radius: Optional[
|
|
||||||
Union[
|
|
||||||
Var[Literal["none", "small", "medium", "large", "full"]],
|
|
||||||
Literal["none", "small", "medium", "large", "full"],
|
|
||||||
]
|
|
||||||
] = None,
|
|
||||||
access_key: Optional[
|
access_key: Optional[
|
||||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
] = None,
|
] = None,
|
||||||
@ -255,7 +251,6 @@ class CalloutRoot(el.Div, CommonMarginProps, RadixThemesComponent):
|
|||||||
size: Button size "1" - "4"
|
size: Button size "1" - "4"
|
||||||
variant: Variant of button: "solid" | "soft" | "outline" | "ghost"
|
variant: Variant of button: "solid" | "soft" | "outline" | "ghost"
|
||||||
high_contrast: Whether to render the button with higher contrast color against background
|
high_contrast: Whether to render the button with higher contrast color against background
|
||||||
radius: Override theme radius for button: "none" | "small" | "medium" | "large" | "full"
|
|
||||||
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||||
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||||
content_editable: Indicates whether the element's content is editable.
|
content_editable: Indicates whether the element's content is editable.
|
||||||
@ -798,3 +793,272 @@ class CalloutText(el.P, CommonMarginProps, RadixThemesComponent):
|
|||||||
A new component instance.
|
A new component instance.
|
||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
|
class Callout(CalloutRoot):
|
||||||
|
@overload
|
||||||
|
@classmethod
|
||||||
|
def create( # type: ignore
|
||||||
|
cls,
|
||||||
|
*children,
|
||||||
|
text: Optional[Union[Var[str], str]] = None,
|
||||||
|
icon: Optional[Union[Var[str], str]] = None,
|
||||||
|
as_child: Optional[Union[Var[bool], bool]] = None,
|
||||||
|
size: Optional[
|
||||||
|
Union[Var[Literal["1", "2", "3"]], Literal["1", "2", "3"]]
|
||||||
|
] = None,
|
||||||
|
variant: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["classic", "solid", "soft", "surface", "outline", "ghost"]],
|
||||||
|
Literal["classic", "solid", "soft", "surface", "outline", "ghost"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
color: Optional[
|
||||||
|
Union[
|
||||||
|
Var[
|
||||||
|
Literal[
|
||||||
|
"tomato",
|
||||||
|
"red",
|
||||||
|
"ruby",
|
||||||
|
"crimson",
|
||||||
|
"pink",
|
||||||
|
"plum",
|
||||||
|
"purple",
|
||||||
|
"violet",
|
||||||
|
"iris",
|
||||||
|
"indigo",
|
||||||
|
"blue",
|
||||||
|
"cyan",
|
||||||
|
"teal",
|
||||||
|
"jade",
|
||||||
|
"green",
|
||||||
|
"grass",
|
||||||
|
"brown",
|
||||||
|
"orange",
|
||||||
|
"sky",
|
||||||
|
"mint",
|
||||||
|
"lime",
|
||||||
|
"yellow",
|
||||||
|
"amber",
|
||||||
|
"gold",
|
||||||
|
"bronze",
|
||||||
|
"gray",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
Literal[
|
||||||
|
"tomato",
|
||||||
|
"red",
|
||||||
|
"ruby",
|
||||||
|
"crimson",
|
||||||
|
"pink",
|
||||||
|
"plum",
|
||||||
|
"purple",
|
||||||
|
"violet",
|
||||||
|
"iris",
|
||||||
|
"indigo",
|
||||||
|
"blue",
|
||||||
|
"cyan",
|
||||||
|
"teal",
|
||||||
|
"jade",
|
||||||
|
"green",
|
||||||
|
"grass",
|
||||||
|
"brown",
|
||||||
|
"orange",
|
||||||
|
"sky",
|
||||||
|
"mint",
|
||||||
|
"lime",
|
||||||
|
"yellow",
|
||||||
|
"amber",
|
||||||
|
"gold",
|
||||||
|
"bronze",
|
||||||
|
"gray",
|
||||||
|
],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
high_contrast: Optional[Union[Var[bool], bool]] = None,
|
||||||
|
access_key: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
auto_capitalize: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
content_editable: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
context_menu: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
dir: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||||
|
draggable: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
enter_key_hint: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
hidden: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
input_mode: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
item_prop: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
lang: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||||
|
role: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||||
|
slot: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||||
|
spell_check: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
tab_index: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
title: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
translate: Optional[
|
||||||
|
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||||
|
] = None,
|
||||||
|
m: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]],
|
||||||
|
Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
mx: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]],
|
||||||
|
Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
my: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]],
|
||||||
|
Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
mt: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]],
|
||||||
|
Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
mr: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]],
|
||||||
|
Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
mb: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]],
|
||||||
|
Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
ml: Optional[
|
||||||
|
Union[
|
||||||
|
Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]],
|
||||||
|
Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"],
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
style: Optional[Style] = None,
|
||||||
|
key: Optional[Any] = None,
|
||||||
|
id: Optional[Any] = None,
|
||||||
|
class_name: Optional[Any] = None,
|
||||||
|
autofocus: Optional[bool] = None,
|
||||||
|
custom_attrs: Optional[Dict[str, Union[Var, str]]] = None,
|
||||||
|
on_blur: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_click: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_context_menu: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_double_click: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_focus: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_mount: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_mouse_down: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_mouse_enter: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_mouse_leave: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_mouse_move: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_mouse_out: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_mouse_over: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_mouse_up: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_scroll: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
on_unmount: Optional[
|
||||||
|
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||||
|
] = None,
|
||||||
|
**props
|
||||||
|
) -> "Callout":
|
||||||
|
"""Create a callout component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
text: The text of the callout.
|
||||||
|
text: The text of the callout.
|
||||||
|
icon: The icon of the callout.
|
||||||
|
as_child: Change the default rendered element for the one passed as a child, merging their props and behavior.
|
||||||
|
size: Button size "1" - "4"
|
||||||
|
variant: Variant of button: "solid" | "soft" | "outline" | "ghost"
|
||||||
|
color: Override theme color for button
|
||||||
|
high_contrast: Whether to render the button with higher contrast color against background
|
||||||
|
access_key: Provides a hint for generating a keyboard shortcut for the current element.
|
||||||
|
auto_capitalize: Controls whether and how text input is automatically capitalized as it is entered/edited by the user.
|
||||||
|
content_editable: Indicates whether the element's content is editable.
|
||||||
|
context_menu: Defines the ID of a <menu> element which will serve as the element's context menu.
|
||||||
|
dir: Defines the text direction. Allowed values are ltr (Left-To-Right) or rtl (Right-To-Left)
|
||||||
|
draggable: Defines whether the element can be dragged.
|
||||||
|
enter_key_hint: Hints what media types the media element is able to play.
|
||||||
|
hidden: Defines whether the element is hidden.
|
||||||
|
input_mode: Defines the type of the element.
|
||||||
|
item_prop: Defines the name of the element for metadata purposes.
|
||||||
|
lang: Defines the language used in the element.
|
||||||
|
role: Defines the role of the element.
|
||||||
|
slot: Assigns a slot in a shadow DOM shadow tree to an element.
|
||||||
|
spell_check: Defines whether the element may be checked for spelling errors.
|
||||||
|
tab_index: Defines the position of the current element in the tabbing order.
|
||||||
|
title: Defines a tooltip for the element.
|
||||||
|
translate: Specifies whether the content of an element should be translated or not.
|
||||||
|
m: Margin: "0" - "9"
|
||||||
|
mx: Margin horizontal: "0" - "9"
|
||||||
|
my: Margin vertical: "0" - "9"
|
||||||
|
mt: Margin top: "0" - "9"
|
||||||
|
mr: Margin right: "0" - "9"
|
||||||
|
mb: Margin bottom: "0" - "9"
|
||||||
|
ml: Margin left: "0" - "9"
|
||||||
|
style: The style of the component.
|
||||||
|
key: A unique key for the component.
|
||||||
|
id: The id for the component.
|
||||||
|
class_name: The class name for the component.
|
||||||
|
autofocus: Whether the component should take the focus once the page is loaded
|
||||||
|
custom_attrs: custom attribute
|
||||||
|
**props: The properties of the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The callout component.
|
||||||
|
"""
|
||||||
|
...
|
||||||
|
|
||||||
|
callout = Callout.create
|
||||||
|
Loading…
Reference in New Issue
Block a user