Merge remote-tracking branch 'origin/main' into reflex-0.4.0
This commit is contained in:
commit
ae20644a82
@ -1,5 +1,6 @@
|
||||
"""Test state inheritance."""
|
||||
|
||||
import time
|
||||
from typing import Generator
|
||||
|
||||
import pytest
|
||||
@ -8,30 +9,57 @@ from selenium.webdriver.common.by import By
|
||||
from reflex.testing import DEFAULT_TIMEOUT, AppHarness, WebDriver
|
||||
|
||||
|
||||
def raises_alert(driver: WebDriver, element: str) -> None:
|
||||
"""Click an element and check that an alert is raised.
|
||||
|
||||
Args:
|
||||
driver: WebDriver instance.
|
||||
element: The element to click.
|
||||
"""
|
||||
btn = driver.find_element(By.ID, element)
|
||||
btn.click()
|
||||
time.sleep(0.2) # wait for the alert to appear
|
||||
alert = driver.switch_to.alert
|
||||
assert alert.text == "clicked"
|
||||
alert.accept()
|
||||
|
||||
|
||||
def StateInheritance():
|
||||
"""Test that state inheritance works as expected."""
|
||||
import reflex as rx
|
||||
|
||||
class ChildMixin:
|
||||
child_mixin: str = "child_mixin"
|
||||
# mixin basevars only work with pydantic/rx.Base models
|
||||
# child_mixin: str = "child_mixin"
|
||||
|
||||
@rx.var
|
||||
def computed_child_mixin(self) -> str:
|
||||
return "computed_child_mixin"
|
||||
|
||||
class Mixin(ChildMixin):
|
||||
mixin: str = "mixin"
|
||||
# mixin basevars only work with pydantic/rx.Base models
|
||||
# mixin: str = "mixin"
|
||||
|
||||
@rx.var
|
||||
def computed_mixin(self) -> str:
|
||||
return "computed_mixin"
|
||||
|
||||
def on_click_mixin(self):
|
||||
return rx.call_script("alert('clicked')")
|
||||
|
||||
class OtherMixin(rx.Base):
|
||||
other_mixin: str = "other_mixin"
|
||||
other_mixin_clicks: int = 0
|
||||
|
||||
@rx.var
|
||||
def computed_other_mixin(self) -> str:
|
||||
return "computed_other_mixin"
|
||||
return self.other_mixin
|
||||
|
||||
def on_click_other_mixin(self):
|
||||
self.other_mixin_clicks += 1
|
||||
self.other_mixin = (
|
||||
f"{self.__class__.__name__}.clicked.{self.other_mixin_clicks}"
|
||||
)
|
||||
|
||||
class Base1(rx.State, Mixin):
|
||||
base1: str = "base1"
|
||||
@ -65,30 +93,49 @@ def StateInheritance():
|
||||
rx.chakra.input(
|
||||
id="token", value=Base1.router.session.client_token, is_read_only=True
|
||||
),
|
||||
# Base 1
|
||||
rx.heading(Base1.computed_mixin, id="base1-computed_mixin"),
|
||||
rx.heading(Base1.computed_basevar, id="base1-computed_basevar"),
|
||||
rx.heading(Base1.computed_child_mixin, id="base1-child-mixin"),
|
||||
rx.heading(Base1.base1, id="base1-base1"),
|
||||
rx.heading(Base1.mixin, id="base1-mixin"),
|
||||
rx.heading(Base1.child_mixin, id="base1-child_mixin"),
|
||||
rx.button(
|
||||
"Base1.on_click_mixin",
|
||||
on_click=Base1.on_click_mixin, # type: ignore
|
||||
id="base1-mixin-btn",
|
||||
),
|
||||
# Base 2
|
||||
rx.heading(Base2.computed_basevar, id="base2-computed_basevar"),
|
||||
rx.heading(Base2.base2, id="base2-base2"),
|
||||
# Child 1
|
||||
rx.heading(Child1.computed_basevar, id="child1-computed_basevar"),
|
||||
rx.heading(Child1.computed_mixin, id="child1-computed_mixin"),
|
||||
rx.heading(Child1.computed_other_mixin, id="child1-other-mixin"),
|
||||
rx.heading(Child1.computed_child_mixin, id="child1-child-mixin"),
|
||||
rx.heading(Child1.base1, id="child1-base1"),
|
||||
rx.heading(Child1.mixin, id="child1-mixin"),
|
||||
rx.heading(Child1.other_mixin, id="child1-other_mixin"),
|
||||
rx.heading(Child1.child_mixin, id="child1-child_mixin"),
|
||||
rx.button(
|
||||
"Child1.on_click_other_mixin",
|
||||
on_click=Child1.on_click_other_mixin, # type: ignore
|
||||
id="child1-other-mixin-btn",
|
||||
),
|
||||
# Child 2
|
||||
rx.heading(Child2.computed_basevar, id="child2-computed_basevar"),
|
||||
rx.heading(Child2.computed_mixin, id="child2-computed_mixin"),
|
||||
rx.heading(Child2.computed_other_mixin, id="child2-other-mixin"),
|
||||
rx.heading(Child2.computed_child_mixin, id="child2-child-mixin"),
|
||||
rx.heading(Child2.base2, id="child2-base2"),
|
||||
rx.heading(Child2.mixin, id="child2-mixin"),
|
||||
rx.heading(Child2.other_mixin, id="child2-other_mixin"),
|
||||
rx.heading(Child2.child_mixin, id="child2-child_mixin"),
|
||||
rx.button(
|
||||
"Child2.on_click_mixin",
|
||||
on_click=Child2.on_click_mixin, # type: ignore
|
||||
id="child2-mixin-btn",
|
||||
),
|
||||
rx.button(
|
||||
"Child2.on_click_other_mixin",
|
||||
on_click=Child2.on_click_other_mixin, # type: ignore
|
||||
id="child2-other-mixin-btn",
|
||||
),
|
||||
# Child 3
|
||||
rx.heading(Child3.computed_basevar, id="child3-computed_basevar"),
|
||||
rx.heading(Child3.computed_mixin, id="child3-computed_mixin"),
|
||||
rx.heading(Child3.computed_other_mixin, id="child3-other-mixin"),
|
||||
@ -96,9 +143,17 @@ def StateInheritance():
|
||||
rx.heading(Child3.computed_child_mixin, id="child3-child-mixin"),
|
||||
rx.heading(Child3.child3, id="child3-child3"),
|
||||
rx.heading(Child3.base2, id="child3-base2"),
|
||||
rx.heading(Child3.mixin, id="child3-mixin"),
|
||||
rx.heading(Child3.other_mixin, id="child3-other_mixin"),
|
||||
rx.heading(Child3.child_mixin, id="child3-child_mixin"),
|
||||
rx.button(
|
||||
"Child3.on_click_mixin",
|
||||
on_click=Child3.on_click_mixin, # type: ignore
|
||||
id="child3-mixin-btn",
|
||||
),
|
||||
rx.button(
|
||||
"Child3.on_click_other_mixin",
|
||||
on_click=Child3.on_click_other_mixin, # type: ignore
|
||||
id="child3-other-mixin-btn",
|
||||
),
|
||||
)
|
||||
|
||||
app = rx.App()
|
||||
@ -178,6 +233,8 @@ def test_state_inheritance(
|
||||
"""
|
||||
assert state_inheritance.app_instance is not None
|
||||
|
||||
# Initial State values Test
|
||||
# Base 1
|
||||
base1_mixin = driver.find_element(By.ID, "base1-computed_mixin")
|
||||
assert base1_mixin.text == "computed_mixin"
|
||||
|
||||
@ -190,18 +247,14 @@ def test_state_inheritance(
|
||||
base1_base1 = driver.find_element(By.ID, "base1-base1")
|
||||
assert base1_base1.text == "base1"
|
||||
|
||||
base1_mixin = driver.find_element(By.ID, "base1-mixin")
|
||||
assert base1_mixin.text == "mixin"
|
||||
|
||||
base1_child_mixin = driver.find_element(By.ID, "base1-child_mixin")
|
||||
assert base1_child_mixin.text == "child_mixin"
|
||||
|
||||
# Base 2
|
||||
base2_computed_basevar = driver.find_element(By.ID, "base2-computed_basevar")
|
||||
assert base2_computed_basevar.text == "computed_basevar2"
|
||||
|
||||
base2_base2 = driver.find_element(By.ID, "base2-base2")
|
||||
assert base2_base2.text == "base2"
|
||||
|
||||
# Child 1
|
||||
child1_computed_basevar = driver.find_element(By.ID, "child1-computed_basevar")
|
||||
assert child1_computed_basevar.text == "computed_basevar1"
|
||||
|
||||
@ -209,7 +262,7 @@ def test_state_inheritance(
|
||||
assert child1_mixin.text == "computed_mixin"
|
||||
|
||||
child1_computed_other_mixin = driver.find_element(By.ID, "child1-other-mixin")
|
||||
assert child1_computed_other_mixin.text == "computed_other_mixin"
|
||||
assert child1_computed_other_mixin.text == "other_mixin"
|
||||
|
||||
child1_computed_child_mixin = driver.find_element(By.ID, "child1-child-mixin")
|
||||
assert child1_computed_child_mixin.text == "computed_child_mixin"
|
||||
@ -217,15 +270,10 @@ def test_state_inheritance(
|
||||
child1_base1 = driver.find_element(By.ID, "child1-base1")
|
||||
assert child1_base1.text == "base1"
|
||||
|
||||
child1_mixin = driver.find_element(By.ID, "child1-mixin")
|
||||
assert child1_mixin.text == "mixin"
|
||||
|
||||
child1_other_mixin = driver.find_element(By.ID, "child1-other_mixin")
|
||||
assert child1_other_mixin.text == "other_mixin"
|
||||
|
||||
child1_child_mixin = driver.find_element(By.ID, "child1-child_mixin")
|
||||
assert child1_child_mixin.text == "child_mixin"
|
||||
|
||||
# Child 2
|
||||
child2_computed_basevar = driver.find_element(By.ID, "child2-computed_basevar")
|
||||
assert child2_computed_basevar.text == "computed_basevar2"
|
||||
|
||||
@ -233,7 +281,7 @@ def test_state_inheritance(
|
||||
assert child2_mixin.text == "computed_mixin"
|
||||
|
||||
child2_computed_other_mixin = driver.find_element(By.ID, "child2-other-mixin")
|
||||
assert child2_computed_other_mixin.text == "computed_other_mixin"
|
||||
assert child2_computed_other_mixin.text == "other_mixin"
|
||||
|
||||
child2_computed_child_mixin = driver.find_element(By.ID, "child2-child-mixin")
|
||||
assert child2_computed_child_mixin.text == "computed_child_mixin"
|
||||
@ -241,15 +289,10 @@ def test_state_inheritance(
|
||||
child2_base2 = driver.find_element(By.ID, "child2-base2")
|
||||
assert child2_base2.text == "base2"
|
||||
|
||||
child2_mixin = driver.find_element(By.ID, "child2-mixin")
|
||||
assert child2_mixin.text == "mixin"
|
||||
|
||||
child2_other_mixin = driver.find_element(By.ID, "child2-other_mixin")
|
||||
assert child2_other_mixin.text == "other_mixin"
|
||||
|
||||
child2_child_mixin = driver.find_element(By.ID, "child2-child_mixin")
|
||||
assert child2_child_mixin.text == "child_mixin"
|
||||
|
||||
# Child 3
|
||||
child3_computed_basevar = driver.find_element(By.ID, "child3-computed_basevar")
|
||||
assert child3_computed_basevar.text == "computed_basevar2"
|
||||
|
||||
@ -257,7 +300,7 @@ def test_state_inheritance(
|
||||
assert child3_mixin.text == "computed_mixin"
|
||||
|
||||
child3_computed_other_mixin = driver.find_element(By.ID, "child3-other-mixin")
|
||||
assert child3_computed_other_mixin.text == "computed_other_mixin"
|
||||
assert child3_computed_other_mixin.text == "other_mixin"
|
||||
|
||||
child3_computed_childvar = driver.find_element(By.ID, "child3-computed_childvar")
|
||||
assert child3_computed_childvar.text == "computed_childvar"
|
||||
@ -271,11 +314,59 @@ def test_state_inheritance(
|
||||
child3_base2 = driver.find_element(By.ID, "child3-base2")
|
||||
assert child3_base2.text == "base2"
|
||||
|
||||
child3_mixin = driver.find_element(By.ID, "child3-mixin")
|
||||
assert child3_mixin.text == "mixin"
|
||||
|
||||
child3_other_mixin = driver.find_element(By.ID, "child3-other_mixin")
|
||||
assert child3_other_mixin.text == "other_mixin"
|
||||
|
||||
child3_child_mixin = driver.find_element(By.ID, "child3-child_mixin")
|
||||
assert child3_child_mixin.text == "child_mixin"
|
||||
# Event Handler Tests
|
||||
raises_alert(driver, "base1-mixin-btn")
|
||||
raises_alert(driver, "child2-mixin-btn")
|
||||
raises_alert(driver, "child3-mixin-btn")
|
||||
|
||||
child1_other_mixin_btn = driver.find_element(By.ID, "child1-other-mixin-btn")
|
||||
child1_other_mixin_btn.click()
|
||||
child1_other_mixin_value = state_inheritance.poll_for_content(
|
||||
child1_other_mixin, exp_not_equal="other_mixin"
|
||||
)
|
||||
child1_computed_mixin_value = state_inheritance.poll_for_content(
|
||||
child1_computed_other_mixin, exp_not_equal="other_mixin"
|
||||
)
|
||||
assert child1_other_mixin_value == "Child1.clicked.1"
|
||||
assert child1_computed_mixin_value == "Child1.clicked.1"
|
||||
|
||||
child2_other_mixin_btn = driver.find_element(By.ID, "child2-other-mixin-btn")
|
||||
child2_other_mixin_btn.click()
|
||||
child2_other_mixin_value = state_inheritance.poll_for_content(
|
||||
child2_other_mixin, exp_not_equal="other_mixin"
|
||||
)
|
||||
child2_computed_mixin_value = state_inheritance.poll_for_content(
|
||||
child2_computed_other_mixin, exp_not_equal="other_mixin"
|
||||
)
|
||||
child3_other_mixin_value = state_inheritance.poll_for_content(
|
||||
child3_other_mixin, exp_not_equal="other_mixin"
|
||||
)
|
||||
child3_computed_mixin_value = state_inheritance.poll_for_content(
|
||||
child3_computed_other_mixin, exp_not_equal="other_mixin"
|
||||
)
|
||||
assert child2_other_mixin_value == "Child2.clicked.1"
|
||||
assert child2_computed_mixin_value == "Child2.clicked.1"
|
||||
assert child3_other_mixin_value == "Child2.clicked.1"
|
||||
assert child3_computed_mixin_value == "Child2.clicked.1"
|
||||
|
||||
child3_other_mixin_btn = driver.find_element(By.ID, "child3-other-mixin-btn")
|
||||
child3_other_mixin_btn.click()
|
||||
child2_other_mixin_value = state_inheritance.poll_for_content(
|
||||
child2_other_mixin, exp_not_equal="other_mixin"
|
||||
)
|
||||
child2_computed_mixin_value = state_inheritance.poll_for_content(
|
||||
child2_computed_other_mixin, exp_not_equal="other_mixin"
|
||||
)
|
||||
child3_other_mixin_value = state_inheritance.poll_for_content(
|
||||
child3_other_mixin, exp_not_equal="other_mixin"
|
||||
)
|
||||
child3_computed_mixin_value = state_inheritance.poll_for_content(
|
||||
child3_computed_other_mixin, exp_not_equal="other_mixin"
|
||||
)
|
||||
assert child2_other_mixin_value == "Child2.clicked.2"
|
||||
assert child2_computed_mixin_value == "Child2.clicked.2"
|
||||
assert child3_other_mixin.text == "Child2.clicked.2"
|
||||
assert child3_computed_other_mixin.text == "Child2.clicked.2"
|
||||
|
@ -2,7 +2,7 @@
|
||||
import axios from "axios";
|
||||
import io from "socket.io-client";
|
||||
import JSON5 from "json5";
|
||||
import env from "env.json";
|
||||
import env from "/env.json";
|
||||
import Cookies from "universal-cookie";
|
||||
import { useEffect, useReducer, useRef, useState } from "react";
|
||||
import Router, { useRouter } from "next/router";
|
||||
@ -74,18 +74,23 @@ export const getToken = () => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the URL for the websocket connection
|
||||
* @returns The websocket URL object.
|
||||
* Get the URL for the backend server
|
||||
* @param url_str The URL string to parse.
|
||||
* @returns The given URL modified to point to the actual backend server.
|
||||
*/
|
||||
export const getEventURL = () => {
|
||||
export const getBackendURL = (url_str) => {
|
||||
// Get backend URL object from the endpoint.
|
||||
const endpoint = new URL(EVENTURL);
|
||||
const endpoint = new URL(url_str);
|
||||
if (SAME_DOMAIN_HOSTNAMES.includes(endpoint.hostname)) {
|
||||
// Use the frontend domain to access the backend
|
||||
const frontend_hostname = window.location.hostname;
|
||||
endpoint.hostname = frontend_hostname;
|
||||
if (window.location.protocol === "https:" && endpoint.protocol === "ws:") {
|
||||
endpoint.protocol = "wss:";
|
||||
if (window.location.protocol === "https:") {
|
||||
if (endpoint.protocol === "ws:") {
|
||||
endpoint.protocol = "wss:";
|
||||
} else if (endpoint.protocol === "http:") {
|
||||
endpoint.protocol = "https:";
|
||||
}
|
||||
endpoint.port = ""; // Assume websocket is on https port via load balancer.
|
||||
}
|
||||
}
|
||||
@ -296,7 +301,7 @@ export const connect = async (
|
||||
client_storage = {},
|
||||
) => {
|
||||
// Get backend URL object from the endpoint.
|
||||
const endpoint = getEventURL()
|
||||
const endpoint = getBackendURL(EVENTURL)
|
||||
|
||||
// Create the socket.
|
||||
socket.current = io(endpoint.href, {
|
||||
@ -397,7 +402,7 @@ export const uploadFiles = async (handler, files, upload_id, on_upload_progress,
|
||||
upload_controllers[upload_id] = controller
|
||||
|
||||
try {
|
||||
return await axios.post(UPLOADURL, formdata, config)
|
||||
return await axios.post(getBackendURL(UPLOADURL), formdata, config)
|
||||
} catch (error) {
|
||||
if (error.response) {
|
||||
// The request was made and the server responded with a status code
|
||||
|
@ -17,7 +17,7 @@ class Button(BaseHTML):
|
||||
auto_focus: Var[Union[str, int, bool]]
|
||||
|
||||
# Disables the button
|
||||
disabled: Var[Union[str, int, bool]]
|
||||
disabled: Var[bool]
|
||||
|
||||
# Associates the button with a form (by id)
|
||||
form: Var[Union[str, int, bool]]
|
||||
|
@ -22,9 +22,7 @@ class Button(BaseHTML):
|
||||
auto_focus: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
disabled: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
disabled: Optional[Union[Var[bool], bool]] = None,
|
||||
form: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||
form_action: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
|
@ -6,9 +6,9 @@ from reflex import el
|
||||
from reflex.constants import EventTriggers
|
||||
from reflex.vars import Var
|
||||
|
||||
from ..base import LiteralSize, RadixThemesComponent
|
||||
from ..base import RadixThemesComponent
|
||||
|
||||
LiteralSwitchSize = Literal["1", "2", "3", "4"]
|
||||
LiteralContentSize = Literal["1", "2", "3", "4"]
|
||||
|
||||
|
||||
class AlertDialogRoot(RadixThemesComponent):
|
||||
@ -43,7 +43,7 @@ class AlertDialogContent(el.Div, RadixThemesComponent):
|
||||
tag = "AlertDialog.Content"
|
||||
|
||||
# The size of the content.
|
||||
size: Var[LiteralSize]
|
||||
size: Var[LiteralContentSize]
|
||||
|
||||
# Whether to force mount the content on open.
|
||||
force_mount: Var[bool]
|
||||
|
@ -12,9 +12,9 @@ from typing import Any, Dict, Literal
|
||||
from reflex import el
|
||||
from reflex.constants import EventTriggers
|
||||
from reflex.vars import Var
|
||||
from ..base import LiteralSize, RadixThemesComponent
|
||||
from ..base import RadixThemesComponent
|
||||
|
||||
LiteralSwitchSize = Literal["1", "2", "3", "4"]
|
||||
LiteralContentSize = Literal["1", "2", "3", "4"]
|
||||
|
||||
class AlertDialogRoot(RadixThemesComponent):
|
||||
def get_event_triggers(self) -> Dict[str, Any]: ...
|
||||
@ -385,10 +385,7 @@ class AlertDialogContent(el.Div, RadixThemesComponent):
|
||||
]
|
||||
] = None,
|
||||
size: Optional[
|
||||
Union[
|
||||
Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]],
|
||||
Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"],
|
||||
]
|
||||
Union[Var[Literal["1", "2", "3", "4"]], Literal["1", "2", "3", "4"]]
|
||||
] = None,
|
||||
force_mount: Optional[Union[Var[bool], bool]] = None,
|
||||
access_key: Optional[
|
||||
|
@ -108,9 +108,7 @@ class Button(el.Button, RadixThemesComponent):
|
||||
auto_focus: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
disabled: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
disabled: Optional[Union[Var[bool], bool]] = None,
|
||||
form: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||
form_action: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
|
@ -49,7 +49,7 @@ class DialogContent(el.Div, RadixThemesComponent):
|
||||
tag = "Dialog.Content"
|
||||
|
||||
# DialogContent size "1" - "4"
|
||||
size: Var[Literal[1, 2, 3, 4]]
|
||||
size: Var[Literal["1", "2", "3", "4"]]
|
||||
|
||||
def get_event_triggers(self) -> Dict[str, Any]:
|
||||
"""Get the events triggers signatures for the component.
|
||||
|
@ -528,7 +528,9 @@ class DialogContent(el.Div, RadixThemesComponent):
|
||||
],
|
||||
]
|
||||
] = None,
|
||||
size: Optional[Union[Var[Literal[1, 2, 3, 4]], Literal[1, 2, 3, 4]]] = None,
|
||||
size: Optional[
|
||||
Union[Var[Literal["1", "2", "3", "4"]], Literal["1", "2", "3", "4"]]
|
||||
] = None,
|
||||
access_key: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
|
@ -111,9 +111,7 @@ class IconButton(el.Button, RadixThemesComponent):
|
||||
auto_focus: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
disabled: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
disabled: Optional[Union[Var[bool], bool]] = None,
|
||||
form: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||
form_action: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
|
@ -46,7 +46,7 @@ class PopoverContent(el.Div, RadixThemesComponent):
|
||||
tag = "Popover.Content"
|
||||
|
||||
# Size of the button: "1" | "2" | "3" | "4"
|
||||
size: Var[Literal[1, 2, 3, 4]]
|
||||
size: Var[Literal["1", "2", "3", "4"]]
|
||||
|
||||
# The preferred side of the anchor to render against when open. Will be reversed when collisions occur and avoidCollisions is enabled.
|
||||
side: Var[Literal["top", "right", "bottom", "left"]]
|
||||
|
@ -384,7 +384,9 @@ class PopoverContent(el.Div, RadixThemesComponent):
|
||||
],
|
||||
]
|
||||
] = None,
|
||||
size: Optional[Union[Var[Literal[1, 2, 3, 4]], Literal[1, 2, 3, 4]]] = None,
|
||||
size: Optional[
|
||||
Union[Var[Literal["1", "2", "3", "4"]], Literal["1", "2", "3", "4"]]
|
||||
] = None,
|
||||
side: Optional[
|
||||
Union[
|
||||
Var[Literal["top", "right", "bottom", "left"]],
|
||||
|
@ -50,12 +50,6 @@ class RadioGroupRoot(RadixThemesComponent):
|
||||
# Whether the radio group is required
|
||||
required: Var[bool]
|
||||
|
||||
# The orientation of the component.
|
||||
orientation: Var[Literal["horizontal", "vertical"]]
|
||||
|
||||
# When true, keyboard navigation will loop from last item to first, and vice versa.
|
||||
loop: Var[bool]
|
||||
|
||||
# Props to rename
|
||||
_rename_props = {"onChange": "onValueChange"}
|
||||
|
||||
@ -86,7 +80,7 @@ class RadioGroupItem(RadixThemesComponent):
|
||||
required: Var[bool]
|
||||
|
||||
|
||||
class HighLevelRadioGroup(RadioGroupRoot):
|
||||
class HighLevelRadioGroup(RadixThemesComponent):
|
||||
"""High level wrapper for the RadioGroup component."""
|
||||
|
||||
# The items of the radio group.
|
||||
@ -101,6 +95,33 @@ class HighLevelRadioGroup(RadioGroupRoot):
|
||||
# The size of the radio group.
|
||||
size: Var[Literal["1", "2", "3"]] = Var.create_safe("2")
|
||||
|
||||
# The variant of the radio group
|
||||
variant: Var[Literal["classic", "surface", "soft"]]
|
||||
|
||||
# The color of the radio group
|
||||
color_scheme: Var[LiteralAccentColor]
|
||||
|
||||
# Whether to render the radio group with higher contrast color against background
|
||||
high_contrast: Var[bool]
|
||||
|
||||
# The controlled value of the radio item to check. Should be used in conjunction with on_change.
|
||||
value: Var[str]
|
||||
|
||||
# The initial value of checked radio item. Should be used in conjunction with on_change.
|
||||
default_value: Var[str]
|
||||
|
||||
# Whether the radio group is disabled
|
||||
disabled: Var[bool]
|
||||
|
||||
# The name of the group. Submitted with its owning form as part of a name/value pair.
|
||||
name: Var[str]
|
||||
|
||||
# Whether the radio group is required
|
||||
required: Var[bool]
|
||||
|
||||
# Props to rename
|
||||
_rename_props = {"onChange": "onValueChange"}
|
||||
|
||||
@classmethod
|
||||
def create(
|
||||
cls,
|
||||
|
@ -104,13 +104,6 @@ class RadioGroupRoot(RadixThemesComponent):
|
||||
disabled: Optional[Union[Var[bool], bool]] = None,
|
||||
name: Optional[Union[Var[str], str]] = None,
|
||||
required: Optional[Union[Var[bool], bool]] = None,
|
||||
orientation: Optional[
|
||||
Union[
|
||||
Var[Literal["horizontal", "vertical"]],
|
||||
Literal["horizontal", "vertical"],
|
||||
]
|
||||
] = None,
|
||||
loop: Optional[Union[Var[bool], bool]] = None,
|
||||
style: Optional[Style] = None,
|
||||
key: Optional[Any] = None,
|
||||
id: Optional[Any] = None,
|
||||
@ -185,8 +178,6 @@ class RadioGroupRoot(RadixThemesComponent):
|
||||
disabled: Whether the radio group is disabled
|
||||
name: The name of the group. Submitted with its owning form as part of a name/value pair.
|
||||
required: Whether the radio group is required
|
||||
orientation: The orientation of the component.
|
||||
loop: When true, keyboard navigation will loop from last item to first, and vice versa.
|
||||
style: Props to rename The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
@ -353,7 +344,7 @@ class RadioGroupItem(RadixThemesComponent):
|
||||
"""
|
||||
...
|
||||
|
||||
class HighLevelRadioGroup(RadioGroupRoot):
|
||||
class HighLevelRadioGroup(RadixThemesComponent):
|
||||
@overload
|
||||
@classmethod
|
||||
def create( # type: ignore
|
||||
@ -449,13 +440,6 @@ class HighLevelRadioGroup(RadioGroupRoot):
|
||||
disabled: Optional[Union[Var[bool], bool]] = None,
|
||||
name: Optional[Union[Var[str], str]] = None,
|
||||
required: Optional[Union[Var[bool], bool]] = None,
|
||||
orientation: Optional[
|
||||
Union[
|
||||
Var[Literal["horizontal", "vertical"]],
|
||||
Literal["horizontal", "vertical"],
|
||||
]
|
||||
] = None,
|
||||
loop: Optional[Union[Var[bool], bool]] = None,
|
||||
style: Optional[Style] = None,
|
||||
key: Optional[Any] = None,
|
||||
id: Optional[Any] = None,
|
||||
@ -466,9 +450,6 @@ class HighLevelRadioGroup(RadioGroupRoot):
|
||||
on_blur: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_change: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
on_click: Optional[
|
||||
Union[EventHandler, EventSpec, list, function, BaseVar]
|
||||
] = None,
|
||||
@ -520,7 +501,7 @@ class HighLevelRadioGroup(RadioGroupRoot):
|
||||
items: The items of the radio group.
|
||||
direction: The direction of the radio group.
|
||||
gap: The gap between the items of the radio group.
|
||||
size: The size of the radio group: "1" | "2" | "3"
|
||||
size: The size of the radio group.
|
||||
variant: The variant of the radio group
|
||||
color_scheme: The color of the radio group
|
||||
high_contrast: Whether to render the radio group with higher contrast color against background
|
||||
@ -529,8 +510,6 @@ class HighLevelRadioGroup(RadioGroupRoot):
|
||||
disabled: Whether the radio group is disabled
|
||||
name: The name of the group. Submitted with its owning form as part of a name/value pair.
|
||||
required: Whether the radio group is required
|
||||
orientation: The orientation of the component.
|
||||
loop: When true, keyboard navigation will loop from last item to first, and vice versa.
|
||||
style: Props to rename The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -7,7 +7,6 @@ from reflex.vars import Var
|
||||
|
||||
from ..base import (
|
||||
LiteralAccentColor,
|
||||
LiteralRadius,
|
||||
RadixThemesComponent,
|
||||
)
|
||||
|
||||
@ -32,8 +31,8 @@ class Slider(RadixThemesComponent):
|
||||
# Whether to render the button with higher contrast color against background
|
||||
high_contrast: Var[bool]
|
||||
|
||||
# Override theme radius for button: "none" | "small" | "medium" | "large" | "full"
|
||||
radius: Var[LiteralRadius]
|
||||
# Override theme radius for button: "none" | "small" | "full"
|
||||
radius: Var[Literal["none", "small", "full"]]
|
||||
|
||||
# The value of the slider when initially rendered. Use when you do not need to control the state of the slider.
|
||||
default_value: Var[Union[List[Union[float, int]], float, int]]
|
||||
|
@ -11,7 +11,7 @@ from typing import Any, Dict, List, Literal, Optional, Union
|
||||
from reflex.components.component import Component
|
||||
from reflex.constants import EventTriggers
|
||||
from reflex.vars import Var
|
||||
from ..base import LiteralAccentColor, LiteralRadius, RadixThemesComponent
|
||||
from ..base import LiteralAccentColor, RadixThemesComponent
|
||||
|
||||
class Slider(RadixThemesComponent):
|
||||
def get_event_triggers(self) -> Dict[str, Any]: ...
|
||||
@ -96,8 +96,7 @@ class Slider(RadixThemesComponent):
|
||||
high_contrast: Optional[Union[Var[bool], bool]] = None,
|
||||
radius: Optional[
|
||||
Union[
|
||||
Var[Literal["none", "small", "medium", "large", "full"]],
|
||||
Literal["none", "small", "medium", "large", "full"],
|
||||
Var[Literal["none", "small", "full"]], Literal["none", "small", "full"]
|
||||
]
|
||||
] = None,
|
||||
default_value: Optional[
|
||||
@ -190,7 +189,7 @@ class Slider(RadixThemesComponent):
|
||||
variant: Variant of button
|
||||
color_scheme: Override theme color for button
|
||||
high_contrast: Whether to render the button with higher contrast color against background
|
||||
radius: Override theme radius for button: "none" | "small" | "medium" | "large" | "full"
|
||||
radius: Override theme radius for button: "none" | "small" | "full"
|
||||
default_value: The value of the slider when initially rendered. Use when you do not need to control the state of the slider.
|
||||
value: The controlled value of the slider. Must be used in conjunction with onValueChange.
|
||||
name: The name of the slider. Submitted with its owning form as part of a name/value pair.
|
||||
|
@ -6,12 +6,10 @@ from reflex.vars import Var
|
||||
|
||||
from ..base import (
|
||||
LiteralAccentColor,
|
||||
LiteralRadius,
|
||||
LiteralVariant,
|
||||
RadixThemesComponent,
|
||||
)
|
||||
|
||||
LiteralSwitchSize = Literal["1", "2", "3", "4"]
|
||||
LiteralSwitchSize = Literal["1", "2", "3"]
|
||||
|
||||
|
||||
class Switch(RadixThemesComponent):
|
||||
@ -43,8 +41,8 @@ class Switch(RadixThemesComponent):
|
||||
# Switch size "1" - "4"
|
||||
size: Var[LiteralSwitchSize]
|
||||
|
||||
# Variant of switch: "solid" | "soft" | "outline" | "ghost"
|
||||
variant: Var[LiteralVariant]
|
||||
# Variant of switch: "classic" | "surface" | "soft"
|
||||
variant: Var[Literal["classic", "surface", "soft"]]
|
||||
|
||||
# Override theme color for switch
|
||||
color_scheme: Var[LiteralAccentColor]
|
||||
@ -52,8 +50,8 @@ class Switch(RadixThemesComponent):
|
||||
# Whether to render the switch with higher contrast color against background
|
||||
high_contrast: Var[bool]
|
||||
|
||||
# Override theme radius for switch: "none" | "small" | "medium" | "large" | "full"
|
||||
radius: Var[LiteralRadius]
|
||||
# Override theme radius for switch: "none" | "small" | "full"
|
||||
radius: Var[Literal["none", "small", "full"]]
|
||||
|
||||
# Props to rename
|
||||
_rename_props = {"onChange": "onCheckedChange"}
|
||||
|
@ -10,14 +10,9 @@ from reflex.style import Style
|
||||
from typing import Any, Dict, Literal
|
||||
from reflex.constants import EventTriggers
|
||||
from reflex.vars import Var
|
||||
from ..base import (
|
||||
LiteralAccentColor,
|
||||
LiteralRadius,
|
||||
LiteralVariant,
|
||||
RadixThemesComponent,
|
||||
)
|
||||
from ..base import LiteralAccentColor, RadixThemesComponent
|
||||
|
||||
LiteralSwitchSize = Literal["1", "2", "3", "4"]
|
||||
LiteralSwitchSize = Literal["1", "2", "3"]
|
||||
|
||||
class Switch(RadixThemesComponent):
|
||||
def get_event_triggers(self) -> Dict[str, Any]: ...
|
||||
@ -97,19 +92,18 @@ class Switch(RadixThemesComponent):
|
||||
name: Optional[Union[Var[str], str]] = None,
|
||||
value: Optional[Union[Var[str], str]] = None,
|
||||
size: Optional[
|
||||
Union[Var[Literal["1", "2", "3", "4"]], Literal["1", "2", "3", "4"]]
|
||||
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"],
|
||||
Var[Literal["classic", "surface", "soft"]],
|
||||
Literal["classic", "surface", "soft"],
|
||||
]
|
||||
] = 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"],
|
||||
Var[Literal["none", "small", "full"]], Literal["none", "small", "full"]
|
||||
]
|
||||
] = None,
|
||||
style: Optional[Style] = None,
|
||||
@ -186,9 +180,9 @@ class Switch(RadixThemesComponent):
|
||||
name: The name of the switch (when submitting a form)
|
||||
value: The value associated with the "on" position
|
||||
size: Switch size "1" - "4"
|
||||
variant: Variant of switch: "solid" | "soft" | "outline" | "ghost"
|
||||
variant: Variant of switch: "classic" | "surface" | "soft"
|
||||
high_contrast: Whether to render the switch with higher contrast color against background
|
||||
radius: Override theme radius for switch: "none" | "small" | "medium" | "large" | "full"
|
||||
radius: Override theme radius for switch: "none" | "small" | "full"
|
||||
style: Props to rename The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -15,9 +15,6 @@ class TabsRoot(RadixThemesComponent):
|
||||
|
||||
tag = "Tabs.Root"
|
||||
|
||||
# The variant of the tab
|
||||
variant: Var[Literal["surface", "ghost"]]
|
||||
|
||||
# The value of the tab that should be active when initially rendered. Use when you do not need to control the state of the tabs.
|
||||
default_value: Var[str]
|
||||
|
||||
@ -47,6 +44,9 @@ class TabsList(RadixThemesComponent):
|
||||
|
||||
tag = "Tabs.List"
|
||||
|
||||
# Tabs size "1" - "2"
|
||||
size: Var[Literal["1", "2"]]
|
||||
|
||||
|
||||
class TabsTrigger(RadixThemesComponent):
|
||||
"""Trigger an action or event, such as submitting a form or displaying a dialog."""
|
||||
|
@ -83,9 +83,6 @@ class TabsRoot(RadixThemesComponent):
|
||||
],
|
||||
]
|
||||
] = None,
|
||||
variant: Optional[
|
||||
Union[Var[Literal["surface", "ghost"]], Literal["surface", "ghost"]]
|
||||
] = None,
|
||||
default_value: Optional[Union[Var[str], str]] = None,
|
||||
value: Optional[Union[Var[str], str]] = None,
|
||||
orientation: Optional[
|
||||
@ -160,7 +157,6 @@ class TabsRoot(RadixThemesComponent):
|
||||
*children: Child components.
|
||||
color: map to CSS default color property.
|
||||
color_scheme: map to radix color property.
|
||||
variant: The variant of the tab
|
||||
default_value: The value of the tab that should be active when initially rendered. Use when you do not need to control the state of the tabs.
|
||||
value: The controlled value of the tab that should be active. Use when you need to control the state of the tabs.
|
||||
orientation: The orientation of the tabs.
|
||||
@ -247,6 +243,7 @@ class TabsList(RadixThemesComponent):
|
||||
],
|
||||
]
|
||||
] = None,
|
||||
size: Optional[Union[Var[Literal["1", "2"]], Literal["1", "2"]]] = None,
|
||||
style: Optional[Style] = None,
|
||||
key: Optional[Any] = None,
|
||||
id: Optional[Any] = None,
|
||||
@ -310,6 +307,7 @@ class TabsList(RadixThemesComponent):
|
||||
*children: Child components.
|
||||
color: map to CSS default color property.
|
||||
color_scheme: map to radix color property.
|
||||
size: Tabs size "1" - "2"
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""Interactive components provided by @radix-ui/themes."""
|
||||
from typing import Any, Dict, Literal
|
||||
from typing import Any, Dict, Literal, Union
|
||||
|
||||
from reflex import el
|
||||
from reflex.components.component import Component
|
||||
@ -29,6 +29,48 @@ class TextArea(RadixThemesComponent, el.Textarea):
|
||||
# The color of the text area
|
||||
color_scheme: Var[LiteralAccentColor]
|
||||
|
||||
# Whether the form control should have autocomplete enabled
|
||||
auto_complete: Var[bool]
|
||||
|
||||
# Automatically focuses the textarea when the page loads
|
||||
auto_focus: Var[bool]
|
||||
|
||||
# Name part of the textarea to submit in 'dir' and 'name' pair when form is submitted
|
||||
dirname: Var[str]
|
||||
|
||||
# Disables the textarea
|
||||
disabled: Var[bool]
|
||||
|
||||
# Associates the textarea with a form (by id)
|
||||
form: Var[Union[str, int, bool]]
|
||||
|
||||
# Maximum number of characters allowed in the textarea
|
||||
max_length: Var[int]
|
||||
|
||||
# Minimum number of characters required in the textarea
|
||||
min_length: Var[int]
|
||||
|
||||
# Name of the textarea, used when submitting the form
|
||||
name: Var[str]
|
||||
|
||||
# Placeholder text in the textarea
|
||||
placeholder: Var[str]
|
||||
|
||||
# Indicates whether the textarea is read-only
|
||||
read_only: Var[bool]
|
||||
|
||||
# Indicates that the textarea is required
|
||||
required: Var[bool]
|
||||
|
||||
# Visible number of lines in the text control
|
||||
rows: Var[str]
|
||||
|
||||
# The controlled value of the textarea, read only unless used with on_change
|
||||
value: Var[str]
|
||||
|
||||
# How the text in the textarea is to be wrapped when submitting the form
|
||||
wrap: Var[str]
|
||||
|
||||
@classmethod
|
||||
def create(cls, *children, **props) -> Component:
|
||||
"""Create an Input component.
|
||||
|
@ -7,7 +7,7 @@ from typing import Any, Dict, Literal, Optional, Union, overload
|
||||
from reflex.vars import Var, BaseVar, ComputedVar
|
||||
from reflex.event import EventChain, EventHandler, EventSpec
|
||||
from reflex.style import Style
|
||||
from typing import Any, Dict, Literal
|
||||
from typing import Any, Dict, Literal, Union
|
||||
from reflex import el
|
||||
from reflex.components.component import Component
|
||||
from reflex.components.core.debounce import DebounceInput
|
||||
@ -94,41 +94,21 @@ class TextArea(RadixThemesComponent, el.Textarea):
|
||||
],
|
||||
]
|
||||
] = None,
|
||||
auto_complete: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
auto_focus: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
cols: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||
dirname: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
disabled: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
auto_complete: Optional[Union[Var[bool], bool]] = None,
|
||||
auto_focus: Optional[Union[Var[bool], bool]] = None,
|
||||
dirname: Optional[Union[Var[str], str]] = None,
|
||||
disabled: Optional[Union[Var[bool], bool]] = None,
|
||||
form: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||
max_length: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
min_length: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
name: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||
placeholder: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
read_only: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
required: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
rows: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||
value: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
wrap: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||
max_length: Optional[Union[Var[int], int]] = None,
|
||||
min_length: Optional[Union[Var[int], int]] = None,
|
||||
name: Optional[Union[Var[str], str]] = None,
|
||||
placeholder: Optional[Union[Var[str], str]] = None,
|
||||
read_only: Optional[Union[Var[bool], bool]] = None,
|
||||
required: Optional[Union[Var[bool], bool]] = None,
|
||||
rows: Optional[Union[Var[str], str]] = None,
|
||||
value: Optional[Union[Var[str], str]] = None,
|
||||
wrap: Optional[Union[Var[str], str]] = None,
|
||||
cols: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
|
||||
access_key: Optional[
|
||||
Union[Var[Union[str, int, bool]], Union[str, int, bool]]
|
||||
] = None,
|
||||
@ -244,7 +224,6 @@ class TextArea(RadixThemesComponent, el.Textarea):
|
||||
color_scheme: The color of the text area
|
||||
auto_complete: Whether the form control should have autocomplete enabled
|
||||
auto_focus: Automatically focuses the textarea when the page loads
|
||||
cols: Visible width of the text control, in average character widths
|
||||
dirname: Name part of the textarea to submit in 'dir' and 'name' pair when form is submitted
|
||||
disabled: Disables the textarea
|
||||
form: Associates the textarea with a form (by id)
|
||||
@ -257,6 +236,7 @@ class TextArea(RadixThemesComponent, el.Textarea):
|
||||
rows: Visible number of lines in the text control
|
||||
value: The controlled value of the textarea, read only unless used with on_change
|
||||
wrap: How the text in the textarea is to be wrapped when submitting the form
|
||||
cols: Visible width of the text control, in average character widths
|
||||
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.
|
||||
|
@ -14,7 +14,6 @@ from reflex.vars import Var
|
||||
from ..base import (
|
||||
LiteralAccentColor,
|
||||
LiteralRadius,
|
||||
LiteralSize,
|
||||
RadixThemesComponent,
|
||||
)
|
||||
|
||||
@ -85,9 +84,6 @@ class TextFieldSlot(RadixThemesComponent):
|
||||
# Override theme color for text field slot
|
||||
color_scheme: Var[LiteralAccentColor]
|
||||
|
||||
# Override the gap spacing between slot and input: "1" - "9"
|
||||
gap: Var[LiteralSize]
|
||||
|
||||
|
||||
class Input(RadixThemesComponent):
|
||||
"""High level wrapper for the Input component."""
|
||||
|
@ -16,7 +16,7 @@ from reflex.components.core.debounce import DebounceInput
|
||||
from reflex.components.lucide.icon import Icon
|
||||
from reflex.constants import EventTriggers
|
||||
from reflex.vars import Var
|
||||
from ..base import LiteralAccentColor, LiteralRadius, LiteralSize, RadixThemesComponent
|
||||
from ..base import LiteralAccentColor, LiteralRadius, RadixThemesComponent
|
||||
|
||||
LiteralTextFieldSize = Literal["1", "2", "3"]
|
||||
LiteralTextFieldVariant = Literal["classic", "surface", "soft"]
|
||||
@ -651,12 +651,6 @@ class TextFieldSlot(RadixThemesComponent):
|
||||
],
|
||||
]
|
||||
] = None,
|
||||
gap: 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,
|
||||
@ -720,7 +714,6 @@ class TextFieldSlot(RadixThemesComponent):
|
||||
*children: Child components.
|
||||
color: map to CSS default color property.
|
||||
color_scheme: map to radix color property.
|
||||
gap: Override the gap spacing between slot and input: "1" - "9"
|
||||
style: The style of the component.
|
||||
key: A unique key for the component.
|
||||
id: The id for the component.
|
||||
|
@ -4,6 +4,8 @@ https://www.radix-ui.com/themes/docs/theme/typography
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Literal
|
||||
|
||||
from reflex import el
|
||||
from reflex.vars import Var
|
||||
|
||||
@ -18,6 +20,8 @@ from .base import (
|
||||
LiteralTextWeight,
|
||||
)
|
||||
|
||||
LiteralType = Literal["p", "label", "div", "span"]
|
||||
|
||||
|
||||
class Text(el.Span, RadixThemesComponent):
|
||||
"""A foundational text primitive based on the <span> element."""
|
||||
@ -28,7 +32,7 @@ class Text(el.Span, RadixThemesComponent):
|
||||
as_child: Var[bool]
|
||||
|
||||
# Change the default rendered element into a semantically appropriate alternative (cannot be used with asChild)
|
||||
as_: Var[str]
|
||||
as_: Var[LiteralType] = "p" # type: ignore
|
||||
|
||||
# Text size: "1" - "9"
|
||||
size: Var[LiteralTextSize]
|
||||
|
@ -7,11 +7,14 @@ from typing import Any, Dict, Literal, Optional, Union, overload
|
||||
from reflex.vars import Var, BaseVar, ComputedVar
|
||||
from reflex.event import EventChain, EventHandler, EventSpec
|
||||
from reflex.style import Style
|
||||
from typing import Literal
|
||||
from reflex import el
|
||||
from reflex.vars import Var
|
||||
from ..base import LiteralAccentColor, RadixThemesComponent
|
||||
from .base import LiteralTextAlign, LiteralTextSize, LiteralTextTrim, LiteralTextWeight
|
||||
|
||||
LiteralType = Literal["p", "label", "div", "span"]
|
||||
|
||||
class Text(el.Span, RadixThemesComponent):
|
||||
@overload
|
||||
@classmethod
|
||||
@ -82,7 +85,12 @@ class Text(el.Span, RadixThemesComponent):
|
||||
]
|
||||
] = None,
|
||||
as_child: Optional[Union[Var[bool], bool]] = None,
|
||||
as_: Optional[Union[Var[str], str]] = None,
|
||||
as_: Optional[
|
||||
Union[
|
||||
Var[Literal["p", "label", "div", "span"]],
|
||||
Literal["p", "label", "div", "span"],
|
||||
]
|
||||
] = None,
|
||||
size: Optional[
|
||||
Union[
|
||||
Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]],
|
||||
|
@ -332,9 +332,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
}
|
||||
cls.computed_vars = {
|
||||
v._var_name: v._var_set_state(cls)
|
||||
for mixin in cls.__mro__
|
||||
if mixin is cls or not issubclass(mixin, (BaseState, ABC))
|
||||
for v in mixin.__dict__.values()
|
||||
for v in cls.__dict__.values()
|
||||
if isinstance(v, ComputedVar)
|
||||
}
|
||||
cls.vars = {
|
||||
@ -352,10 +350,29 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
events = {
|
||||
name: fn
|
||||
for name, fn in cls.__dict__.items()
|
||||
if not name.startswith("_")
|
||||
and isinstance(fn, Callable)
|
||||
and not isinstance(fn, EventHandler)
|
||||
if cls._item_is_event_handler(name, fn)
|
||||
}
|
||||
|
||||
for mixin in cls._mixins():
|
||||
for name, value in mixin.__dict__.items():
|
||||
if isinstance(value, ComputedVar):
|
||||
fget = cls._copy_fn(value.fget)
|
||||
newcv = ComputedVar(fget=fget, _var_name=value._var_name)
|
||||
newcv._var_set_state(cls)
|
||||
setattr(cls, name, newcv)
|
||||
cls.computed_vars[newcv._var_name] = newcv
|
||||
cls.vars[newcv._var_name] = newcv
|
||||
continue
|
||||
if events.get(name) is not None:
|
||||
continue
|
||||
if not cls._item_is_event_handler(name, value):
|
||||
continue
|
||||
if parent_state is not None and parent_state.event_handlers.get(name):
|
||||
continue
|
||||
value = cls._copy_fn(value)
|
||||
value.__qualname__ = f"{cls.__name__}.{name}"
|
||||
events[name] = value
|
||||
|
||||
for name, fn in events.items():
|
||||
handler = EventHandler(fn=fn)
|
||||
cls.event_handlers[name] = handler
|
||||
@ -363,6 +380,58 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
|
||||
|
||||
cls._init_var_dependency_dicts()
|
||||
|
||||
@staticmethod
|
||||
def _copy_fn(fn: Callable) -> Callable:
|
||||
"""Copy a function. Used to copy ComputedVars and EventHandlers from mixins.
|
||||
|
||||
Args:
|
||||
fn: The function to copy.
|
||||
|
||||
Returns:
|
||||
The copied function.
|
||||
"""
|
||||
newfn = FunctionType(
|
||||
fn.__code__,
|
||||
fn.__globals__,
|
||||
name=fn.__name__,
|
||||
argdefs=fn.__defaults__,
|
||||
closure=fn.__closure__,
|
||||
)
|
||||
newfn.__annotations__ = fn.__annotations__
|
||||
return newfn
|
||||
|
||||
@staticmethod
|
||||
def _item_is_event_handler(name: str, value: Any) -> bool:
|
||||
"""Check if the item is an event handler.
|
||||
|
||||
Args:
|
||||
name: The name of the item.
|
||||
value: The value of the item.
|
||||
|
||||
Returns:
|
||||
Whether the item is an event handler.
|
||||
"""
|
||||
return (
|
||||
not name.startswith("_")
|
||||
and isinstance(value, Callable)
|
||||
and not isinstance(value, EventHandler)
|
||||
and hasattr(value, "__code__")
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _mixins(cls) -> List[Type]:
|
||||
"""Get the mixin classes of the state.
|
||||
|
||||
Returns:
|
||||
The mixin classes of the state.
|
||||
"""
|
||||
return [
|
||||
mixin
|
||||
for mixin in cls.__mro__
|
||||
if not issubclass(mixin, (BaseState, ABC))
|
||||
and mixin not in [pydantic.BaseModel, Base]
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def _init_var_dependency_dicts(cls):
|
||||
"""Initialize the var dependency tracking dicts.
|
||||
|
@ -19,6 +19,7 @@ from typing import (
|
||||
Set,
|
||||
Type,
|
||||
Union,
|
||||
overload,
|
||||
_GenericAlias, # type: ignore
|
||||
)
|
||||
|
||||
@ -136,6 +137,16 @@ class ComputedVar(Var):
|
||||
def _deps(self, objclass: Type, obj: Optional[FunctionType] = ...) -> Set[str]: ...
|
||||
def mark_dirty(self, instance) -> None: ...
|
||||
def _determine_var_type(self) -> Type: ...
|
||||
@overload
|
||||
def __init__(
|
||||
self,
|
||||
fget: Callable[[BaseState], Any],
|
||||
fset: Callable[[BaseState, Any], None] | None = None,
|
||||
fdel: Callable[[BaseState], Any] | None = None,
|
||||
doc: str | None = None,
|
||||
**kwargs,
|
||||
) -> None: ...
|
||||
@overload
|
||||
def __init__(self, func) -> None: ...
|
||||
|
||||
def cached_var(fget: Callable[[Any], Any]) -> ComputedVar: ...
|
||||
|
Loading…
Reference in New Issue
Block a user