瀏覽代碼

Merge remote-tracking branch 'origin/main' into reflex-0.4.0

Masen Furer 1 年之前
父節點
當前提交
ae20644a82
共有 28 個文件被更改,包括 373 次插入191 次删除
  1. 128 37
      integration/test_state_inheritance.py
  2. 14 9
      reflex/.templates/web/utils/state.js
  3. 1 1
      reflex/components/el/elements/forms.py
  4. 1 3
      reflex/components/el/elements/forms.pyi
  5. 3 3
      reflex/components/radix/themes/components/alertdialog.py
  6. 3 6
      reflex/components/radix/themes/components/alertdialog.pyi
  7. 1 3
      reflex/components/radix/themes/components/button.pyi
  8. 1 1
      reflex/components/radix/themes/components/dialog.py
  9. 3 1
      reflex/components/radix/themes/components/dialog.pyi
  10. 1 3
      reflex/components/radix/themes/components/iconbutton.pyi
  11. 1 1
      reflex/components/radix/themes/components/popover.py
  12. 3 1
      reflex/components/radix/themes/components/popover.pyi
  13. 28 7
      reflex/components/radix/themes/components/radiogroup.py
  14. 2 23
      reflex/components/radix/themes/components/radiogroup.pyi
  15. 2 3
      reflex/components/radix/themes/components/slider.py
  16. 3 4
      reflex/components/radix/themes/components/slider.pyi
  17. 5 7
      reflex/components/radix/themes/components/switch.py
  18. 8 14
      reflex/components/radix/themes/components/switch.pyi
  19. 3 3
      reflex/components/radix/themes/components/tabs.py
  20. 2 4
      reflex/components/radix/themes/components/tabs.pyi
  21. 43 1
      reflex/components/radix/themes/components/textarea.py
  22. 16 36
      reflex/components/radix/themes/components/textarea.pyi
  23. 0 4
      reflex/components/radix/themes/components/textfield.py
  24. 1 8
      reflex/components/radix/themes/components/textfield.pyi
  25. 5 1
      reflex/components/radix/themes/typography/text.py
  26. 9 1
      reflex/components/radix/themes/typography/text.pyi
  27. 75 6
      reflex/state.py
  28. 11 0
      reflex/vars.pyi

+ 128 - 37
integration/test_state_inheritance.py

@@ -1,5 +1,6 @@
 """Test state inheritance."""
 """Test state inheritance."""
 
 
+import time
 from typing import Generator
 from typing import Generator
 
 
 import pytest
 import pytest
@@ -8,30 +9,57 @@ from selenium.webdriver.common.by import By
 from reflex.testing import DEFAULT_TIMEOUT, AppHarness, WebDriver
 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():
 def StateInheritance():
     """Test that state inheritance works as expected."""
     """Test that state inheritance works as expected."""
     import reflex as rx
     import reflex as rx
 
 
     class ChildMixin:
     class ChildMixin:
-        child_mixin: str = "child_mixin"
+        # mixin basevars only work with pydantic/rx.Base models
+        #  child_mixin: str = "child_mixin"
 
 
         @rx.var
         @rx.var
         def computed_child_mixin(self) -> str:
         def computed_child_mixin(self) -> str:
             return "computed_child_mixin"
             return "computed_child_mixin"
 
 
     class Mixin(ChildMixin):
     class Mixin(ChildMixin):
-        mixin: str = "mixin"
+        # mixin basevars only work with pydantic/rx.Base models
+        #  mixin: str = "mixin"
 
 
         @rx.var
         @rx.var
         def computed_mixin(self) -> str:
         def computed_mixin(self) -> str:
             return "computed_mixin"
             return "computed_mixin"
 
 
+        def on_click_mixin(self):
+            return rx.call_script("alert('clicked')")
+
     class OtherMixin(rx.Base):
     class OtherMixin(rx.Base):
         other_mixin: str = "other_mixin"
         other_mixin: str = "other_mixin"
+        other_mixin_clicks: int = 0
 
 
         @rx.var
         @rx.var
         def computed_other_mixin(self) -> str:
         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):
     class Base1(rx.State, Mixin):
         base1: str = "base1"
         base1: str = "base1"
@@ -65,30 +93,49 @@ def StateInheritance():
             rx.chakra.input(
             rx.chakra.input(
                 id="token", value=Base1.router.session.client_token, is_read_only=True
                 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_mixin, id="base1-computed_mixin"),
             rx.heading(Base1.computed_basevar, id="base1-computed_basevar"),
             rx.heading(Base1.computed_basevar, id="base1-computed_basevar"),
             rx.heading(Base1.computed_child_mixin, id="base1-child-mixin"),
             rx.heading(Base1.computed_child_mixin, id="base1-child-mixin"),
             rx.heading(Base1.base1, id="base1-base1"),
             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.computed_basevar, id="base2-computed_basevar"),
             rx.heading(Base2.base2, id="base2-base2"),
             rx.heading(Base2.base2, id="base2-base2"),
+            # Child 1
             rx.heading(Child1.computed_basevar, id="child1-computed_basevar"),
             rx.heading(Child1.computed_basevar, id="child1-computed_basevar"),
             rx.heading(Child1.computed_mixin, id="child1-computed_mixin"),
             rx.heading(Child1.computed_mixin, id="child1-computed_mixin"),
             rx.heading(Child1.computed_other_mixin, id="child1-other-mixin"),
             rx.heading(Child1.computed_other_mixin, id="child1-other-mixin"),
             rx.heading(Child1.computed_child_mixin, id="child1-child-mixin"),
             rx.heading(Child1.computed_child_mixin, id="child1-child-mixin"),
             rx.heading(Child1.base1, id="child1-base1"),
             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.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_basevar, id="child2-computed_basevar"),
             rx.heading(Child2.computed_mixin, id="child2-computed_mixin"),
             rx.heading(Child2.computed_mixin, id="child2-computed_mixin"),
             rx.heading(Child2.computed_other_mixin, id="child2-other-mixin"),
             rx.heading(Child2.computed_other_mixin, id="child2-other-mixin"),
             rx.heading(Child2.computed_child_mixin, id="child2-child-mixin"),
             rx.heading(Child2.computed_child_mixin, id="child2-child-mixin"),
             rx.heading(Child2.base2, id="child2-base2"),
             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.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_basevar, id="child3-computed_basevar"),
             rx.heading(Child3.computed_mixin, id="child3-computed_mixin"),
             rx.heading(Child3.computed_mixin, id="child3-computed_mixin"),
             rx.heading(Child3.computed_other_mixin, id="child3-other-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.computed_child_mixin, id="child3-child-mixin"),
             rx.heading(Child3.child3, id="child3-child3"),
             rx.heading(Child3.child3, id="child3-child3"),
             rx.heading(Child3.base2, id="child3-base2"),
             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.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()
     app = rx.App()
@@ -178,6 +233,8 @@ def test_state_inheritance(
     """
     """
     assert state_inheritance.app_instance is not None
     assert state_inheritance.app_instance is not None
 
 
+    # Initial State values Test
+    # Base 1
     base1_mixin = driver.find_element(By.ID, "base1-computed_mixin")
     base1_mixin = driver.find_element(By.ID, "base1-computed_mixin")
     assert base1_mixin.text == "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")
     base1_base1 = driver.find_element(By.ID, "base1-base1")
     assert base1_base1.text == "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")
     base2_computed_basevar = driver.find_element(By.ID, "base2-computed_basevar")
     assert base2_computed_basevar.text == "computed_basevar2"
     assert base2_computed_basevar.text == "computed_basevar2"
 
 
     base2_base2 = driver.find_element(By.ID, "base2-base2")
     base2_base2 = driver.find_element(By.ID, "base2-base2")
     assert base2_base2.text == "base2"
     assert base2_base2.text == "base2"
 
 
+    # Child 1
     child1_computed_basevar = driver.find_element(By.ID, "child1-computed_basevar")
     child1_computed_basevar = driver.find_element(By.ID, "child1-computed_basevar")
     assert child1_computed_basevar.text == "computed_basevar1"
     assert child1_computed_basevar.text == "computed_basevar1"
 
 
@@ -209,7 +262,7 @@ def test_state_inheritance(
     assert child1_mixin.text == "computed_mixin"
     assert child1_mixin.text == "computed_mixin"
 
 
     child1_computed_other_mixin = driver.find_element(By.ID, "child1-other-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")
     child1_computed_child_mixin = driver.find_element(By.ID, "child1-child-mixin")
     assert child1_computed_child_mixin.text == "computed_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")
     child1_base1 = driver.find_element(By.ID, "child1-base1")
     assert child1_base1.text == "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")
     child1_other_mixin = driver.find_element(By.ID, "child1-other_mixin")
     assert child1_other_mixin.text == "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")
     child2_computed_basevar = driver.find_element(By.ID, "child2-computed_basevar")
     assert child2_computed_basevar.text == "computed_basevar2"
     assert child2_computed_basevar.text == "computed_basevar2"
 
 
@@ -233,7 +281,7 @@ def test_state_inheritance(
     assert child2_mixin.text == "computed_mixin"
     assert child2_mixin.text == "computed_mixin"
 
 
     child2_computed_other_mixin = driver.find_element(By.ID, "child2-other-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")
     child2_computed_child_mixin = driver.find_element(By.ID, "child2-child-mixin")
     assert child2_computed_child_mixin.text == "computed_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")
     child2_base2 = driver.find_element(By.ID, "child2-base2")
     assert child2_base2.text == "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")
     child2_other_mixin = driver.find_element(By.ID, "child2-other_mixin")
     assert child2_other_mixin.text == "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")
     child3_computed_basevar = driver.find_element(By.ID, "child3-computed_basevar")
     assert child3_computed_basevar.text == "computed_basevar2"
     assert child3_computed_basevar.text == "computed_basevar2"
 
 
@@ -257,7 +300,7 @@ def test_state_inheritance(
     assert child3_mixin.text == "computed_mixin"
     assert child3_mixin.text == "computed_mixin"
 
 
     child3_computed_other_mixin = driver.find_element(By.ID, "child3-other-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")
     child3_computed_childvar = driver.find_element(By.ID, "child3-computed_childvar")
     assert child3_computed_childvar.text == "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")
     child3_base2 = driver.find_element(By.ID, "child3-base2")
     assert child3_base2.text == "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")
     child3_other_mixin = driver.find_element(By.ID, "child3-other_mixin")
     assert child3_other_mixin.text == "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"

+ 14 - 9
reflex/.templates/web/utils/state.js

@@ -2,7 +2,7 @@
 import axios from "axios";
 import axios from "axios";
 import io from "socket.io-client";
 import io from "socket.io-client";
 import JSON5 from "json5";
 import JSON5 from "json5";
-import env from "env.json";
+import env from "/env.json";
 import Cookies from "universal-cookie";
 import Cookies from "universal-cookie";
 import { useEffect, useReducer, useRef, useState } from "react";
 import { useEffect, useReducer, useRef, useState } from "react";
 import Router, { useRouter } from "next/router";
 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.
   // 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)) {
   if (SAME_DOMAIN_HOSTNAMES.includes(endpoint.hostname)) {
     // Use the frontend domain to access the backend
     // Use the frontend domain to access the backend
     const frontend_hostname = window.location.hostname;
     const frontend_hostname = window.location.hostname;
     endpoint.hostname = frontend_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.
       endpoint.port = "";  // Assume websocket is on https port via load balancer.
     }
     }
   }
   }
@@ -296,7 +301,7 @@ export const connect = async (
   client_storage = {},
   client_storage = {},
 ) => {
 ) => {
   // Get backend URL object from the endpoint.
   // Get backend URL object from the endpoint.
-  const endpoint = getEventURL()
+  const endpoint = getBackendURL(EVENTURL)
 
 
   // Create the socket.
   // Create the socket.
   socket.current = io(endpoint.href, {
   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
   upload_controllers[upload_id] = controller
 
 
   try {
   try {
-    return await axios.post(UPLOADURL, formdata, config)
+    return await axios.post(getBackendURL(UPLOADURL), formdata, config)
   } catch (error) {
   } catch (error) {
     if (error.response) {
     if (error.response) {
       // The request was made and the server responded with a status code
       // The request was made and the server responded with a status code

+ 1 - 1
reflex/components/el/elements/forms.py

@@ -17,7 +17,7 @@ class Button(BaseHTML):
     auto_focus: Var[Union[str, int, bool]]
     auto_focus: Var[Union[str, int, bool]]
 
 
     # Disables the button
     # Disables the button
-    disabled: Var[Union[str, int, bool]]
+    disabled: Var[bool]
 
 
     # Associates the button with a form (by id)
     # Associates the button with a form (by id)
     form: Var[Union[str, int, bool]]
     form: Var[Union[str, int, bool]]

+ 1 - 3
reflex/components/el/elements/forms.pyi

@@ -22,9 +22,7 @@ class Button(BaseHTML):
         auto_focus: Optional[
         auto_focus: Optional[
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
         ] = None,
         ] = 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: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
         form_action: Optional[
         form_action: Optional[
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]

+ 3 - 3
reflex/components/radix/themes/components/alertdialog.py

@@ -6,9 +6,9 @@ from reflex import el
 from reflex.constants import EventTriggers
 from reflex.constants import EventTriggers
 from reflex.vars import Var
 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):
 class AlertDialogRoot(RadixThemesComponent):
@@ -43,7 +43,7 @@ class AlertDialogContent(el.Div, RadixThemesComponent):
     tag = "AlertDialog.Content"
     tag = "AlertDialog.Content"
 
 
     # The size of the content.
     # The size of the content.
-    size: Var[LiteralSize]
+    size: Var[LiteralContentSize]
 
 
     # Whether to force mount the content on open.
     # Whether to force mount the content on open.
     force_mount: Var[bool]
     force_mount: Var[bool]

+ 3 - 6
reflex/components/radix/themes/components/alertdialog.pyi

@@ -12,9 +12,9 @@ from typing import Any, Dict, Literal
 from reflex import el
 from reflex import el
 from reflex.constants import EventTriggers
 from reflex.constants import EventTriggers
 from reflex.vars import Var
 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):
 class AlertDialogRoot(RadixThemesComponent):
     def get_event_triggers(self) -> Dict[str, Any]: ...
     def get_event_triggers(self) -> Dict[str, Any]: ...
@@ -385,10 +385,7 @@ class AlertDialogContent(el.Div, RadixThemesComponent):
             ]
             ]
         ] = None,
         ] = None,
         size: Optional[
         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,
         ] = None,
         force_mount: Optional[Union[Var[bool], bool]] = None,
         force_mount: Optional[Union[Var[bool], bool]] = None,
         access_key: Optional[
         access_key: Optional[

+ 1 - 3
reflex/components/radix/themes/components/button.pyi

@@ -108,9 +108,7 @@ class Button(el.Button, RadixThemesComponent):
         auto_focus: Optional[
         auto_focus: Optional[
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
         ] = None,
         ] = 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: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
         form_action: Optional[
         form_action: Optional[
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]

+ 1 - 1
reflex/components/radix/themes/components/dialog.py

@@ -49,7 +49,7 @@ class DialogContent(el.Div, RadixThemesComponent):
     tag = "Dialog.Content"
     tag = "Dialog.Content"
 
 
     # DialogContent size "1" - "4"
     # 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]:
     def get_event_triggers(self) -> Dict[str, Any]:
         """Get the events triggers signatures for the component.
         """Get the events triggers signatures for the component.

+ 3 - 1
reflex/components/radix/themes/components/dialog.pyi

@@ -528,7 +528,9 @@ class DialogContent(el.Div, RadixThemesComponent):
                 ],
                 ],
             ]
             ]
         ] = None,
         ] = 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[
         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,

+ 1 - 3
reflex/components/radix/themes/components/iconbutton.pyi

@@ -111,9 +111,7 @@ class IconButton(el.Button, RadixThemesComponent):
         auto_focus: Optional[
         auto_focus: Optional[
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
         ] = None,
         ] = 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: Optional[Union[Var[Union[str, int, bool]], Union[str, int, bool]]] = None,
         form_action: Optional[
         form_action: Optional[
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]
             Union[Var[Union[str, int, bool]], Union[str, int, bool]]

+ 1 - 1
reflex/components/radix/themes/components/popover.py

@@ -46,7 +46,7 @@ class PopoverContent(el.Div, RadixThemesComponent):
     tag = "Popover.Content"
     tag = "Popover.Content"
 
 
     # Size of the button: "1" | "2" | "3" | "4"
     # 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.
     # 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"]]
     side: Var[Literal["top", "right", "bottom", "left"]]

+ 3 - 1
reflex/components/radix/themes/components/popover.pyi

@@ -384,7 +384,9 @@ class PopoverContent(el.Div, RadixThemesComponent):
                 ],
                 ],
             ]
             ]
         ] = None,
         ] = 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[
         side: Optional[
             Union[
             Union[
                 Var[Literal["top", "right", "bottom", "left"]],
                 Var[Literal["top", "right", "bottom", "left"]],

+ 28 - 7
reflex/components/radix/themes/components/radiogroup.py

@@ -50,12 +50,6 @@ class RadioGroupRoot(RadixThemesComponent):
     # Whether the radio group is required
     # Whether the radio group is required
     required: Var[bool]
     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
     # Props to rename
     _rename_props = {"onChange": "onValueChange"}
     _rename_props = {"onChange": "onValueChange"}
 
 
@@ -86,7 +80,7 @@ class RadioGroupItem(RadixThemesComponent):
     required: Var[bool]
     required: Var[bool]
 
 
 
 
-class HighLevelRadioGroup(RadioGroupRoot):
+class HighLevelRadioGroup(RadixThemesComponent):
     """High level wrapper for the RadioGroup component."""
     """High level wrapper for the RadioGroup component."""
 
 
     # The items of the radio group.
     # The items of the radio group.
@@ -101,6 +95,33 @@ class HighLevelRadioGroup(RadioGroupRoot):
     # The size of the radio group.
     # The size of the radio group.
     size: Var[Literal["1", "2", "3"]] = Var.create_safe("2")
     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
     @classmethod
     def create(
     def create(
         cls,
         cls,

+ 2 - 23
reflex/components/radix/themes/components/radiogroup.pyi

@@ -104,13 +104,6 @@ class RadioGroupRoot(RadixThemesComponent):
         disabled: Optional[Union[Var[bool], bool]] = None,
         disabled: Optional[Union[Var[bool], bool]] = None,
         name: Optional[Union[Var[str], str]] = None,
         name: Optional[Union[Var[str], str]] = None,
         required: Optional[Union[Var[bool], bool]] = 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,
         style: Optional[Style] = None,
         key: Optional[Any] = None,
         key: Optional[Any] = None,
         id: Optional[Any] = None,
         id: Optional[Any] = None,
@@ -185,8 +178,6 @@ class RadioGroupRoot(RadixThemesComponent):
             disabled: Whether the radio group is disabled
             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.
             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
             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.
             style: Props to rename  The style of the component.
             key: A unique key for the component.
             key: A unique key for the component.
             id: The id for the component.
             id: The id for the component.
@@ -353,7 +344,7 @@ class RadioGroupItem(RadixThemesComponent):
         """
         """
         ...
         ...
 
 
-class HighLevelRadioGroup(RadioGroupRoot):
+class HighLevelRadioGroup(RadixThemesComponent):
     @overload
     @overload
     @classmethod
     @classmethod
     def create(  # type: ignore
     def create(  # type: ignore
@@ -449,13 +440,6 @@ class HighLevelRadioGroup(RadioGroupRoot):
         disabled: Optional[Union[Var[bool], bool]] = None,
         disabled: Optional[Union[Var[bool], bool]] = None,
         name: Optional[Union[Var[str], str]] = None,
         name: Optional[Union[Var[str], str]] = None,
         required: Optional[Union[Var[bool], bool]] = 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,
         style: Optional[Style] = None,
         key: Optional[Any] = None,
         key: Optional[Any] = None,
         id: Optional[Any] = None,
         id: Optional[Any] = None,
@@ -466,9 +450,6 @@ class HighLevelRadioGroup(RadioGroupRoot):
         on_blur: Optional[
         on_blur: Optional[
             Union[EventHandler, EventSpec, list, function, BaseVar]
             Union[EventHandler, EventSpec, list, function, BaseVar]
         ] = None,
         ] = None,
-        on_change: Optional[
-            Union[EventHandler, EventSpec, list, function, BaseVar]
-        ] = None,
         on_click: Optional[
         on_click: Optional[
             Union[EventHandler, EventSpec, list, function, BaseVar]
             Union[EventHandler, EventSpec, list, function, BaseVar]
         ] = None,
         ] = None,
@@ -520,7 +501,7 @@ class HighLevelRadioGroup(RadioGroupRoot):
             items: The items of the radio group.
             items: The items of the radio group.
             direction: The direction of the radio group.
             direction: The direction of the radio group.
             gap: The gap between the items 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
             variant: The variant of the radio group
             color_scheme: The color 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
             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
             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.
             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
             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.
             style: Props to rename  The style of the component.
             key: A unique key for the component.
             key: A unique key for the component.
             id: The id for the component.
             id: The id for the component.

+ 2 - 3
reflex/components/radix/themes/components/slider.py

@@ -7,7 +7,6 @@ from reflex.vars import Var
 
 
 from ..base import (
 from ..base import (
     LiteralAccentColor,
     LiteralAccentColor,
-    LiteralRadius,
     RadixThemesComponent,
     RadixThemesComponent,
 )
 )
 
 
@@ -32,8 +31,8 @@ class Slider(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]
+    # 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.
     # 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]]
     default_value: Var[Union[List[Union[float, int]], float, int]]

+ 3 - 4
reflex/components/radix/themes/components/slider.pyi

@@ -11,7 +11,7 @@ from typing import Any, Dict, List, Literal, Optional, Union
 from reflex.components.component import Component
 from reflex.components.component import Component
 from reflex.constants import EventTriggers
 from reflex.constants import EventTriggers
 from reflex.vars import Var
 from reflex.vars import Var
-from ..base import LiteralAccentColor, LiteralRadius, RadixThemesComponent
+from ..base import LiteralAccentColor, RadixThemesComponent
 
 
 class Slider(RadixThemesComponent):
 class Slider(RadixThemesComponent):
     def get_event_triggers(self) -> Dict[str, Any]: ...
     def get_event_triggers(self) -> Dict[str, Any]: ...
@@ -96,8 +96,7 @@ class Slider(RadixThemesComponent):
         high_contrast: Optional[Union[Var[bool], bool]] = None,
         high_contrast: Optional[Union[Var[bool], bool]] = None,
         radius: Optional[
         radius: Optional[
             Union[
             Union[
-                Var[Literal["none", "small", "medium", "large", "full"]],
-                Literal["none", "small", "medium", "large", "full"],
+                Var[Literal["none", "small", "full"]], Literal["none", "small", "full"]
             ]
             ]
         ] = None,
         ] = None,
         default_value: Optional[
         default_value: Optional[
@@ -190,7 +189,7 @@ class Slider(RadixThemesComponent):
             variant: Variant of button
             variant: Variant of button
             color_scheme: Override theme color for button
             color_scheme: Override theme color for button
             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"
+            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.
             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.
             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.
             name: The name of the slider. Submitted with its owning form as part of a name/value pair.

+ 5 - 7
reflex/components/radix/themes/components/switch.py

@@ -6,12 +6,10 @@ from reflex.vars import Var
 
 
 from ..base import (
 from ..base import (
     LiteralAccentColor,
     LiteralAccentColor,
-    LiteralRadius,
-    LiteralVariant,
     RadixThemesComponent,
     RadixThemesComponent,
 )
 )
 
 
-LiteralSwitchSize = Literal["1", "2", "3", "4"]
+LiteralSwitchSize = Literal["1", "2", "3"]
 
 
 
 
 class Switch(RadixThemesComponent):
 class Switch(RadixThemesComponent):
@@ -43,8 +41,8 @@ class Switch(RadixThemesComponent):
     # Switch size "1" - "4"
     # Switch size "1" - "4"
     size: Var[LiteralSwitchSize]
     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
     # Override theme color for switch
     color_scheme: Var[LiteralAccentColor]
     color_scheme: Var[LiteralAccentColor]
@@ -52,8 +50,8 @@ class Switch(RadixThemesComponent):
     # Whether to render the switch with higher contrast color against background
     # Whether to render the switch with higher contrast color against background
     high_contrast: Var[bool]
     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
     # Props to rename
     _rename_props = {"onChange": "onCheckedChange"}
     _rename_props = {"onChange": "onCheckedChange"}

+ 8 - 14
reflex/components/radix/themes/components/switch.pyi

@@ -10,14 +10,9 @@ from reflex.style import Style
 from typing import Any, Dict, Literal
 from typing import Any, Dict, Literal
 from reflex.constants import EventTriggers
 from reflex.constants import EventTriggers
 from reflex.vars import Var
 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):
 class Switch(RadixThemesComponent):
     def get_event_triggers(self) -> Dict[str, Any]: ...
     def get_event_triggers(self) -> Dict[str, Any]: ...
@@ -97,19 +92,18 @@ class Switch(RadixThemesComponent):
         name: Optional[Union[Var[str], str]] = None,
         name: Optional[Union[Var[str], str]] = None,
         value: Optional[Union[Var[str], str]] = None,
         value: Optional[Union[Var[str], str]] = None,
         size: Optional[
         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,
         ] = None,
         variant: Optional[
         variant: Optional[
             Union[
             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,
         ] = None,
         high_contrast: Optional[Union[Var[bool], bool]] = None,
         high_contrast: Optional[Union[Var[bool], bool]] = None,
         radius: Optional[
         radius: Optional[
             Union[
             Union[
-                Var[Literal["none", "small", "medium", "large", "full"]],
-                Literal["none", "small", "medium", "large", "full"],
+                Var[Literal["none", "small", "full"]], Literal["none", "small", "full"]
             ]
             ]
         ] = None,
         ] = None,
         style: Optional[Style] = None,
         style: Optional[Style] = None,
@@ -186,9 +180,9 @@ class Switch(RadixThemesComponent):
             name: The name of the switch (when submitting a form)
             name: The name of the switch (when submitting a form)
             value: The value associated with the "on" position
             value: The value associated with the "on" position
             size: Switch size "1" - "4"
             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
             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.
             style: Props to rename  The style of the component.
             key: A unique key for the component.
             key: A unique key for the component.
             id: The id for the component.
             id: The id for the component.

+ 3 - 3
reflex/components/radix/themes/components/tabs.py

@@ -15,9 +15,6 @@ class TabsRoot(RadixThemesComponent):
 
 
     tag = "Tabs.Root"
     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.
     # 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]
     default_value: Var[str]
 
 
@@ -47,6 +44,9 @@ class TabsList(RadixThemesComponent):
 
 
     tag = "Tabs.List"
     tag = "Tabs.List"
 
 
+    # Tabs size "1" - "2"
+    size: Var[Literal["1", "2"]]
+
 
 
 class TabsTrigger(RadixThemesComponent):
 class TabsTrigger(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."""

+ 2 - 4
reflex/components/radix/themes/components/tabs.pyi

@@ -83,9 +83,6 @@ class TabsRoot(RadixThemesComponent):
                 ],
                 ],
             ]
             ]
         ] = None,
         ] = None,
-        variant: Optional[
-            Union[Var[Literal["surface", "ghost"]], Literal["surface", "ghost"]]
-        ] = None,
         default_value: Optional[Union[Var[str], str]] = None,
         default_value: Optional[Union[Var[str], str]] = None,
         value: Optional[Union[Var[str], str]] = None,
         value: Optional[Union[Var[str], str]] = None,
         orientation: Optional[
         orientation: Optional[
@@ -160,7 +157,6 @@ class TabsRoot(RadixThemesComponent):
             *children: Child components.
             *children: Child components.
             color: map to CSS default color property.
             color: map to CSS default color property.
             color_scheme: map to radix 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.
             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.
             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.
             orientation: The orientation of the tabs.
@@ -247,6 +243,7 @@ class TabsList(RadixThemesComponent):
                 ],
                 ],
             ]
             ]
         ] = None,
         ] = None,
+        size: Optional[Union[Var[Literal["1", "2"]], Literal["1", "2"]]] = None,
         style: Optional[Style] = None,
         style: Optional[Style] = None,
         key: Optional[Any] = None,
         key: Optional[Any] = None,
         id: Optional[Any] = None,
         id: Optional[Any] = None,
@@ -310,6 +307,7 @@ class TabsList(RadixThemesComponent):
             *children: Child components.
             *children: Child components.
             color: map to CSS default color property.
             color: map to CSS default color property.
             color_scheme: map to radix color property.
             color_scheme: map to radix color property.
+            size: Tabs size "1" - "2"
             style: The style of the component.
             style: The style of the component.
             key: A unique key for the component.
             key: A unique key for the component.
             id: The id for the component.
             id: The id for the component.

+ 43 - 1
reflex/components/radix/themes/components/textarea.py

@@ -1,5 +1,5 @@
 """Interactive components provided by @radix-ui/themes."""
 """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 import el
 from reflex.components.component import Component
 from reflex.components.component import Component
@@ -29,6 +29,48 @@ class TextArea(RadixThemesComponent, el.Textarea):
     # The color of the text area
     # The color of the text area
     color_scheme: Var[LiteralAccentColor]
     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
     @classmethod
     def create(cls, *children, **props) -> Component:
     def create(cls, *children, **props) -> Component:
         """Create an Input component.
         """Create an Input component.

+ 16 - 36
reflex/components/radix/themes/components/textarea.pyi

@@ -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, Literal, Union
 from reflex import el
 from reflex import el
 from reflex.components.component import Component
 from reflex.components.component import Component
 from reflex.components.core.debounce import DebounceInput
 from reflex.components.core.debounce import DebounceInput
@@ -94,41 +94,21 @@ class TextArea(RadixThemesComponent, el.Textarea):
                 ],
                 ],
             ]
             ]
         ] = None,
         ] = 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,
         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[
         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,
@@ -244,7 +224,6 @@ class TextArea(RadixThemesComponent, el.Textarea):
             color_scheme: The color of the text area
             color_scheme: The color of the text area
             auto_complete: Whether the form control should have autocomplete enabled
             auto_complete: Whether the form control should have autocomplete enabled
             auto_focus: Automatically focuses the textarea when the page loads
             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
             dirname: Name part of the textarea to submit in 'dir' and 'name' pair when form is submitted
             disabled: Disables the textarea
             disabled: Disables the textarea
             form: Associates the textarea with a form (by id)
             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
             rows: Visible number of lines in the text control
             value: The controlled value of the textarea, read only unless used with on_change
             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
             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.
             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.

+ 0 - 4
reflex/components/radix/themes/components/textfield.py

@@ -14,7 +14,6 @@ from reflex.vars import Var
 from ..base import (
 from ..base import (
     LiteralAccentColor,
     LiteralAccentColor,
     LiteralRadius,
     LiteralRadius,
-    LiteralSize,
     RadixThemesComponent,
     RadixThemesComponent,
 )
 )
 
 
@@ -85,9 +84,6 @@ class TextFieldSlot(RadixThemesComponent):
     # Override theme color for text field slot
     # Override theme color for text field slot
     color_scheme: Var[LiteralAccentColor]
     color_scheme: Var[LiteralAccentColor]
 
 
-    # Override the gap spacing between slot and input: "1" - "9"
-    gap: Var[LiteralSize]
-
 
 
 class Input(RadixThemesComponent):
 class Input(RadixThemesComponent):
     """High level wrapper for the Input component."""
     """High level wrapper for the Input component."""

+ 1 - 8
reflex/components/radix/themes/components/textfield.pyi

@@ -16,7 +16,7 @@ from reflex.components.core.debounce import DebounceInput
 from reflex.components.lucide.icon import Icon
 from reflex.components.lucide.icon import Icon
 from reflex.constants import EventTriggers
 from reflex.constants import EventTriggers
 from reflex.vars import Var
 from reflex.vars import Var
-from ..base import LiteralAccentColor, LiteralRadius, LiteralSize, RadixThemesComponent
+from ..base import LiteralAccentColor, LiteralRadius, RadixThemesComponent
 
 
 LiteralTextFieldSize = Literal["1", "2", "3"]
 LiteralTextFieldSize = Literal["1", "2", "3"]
 LiteralTextFieldVariant = Literal["classic", "surface", "soft"]
 LiteralTextFieldVariant = Literal["classic", "surface", "soft"]
@@ -651,12 +651,6 @@ class TextFieldSlot(RadixThemesComponent):
                 ],
                 ],
             ]
             ]
         ] = None,
         ] = 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,
         style: Optional[Style] = None,
         key: Optional[Any] = None,
         key: Optional[Any] = None,
         id: Optional[Any] = None,
         id: Optional[Any] = None,
@@ -720,7 +714,6 @@ class TextFieldSlot(RadixThemesComponent):
             *children: Child components.
             *children: Child components.
             color: map to CSS default color property.
             color: map to CSS default color property.
             color_scheme: map to radix 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.
             style: The style of the component.
             key: A unique key for the component.
             key: A unique key for the component.
             id: The id for the component.
             id: The id for the component.

+ 5 - 1
reflex/components/radix/themes/typography/text.py

@@ -4,6 +4,8 @@ https://www.radix-ui.com/themes/docs/theme/typography
 """
 """
 from __future__ import annotations
 from __future__ import annotations
 
 
+from typing import Literal
+
 from reflex import el
 from reflex import el
 from reflex.vars import Var
 from reflex.vars import Var
 
 
@@ -18,6 +20,8 @@ from .base import (
     LiteralTextWeight,
     LiteralTextWeight,
 )
 )
 
 
+LiteralType = Literal["p", "label", "div", "span"]
+
 
 
 class Text(el.Span, RadixThemesComponent):
 class Text(el.Span, RadixThemesComponent):
     """A foundational text primitive based on the <span> element."""
     """A foundational text primitive based on the <span> element."""
@@ -28,7 +32,7 @@ class Text(el.Span, RadixThemesComponent):
     as_child: Var[bool]
     as_child: Var[bool]
 
 
     # Change the default rendered element into a semantically appropriate alternative (cannot be used with asChild)
     # 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"
     # Text size: "1" - "9"
     size: Var[LiteralTextSize]
     size: Var[LiteralTextSize]

+ 9 - 1
reflex/components/radix/themes/typography/text.pyi

@@ -7,11 +7,14 @@ 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 reflex import el
 from reflex import el
 from reflex.vars import Var
 from reflex.vars import Var
 from ..base import LiteralAccentColor, RadixThemesComponent
 from ..base import LiteralAccentColor, RadixThemesComponent
 from .base import LiteralTextAlign, LiteralTextSize, LiteralTextTrim, LiteralTextWeight
 from .base import LiteralTextAlign, LiteralTextSize, LiteralTextTrim, LiteralTextWeight
 
 
+LiteralType = Literal["p", "label", "div", "span"]
+
 class Text(el.Span, RadixThemesComponent):
 class Text(el.Span, RadixThemesComponent):
     @overload
     @overload
     @classmethod
     @classmethod
@@ -82,7 +85,12 @@ class Text(el.Span, RadixThemesComponent):
             ]
             ]
         ] = None,
         ] = None,
         as_child: Optional[Union[Var[bool], bool]] = 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[
         size: Optional[
             Union[
             Union[
                 Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]],
                 Var[Literal["1", "2", "3", "4", "5", "6", "7", "8", "9"]],

+ 75 - 6
reflex/state.py

@@ -332,9 +332,7 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
         }
         }
         cls.computed_vars = {
         cls.computed_vars = {
             v._var_name: v._var_set_state(cls)
             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)
             if isinstance(v, ComputedVar)
         }
         }
         cls.vars = {
         cls.vars = {
@@ -352,10 +350,29 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
         events = {
         events = {
             name: fn
             name: fn
             for name, fn in cls.__dict__.items()
             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():
         for name, fn in events.items():
             handler = EventHandler(fn=fn)
             handler = EventHandler(fn=fn)
             cls.event_handlers[name] = handler
             cls.event_handlers[name] = handler
@@ -363,6 +380,58 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
 
 
         cls._init_var_dependency_dicts()
         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
     @classmethod
     def _init_var_dependency_dicts(cls):
     def _init_var_dependency_dicts(cls):
         """Initialize the var dependency tracking dicts.
         """Initialize the var dependency tracking dicts.

+ 11 - 0
reflex/vars.pyi

@@ -19,6 +19,7 @@ from typing import (
     Set,
     Set,
     Type,
     Type,
     Union,
     Union,
+    overload,
     _GenericAlias,  # type: ignore
     _GenericAlias,  # type: ignore
 )
 )
 
 
@@ -136,6 +137,16 @@ class ComputedVar(Var):
     def _deps(self, objclass: Type, obj: Optional[FunctionType] = ...) -> Set[str]: ...
     def _deps(self, objclass: Type, obj: Optional[FunctionType] = ...) -> Set[str]: ...
     def mark_dirty(self, instance) -> None: ...
     def mark_dirty(self, instance) -> None: ...
     def _determine_var_type(self) -> Type: ...
     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 __init__(self, func) -> None: ...
 
 
 def cached_var(fget: Callable[[Any], Any]) -> ComputedVar: ...
 def cached_var(fget: Callable[[Any], Any]) -> ComputedVar: ...