From 625c5302dd19e886e5795ce9226b59ebe1a2310b Mon Sep 17 00:00:00 2001 From: Elijah Ahianyo Date: Thu, 12 Sep 2024 17:46:42 +0000 Subject: [PATCH] [REF-3562][REF-3563] Replace chakra usage (#3872) --- benchmarks/test_benchmark_compile_pages.py | 3 +- integration/test_background_task.py | 5 +- integration/test_client_storage.py | 10 +- integration/test_dynamic_routes.py | 12 +- integration/test_event_actions.py | 8 +- integration/test_event_chain.py | 6 +- integration/test_form_submit.py | 65 ++----- integration/test_server_side_event.py | 10 +- integration/test_table.py | 114 +++-------- integration/test_tailwind.py | 4 +- integration/test_upload.py | 4 +- integration/test_var_operations.py | 7 +- poetry.lock | 153 +++++++++++++-- pyproject.toml | 2 +- .../.templates/jinja/web/pages/_app.js.jinja2 | 2 +- .../reflex/chakra_color_mode_provider.js | 36 ---- reflex/__init__.pyi | 1 + reflex/components/radix/__init__.pyi | 1 + reflex/components/radix/themes/base.py | 20 -- reflex/components/radix/themes/base.pyi | 1 - .../radix/themes/layout/__init__.pyi | 1 + reflex/style.py | 1 - reflex/utils/pyi_generator.py | 8 +- tests/components/datadisplay/test_table.py | 177 ------------------ tests/components/forms/test_form.py | 3 +- tests/components/media/test_icon.py | 55 ------ tests/components/test_component.py | 7 +- tests/components/typography/test_markdown.py | 5 +- tests/test_app.py | 19 +- 29 files changed, 235 insertions(+), 505 deletions(-) delete mode 100644 reflex/.templates/web/components/reflex/chakra_color_mode_provider.js delete mode 100644 tests/components/datadisplay/test_table.py delete mode 100644 tests/components/media/test_icon.py diff --git a/benchmarks/test_benchmark_compile_pages.py b/benchmarks/test_benchmark_compile_pages.py index 33404bca7..4448bca45 100644 --- a/benchmarks/test_benchmark_compile_pages.py +++ b/benchmarks/test_benchmark_compile_pages.py @@ -130,7 +130,6 @@ def render_multiple_pages(app, num: int): def AppWithOnePage(): """A reflex app with one page.""" - import reflex_chakra as rc from rxconfig import config # type: ignore import reflex as rx @@ -145,7 +144,7 @@ def AppWithOnePage(): def index() -> rx.Component: return rx.center( - rc.input( + rx.input( id="token", value=State.router.session.client_token, is_read_only=True ), rx.vstack( diff --git a/integration/test_background_task.py b/integration/test_background_task.py index 3764f67b4..b97791b0a 100644 --- a/integration/test_background_task.py +++ b/integration/test_background_task.py @@ -13,7 +13,6 @@ def BackgroundTask(): import asyncio import pytest - import reflex_chakra as rc import reflex as rx from reflex.state import ImmutableStateError @@ -116,11 +115,11 @@ def BackgroundTask(): def index() -> rx.Component: return rx.vstack( - rc.input( + rx.input( id="token", value=State.router.session.client_token, is_read_only=True ), rx.heading(State.counter, id="counter"), - rc.input( + rx.input( id="iterations", placeholder="Iterations", value=State.iterations.to_string(), # type: ignore diff --git a/integration/test_client_storage.py b/integration/test_client_storage.py index e88d2fa14..e4a38a15b 100644 --- a/integration/test_client_storage.py +++ b/integration/test_client_storage.py @@ -17,8 +17,6 @@ from . import utils def ClientSide(): """App for testing client-side state.""" - import reflex_chakra as rc - import reflex as rx class ClientSideState(rx.State): @@ -72,18 +70,18 @@ def ClientSide(): def index(): return rx.fragment( - rc.input( + rx.input( value=ClientSideState.router.session.client_token, is_read_only=True, id="token", ), - rc.input( + rx.input( placeholder="state var", value=ClientSideState.state_var, on_change=ClientSideState.set_state_var, # type: ignore id="state_var", ), - rc.input( + rx.input( placeholder="input value", value=ClientSideState.input_value, on_change=ClientSideState.set_input_value, # type: ignore @@ -313,7 +311,6 @@ async def test_client_side_state( # no cookies should be set yet! assert not driver.get_cookies() local_storage_items = local_storage.items() - local_storage_items.pop("chakra-ui-color-mode", None) local_storage_items.pop("last_compiled_time", None) assert not local_storage_items @@ -429,7 +426,6 @@ async def test_client_side_state( assert f"{sub_state_name}.c3" not in cookie_info_map(driver) local_storage_items = local_storage.items() - local_storage_items.pop("chakra-ui-color-mode", None) local_storage_items.pop("last_compiled_time", None) assert local_storage_items.pop(f"{sub_state_name}.l1") == "l1 value" assert local_storage_items.pop(f"{sub_state_name}.l2") == "l2 value" diff --git a/integration/test_dynamic_routes.py b/integration/test_dynamic_routes.py index 235232461..dc75eac6f 100644 --- a/integration/test_dynamic_routes.py +++ b/integration/test_dynamic_routes.py @@ -17,8 +17,6 @@ def DynamicRoute(): """App for testing dynamic routes.""" from typing import List - import reflex_chakra as rc - import reflex as rx class DynamicState(rx.State): @@ -41,13 +39,13 @@ def DynamicRoute(): def index(): return rx.fragment( - rc.input( + rx.input( value=DynamicState.router.session.client_token, is_read_only=True, id="token", ), - rc.input(value=rx.State.page_id, is_read_only=True, id="page_id"), # type: ignore - rc.input( + rx.input(value=rx.State.page_id, is_read_only=True, id="page_id"), # type: ignore + rx.input( value=DynamicState.router.page.raw_path, is_read_only=True, id="raw_path", @@ -60,10 +58,10 @@ def DynamicRoute(): id="link_page_next", # type: ignore ), rx.link("missing", href="/missing", id="link_missing"), - rc.list( + rx.list( # type: ignore rx.foreach( DynamicState.order, # type: ignore - lambda i: rc.list_item(rx.text(i)), + lambda i: rx.list_item(rx.text(i)), ), ), ) diff --git a/integration/test_event_actions.py b/integration/test_event_actions.py index 5845d80f1..499478a1c 100644 --- a/integration/test_event_actions.py +++ b/integration/test_event_actions.py @@ -16,8 +16,6 @@ def TestEventAction(): """App for testing event_actions.""" from typing import List, Optional - import reflex_chakra as rc - import reflex as rx class EventActionState(rx.State): @@ -55,7 +53,7 @@ def TestEventAction(): def index(): return rx.vstack( - rc.input( + rx.input( value=EventActionState.router.session.client_token, is_read_only=True, id="token", @@ -148,10 +146,10 @@ def TestEventAction(): 200 ).stop_propagation, ), - rc.list( + rx.list( # type: ignore rx.foreach( EventActionState.order, # type: ignore - rc.list_item, + rx.list_item, ), ), on_click=EventActionState.on_click("outer"), # type: ignore diff --git a/integration/test_event_chain.py b/integration/test_event_chain.py index cdef575a1..740fc71a3 100644 --- a/integration/test_event_chain.py +++ b/integration/test_event_chain.py @@ -18,8 +18,6 @@ def EventChain(): import time from typing import List - import reflex_chakra as rc - import reflex as rx # repeated here since the outer global isn't exported into the App module @@ -129,7 +127,7 @@ def EventChain(): app = rx.App(state=rx.State) - token_input = rc.input( + token_input = rx.input( value=State.router.session.client_token, is_read_only=True, id="token" ) @@ -137,7 +135,7 @@ def EventChain(): def index(): return rx.fragment( token_input, - rc.input(value=State.interim_value, is_read_only=True, id="interim_value"), + rx.input(value=State.interim_value, is_read_only=True, id="interim_value"), rx.button( "Return Event", id="return_event", diff --git a/integration/test_form_submit.py b/integration/test_form_submit.py index acc6bca96..a020a7e15 100644 --- a/integration/test_form_submit.py +++ b/integration/test_form_submit.py @@ -20,8 +20,6 @@ def FormSubmit(form_component): """ from typing import Dict, List - import reflex_chakra as rc - import reflex as rx class FormState(rx.State): @@ -37,28 +35,29 @@ def FormSubmit(form_component): @app.add_page def index(): return rx.vstack( - rc.input( + rx.input( value=FormState.router.session.client_token, is_read_only=True, id="token", ), eval(form_component)( rx.vstack( - rc.input(id="name_input"), - rx.hstack(rc.pin_input(length=4, id="pin_input")), - rc.number_input(id="number_input"), + rx.input(id="name_input"), rx.checkbox(id="bool_input"), rx.switch(id="bool_input2"), rx.checkbox(id="bool_input3"), rx.switch(id="bool_input4"), rx.slider(id="slider_input", default_value=[50], width="100%"), - rc.range_slider(id="range_input"), rx.radio(["option1", "option2"], id="radio_input"), rx.radio(FormState.var_options, id="radio_input_var"), - rc.select(["option1", "option2"], id="select_input"), - rc.select(FormState.var_options, id="select_input_var"), + rx.select( + ["option1", "option2"], + name="select_input", + default_value="option1", + ), + rx.select(FormState.var_options, id="select_input_var"), rx.text_area(id="text_area_input"), - rc.input( + rx.input( id="debounce_input", debounce_timeout=0, on_change=rx.console_log, @@ -81,8 +80,6 @@ def FormSubmitName(form_component): """ from typing import Dict, List - import reflex_chakra as rc - import reflex as rx class FormState(rx.State): @@ -98,22 +95,19 @@ def FormSubmitName(form_component): @app.add_page def index(): return rx.vstack( - rc.input( + rx.input( value=FormState.router.session.client_token, is_read_only=True, id="token", ), eval(form_component)( rx.vstack( - rc.input(name="name_input"), - rx.hstack(rc.pin_input(length=4, name="pin_input")), - rc.number_input(name="number_input"), + rx.input(name="name_input"), rx.checkbox(name="bool_input"), rx.switch(name="bool_input2"), rx.checkbox(name="bool_input3"), rx.switch(name="bool_input4"), rx.slider(name="slider_input", default_value=[50], width="100%"), - rc.range_slider(name="range_input"), rx.radio(FormState.options, name="radio_input"), rx.select( FormState.options, @@ -121,21 +115,13 @@ def FormSubmitName(form_component): default_value=FormState.options[0], ), rx.text_area(name="text_area_input"), - rc.input_group( - rc.input_left_element(rx.icon(tag="chevron_right")), - rc.input( - name="debounce_input", - debounce_timeout=0, - on_change=rx.console_log, - ), - rc.input_right_element(rx.icon(tag="chevron_left")), - ), - rc.button_group( - rx.button("Submit", type_="submit"), - rx.icon_button(FormState.val, icon=rx.icon(tag="plus")), - variant="outline", - is_attached=True, + rx.input( + name="debounce_input", + debounce_timeout=0, + on_change=rx.console_log, ), + rx.button("Submit", type_="submit"), + rx.icon_button(FormState.val, icon=rx.icon(tag="plus")), ), on_submit=FormState.form_submit, custom_attrs={"action": "/invalid"}, @@ -152,16 +138,12 @@ def FormSubmitName(form_component): functools.partial(FormSubmitName, form_component="rx.form.root"), functools.partial(FormSubmit, form_component="rx.el.form"), functools.partial(FormSubmitName, form_component="rx.el.form"), - functools.partial(FormSubmit, form_component="rc.form"), - functools.partial(FormSubmitName, form_component="rc.form"), ], ids=[ "id-radix", "name-radix", "id-html", "name-html", - "id-chakra", - "name-chakra", ], ) def form_submit(request, tmp_path_factory) -> Generator[AppHarness, None, None]: @@ -224,16 +206,6 @@ async def test_submit(driver, form_submit: AppHarness): name_input = driver.find_element(by, "name_input") name_input.send_keys("foo") - pin_inputs = driver.find_elements(By.CLASS_NAME, "chakra-pin-input") - pin_values = ["8", "1", "6", "4"] - for i, pin_input in enumerate(pin_inputs): - pin_input.send_keys(pin_values[i]) - - number_input = driver.find_element(By.CLASS_NAME, "chakra-numberinput") - buttons = number_input.find_elements(By.XPATH, "//div[@role='button']") - for _ in range(3): - buttons[1].click() - checkbox_input = driver.find_element(By.XPATH, "//button[@role='checkbox']") checkbox_input.click() @@ -275,15 +247,12 @@ async def test_submit(driver, form_submit: AppHarness): print(form_data) assert form_data["name_input"] == "foo" - assert form_data["pin_input"] == pin_values - assert form_data["number_input"] == "-3" assert form_data["bool_input"] assert form_data["bool_input2"] assert not form_data.get("bool_input3", False) assert not form_data.get("bool_input4", False) assert form_data["slider_input"] == "50" - assert form_data["range_input"] == ["25", "75"] assert form_data["radio_input"] == "option2" assert form_data["select_input"] == "option1" assert form_data["text_area_input"] == "Some\nText" diff --git a/integration/test_server_side_event.py b/integration/test_server_side_event.py index 8687b0f32..ee5e8dbc0 100644 --- a/integration/test_server_side_event.py +++ b/integration/test_server_side_event.py @@ -11,8 +11,6 @@ from reflex.testing import AppHarness def ServerSideEvent(): """App with inputs set via event handlers and set_value.""" - import reflex_chakra as rc - import reflex as rx class SSState(rx.State): @@ -41,12 +39,12 @@ def ServerSideEvent(): @app.add_page def index(): return rx.fragment( - rc.input( + rx.input( id="token", value=SSState.router.session.client_token, is_read_only=True ), - rc.input(default_value="a", id="a"), - rc.input(default_value="b", id="b"), - rc.input(default_value="c", id="c"), + rx.input(default_value="a", id="a"), + rx.input(default_value="b", id="b"), + rx.input(default_value="c", id="c"), rx.button( "Clear Immediate", id="clear_immediate", diff --git a/integration/test_table.py b/integration/test_table.py index d28798a98..09004a874 100644 --- a/integration/test_table.py +++ b/integration/test_table.py @@ -10,91 +10,47 @@ from reflex.testing import AppHarness def Table(): """App using table component.""" - from typing import List - - import reflex_chakra as rc - import reflex as rx - class TableState(rx.State): - rows: List[List[str]] = [ - ["John", "30", "New York"], - ["Jane", "31", "San Fransisco"], - ["Joe", "32", "Los Angeles"], - ] - - headers: List[str] = ["Name", "Age", "Location"] - - footers: List[str] = ["footer1", "footer2", "footer3"] - - caption: str = "random caption" - app = rx.App(state=rx.State) @app.add_page def index(): return rx.center( - rc.input( + rx.input( id="token", - value=TableState.router.session.client_token, + value=rx.State.router.session.client_token, is_read_only=True, ), - rc.table_container( - rc.table( - headers=TableState.headers, - rows=TableState.rows, - footers=TableState.footers, - caption=TableState.caption, - variant="striped", - color_scheme="blue", - width="100%", + rx.table.root( + rx.table.header( + rx.table.row( + rx.table.column_header_cell("Name"), + rx.table.column_header_cell("Age"), + rx.table.column_header_cell("Location"), + ), ), + rx.table.body( + rx.table.row( + rx.table.row_header_cell("John"), + rx.table.cell(30), + rx.table.cell("New York"), + ), + rx.table.row( + rx.table.row_header_cell("Jane"), + rx.table.cell(31), + rx.table.cell("San Fransisco"), + ), + rx.table.row( + rx.table.row_header_cell("Joe"), + rx.table.cell(32), + rx.table.cell("Los Angeles"), + ), + ), + width="100%", ), ) - @app.add_page - def another(): - return rx.center( - rc.table_container( - rc.table( # type: ignore - rc.thead( # type: ignore - rc.tr( # type: ignore - rc.th("Name"), - rc.th("Age"), - rc.th("Location"), - ) - ), - rc.tbody( # type: ignore - rc.tr( # type: ignore - rc.td("John"), - rc.td(30), - rc.td("New York"), - ), - rc.tr( # type: ignore - rc.td("Jane"), - rc.td(31), - rc.td("San Francisco"), - ), - rc.tr( # type: ignore - rc.td("Joe"), - rc.td(32), - rc.td("Los Angeles"), - ), - ), - rc.tfoot( # type: ignore - rc.tr( - rc.td("footer1"), - rc.td("footer2"), - rc.td("footer3"), - ) # type: ignore - ), - rc.table_caption("random caption"), - variant="striped", - color_scheme="teal", - ) - ) - ) - @pytest.fixture() def table(tmp_path_factory) -> Generator[AppHarness, None, None]: @@ -138,23 +94,20 @@ def driver(table: AppHarness): driver.quit() -@pytest.mark.parametrize("route", ["", "/another"]) -def test_table(driver, table: AppHarness, route): +def test_table(driver, table: AppHarness): """Test that a table component is rendered properly. Args: driver: Selenium WebDriver open to the app table: Harness for Table app - route: Page route or path. """ - driver.get(f"{table.frontend_url}/{route}") assert table.app_instance is not None, "app is not running" thead = driver.find_element(By.TAG_NAME, "thead") # poll till page is fully loaded. table.poll_for_content(element=thead) # check headers - assert thead.find_element(By.TAG_NAME, "tr").text == "NAME AGE LOCATION" + assert thead.find_element(By.TAG_NAME, "tr").text == "Name Age Location" # check first row value assert ( driver.find_element(By.TAG_NAME, "tbody") @@ -162,12 +115,3 @@ def test_table(driver, table: AppHarness, route): .text == "John 30 New York" ) - # check footer - assert ( - driver.find_element(By.TAG_NAME, "tfoot") - .find_element(By.TAG_NAME, "tr") - .text.lower() - == "footer1 footer2 footer3" - ) - # check caption - assert driver.find_element(By.TAG_NAME, "caption").text == "random caption" diff --git a/integration/test_tailwind.py b/integration/test_tailwind.py index 491eba538..bda664a1c 100644 --- a/integration/test_tailwind.py +++ b/integration/test_tailwind.py @@ -27,8 +27,6 @@ def TailwindApp( """ from pathlib import Path - import reflex_chakra as rc - import reflex as rx class UnusedState(rx.State): @@ -36,7 +34,7 @@ def TailwindApp( def index(): return rx.el.div( - rc.text(paragraph_text, class_name=paragraph_class_name), + rx.text(paragraph_text, class_name=paragraph_class_name), rx.el.p(paragraph_text, class_name=paragraph_class_name), rx.text(paragraph_text, as_="p", class_name=paragraph_class_name), rx.el.div("Test external stylesheet", class_name="external"), diff --git a/integration/test_upload.py b/integration/test_upload.py index 1f8b39efc..813313462 100644 --- a/integration/test_upload.py +++ b/integration/test_upload.py @@ -16,8 +16,6 @@ def UploadFile(): """App for testing dynamic routes.""" from typing import Dict, List - import reflex_chakra as rc - import reflex as rx class UploadState(rx.State): @@ -46,7 +44,7 @@ def UploadFile(): def index(): return rx.vstack( - rc.input( + rx.input( value=UploadState.router.session.client_token, is_read_only=True, id="token", diff --git a/integration/test_var_operations.py b/integration/test_var_operations.py index 2feb80ae0..3542bdf39 100644 --- a/integration/test_var_operations.py +++ b/integration/test_var_operations.py @@ -14,8 +14,6 @@ def VarOperations(): """App with var operations.""" from typing import Dict, List - import reflex_chakra as rc - import reflex as rx from reflex.ivars.base import LiteralVar from reflex.ivars.sequence import ArrayVar @@ -552,10 +550,7 @@ def VarOperations(): VarOperationState.html_str, id="html_str", ), - rc.highlight( - "second", - query=[VarOperationState.str_var2], - ), + rx.el.mark("second"), rx.text(ArrayVar.range(2, 5).join(","), id="list_join_range1"), rx.text(ArrayVar.range(2, 10, 2).join(","), id="list_join_range2"), rx.text(ArrayVar.range(5, 0, -1).join(","), id="list_join_range3"), diff --git a/poetry.lock b/poetry.lock index 6604a361a..6fe39acc4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,9 +1,10 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. [[package]] name = "alembic" version = "1.13.2" description = "A database migration tool for SQLAlchemy." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -25,6 +26,7 @@ tz = ["backports.zoneinfo"] name = "annotated-types" version = "0.7.0" description = "Reusable constraint types to use with typing.Annotated" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -39,6 +41,7 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} name = "anyio" version = "4.4.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -61,6 +64,7 @@ trio = ["trio (>=0.23)"] name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -72,6 +76,7 @@ files = [ name = "asynctest" version = "0.13.0" description = "Enhance the standard unittest package with features for testing asyncio libraries" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -83,6 +88,7 @@ files = [ name = "attrs" version = "24.2.0" description = "Classes Without Boilerplate" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -102,6 +108,7 @@ tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] name = "backports-tarfile" version = "1.2.0" description = "Backport of CPython tarfile module" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -117,6 +124,7 @@ testing = ["jaraco.test", "pytest (!=8.0.*)", "pytest (>=6,!=8.1.*)", "pytest-ch name = "bidict" version = "0.23.1" description = "The bidirectional mapping library for Python." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -128,6 +136,7 @@ files = [ name = "build" version = "1.2.2" description = "A simple, correct Python build frontend" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -153,6 +162,7 @@ virtualenv = ["virtualenv (>=20.0.35)"] name = "certifi" version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -164,6 +174,7 @@ files = [ name = "cffi" version = "1.17.1" description = "Foreign Function Interface for Python calling C code." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -243,6 +254,7 @@ pycparser = "*" name = "cfgv" version = "3.4.0" description = "Validate configuration and produce human readable error messages." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -254,6 +266,7 @@ files = [ name = "charset-normalizer" version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -353,6 +366,7 @@ files = [ name = "click" version = "8.1.7" description = "Composable command line interface toolkit" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -367,6 +381,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -378,6 +393,7 @@ files = [ name = "coverage" version = "7.6.1" description = "Code coverage measurement for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -465,6 +481,7 @@ toml = ["tomli"] name = "cryptography" version = "43.0.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -514,6 +531,7 @@ test-randomorder = ["pytest-randomly"] name = "darglint" version = "1.8.1" description = "A utility for ensuring Google-style docstrings stay up to date with the source code." +category = "dev" optional = false python-versions = ">=3.6,<4.0" files = [ @@ -525,6 +543,7 @@ files = [ name = "dill" version = "0.3.8" description = "serialize all of Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -540,6 +559,7 @@ profile = ["gprof2dot (>=2022.7.29)"] name = "distlib" version = "0.3.8" description = "Distribution utilities" +category = "dev" optional = false python-versions = "*" files = [ @@ -551,6 +571,7 @@ files = [ name = "distro" version = "1.9.0" description = "Distro - an OS platform information API" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -562,14 +583,19 @@ files = [ name = "docutils" version = "0.20.1" description = "Docutils -- Python Documentation Utilities" +category = "main" optional = false -python-versions = "*" -files = [] +python-versions = ">=3.7" +files = [ + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, +] [[package]] name = "exceptiongroup" version = "1.2.2" description = "Backport of PEP 654 (exception groups)" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -584,6 +610,7 @@ test = ["pytest (>=6)"] name = "fastapi" version = "0.114.0" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -604,6 +631,7 @@ standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "htt name = "filelock" version = "3.15.4" description = "A platform independent file lock." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -620,6 +648,7 @@ typing = ["typing-extensions (>=4.8)"] name = "greenlet" version = "3.0.3" description = "Lightweight in-process concurrent programming" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -691,6 +720,7 @@ test = ["objgraph", "psutil"] name = "gunicorn" version = "23.0.0" description = "WSGI HTTP Server for UNIX" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -712,6 +742,7 @@ tornado = ["tornado (>=0.2)"] name = "h11" version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -723,6 +754,7 @@ files = [ name = "httpcore" version = "1.0.5" description = "A minimal low-level HTTP client." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -737,13 +769,14 @@ h11 = ">=0.13,<0.15" [package.extras] asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] trio = ["trio (>=0.22.0,<0.26.0)"] [[package]] name = "httpx" version = "0.27.2" description = "The next generation HTTP client." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -754,21 +787,22 @@ files = [ [package.dependencies] anyio = "*" certifi = "*" -httpcore = "==1.*" +httpcore = ">=1.0.0,<2.0.0" idna = "*" sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] zstd = ["zstandard (>=0.18.0)"] [[package]] name = "identify" version = "2.6.0" description = "File identification library for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -783,6 +817,7 @@ license = ["ukkonen"] name = "idna" version = "3.8" description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -794,6 +829,7 @@ files = [ name = "importlib-metadata" version = "8.4.0" description = "Read metadata from Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -813,6 +849,7 @@ test = ["flufl.flake8", "importlib-resources (>=1.3)", "jaraco.test (>=5.4)", "p name = "importlib-resources" version = "6.4.4" description = "Read resources from Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -835,6 +872,7 @@ type = ["pytest-mypy"] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -846,6 +884,7 @@ files = [ name = "jaraco-classes" version = "3.4.0" description = "Utility functions for Python class constructs" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -864,6 +903,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-ena name = "jaraco-context" version = "6.0.1" description = "Useful decorators and context managers" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -882,6 +922,7 @@ test = ["portend", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-c name = "jaraco-functools" version = "4.0.2" description = "Functools like those found in stdlib" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -900,6 +941,7 @@ test = ["jaraco.classes", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "p name = "jeepney" version = "0.8.0" description = "Low-level, pure Python DBus protocol wrapper." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -915,6 +957,7 @@ trio = ["async_generator", "trio"] name = "jinja2" version = "3.1.4" description = "A very fast and expressive template engine." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -932,6 +975,7 @@ i18n = ["Babel (>=2.7)"] name = "keyring" version = "25.3.0" description = "Store and access your passwords safely." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -958,6 +1002,7 @@ test = ["pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest- name = "lazy-loader" version = "0.4" description = "Makes it easy to load subpackages and functions on demand." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -977,6 +1022,7 @@ test = ["pytest (>=7.4)", "pytest-cov (>=4.1)"] name = "mako" version = "1.3.5" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -996,6 +1042,7 @@ testing = ["pytest"] name = "markdown-it-py" version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1020,6 +1067,7 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "markupsafe" version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1089,6 +1137,7 @@ files = [ name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1100,6 +1149,7 @@ files = [ name = "more-itertools" version = "10.5.0" description = "More routines for operating on iterables, beyond itertools" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1111,6 +1161,7 @@ files = [ name = "nh3" version = "0.2.18" description = "Python bindings to the ammonia HTML sanitization library." +category = "main" optional = false python-versions = "*" files = [ @@ -1136,6 +1187,7 @@ files = [ name = "nodeenv" version = "1.9.1" description = "Node.js virtual environment builder" +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -1147,6 +1199,7 @@ files = [ name = "numpy" version = "1.24.4" description = "Fundamental package for array computing in Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1184,6 +1237,7 @@ files = [ name = "numpy" version = "2.0.2" description = "Fundamental package for array computing in Python" +category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -1238,6 +1292,7 @@ files = [ name = "numpy" version = "2.1.1" description = "Fundamental package for array computing in Python" +category = "dev" optional = false python-versions = ">=3.10" files = [ @@ -1300,6 +1355,7 @@ files = [ name = "outcome" version = "1.3.0.post0" description = "Capture the outcome of Python function calls." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1314,6 +1370,7 @@ attrs = ">=19.2.0" name = "packaging" version = "24.1" description = "Core utilities for Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1325,6 +1382,7 @@ files = [ name = "pandas" version = "1.5.3" description = "Powerful data structures for data analysis, time series, and statistics" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1369,6 +1427,7 @@ test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] name = "pandas" version = "2.2.2" description = "Powerful data structures for data analysis, time series, and statistics" +category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -1442,6 +1501,7 @@ xml = ["lxml (>=4.9.2)"] name = "pillow" version = "10.4.0" description = "Python Imaging Library (Fork)" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1539,6 +1599,7 @@ xmp = ["defusedxml"] name = "pip" version = "24.2" description = "The PyPA recommended tool for installing Python packages." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1550,6 +1611,7 @@ files = [ name = "pipdeptree" version = "2.16.2" description = "Command line utility to show dependency tree of packages." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1568,6 +1630,7 @@ test = ["covdefaults (>=2.3)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pyte name = "pkginfo" version = "1.10.0" description = "Query metadata from sdists / bdists / installed packages." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1582,6 +1645,7 @@ testing = ["pytest", "pytest-cov", "wheel"] name = "platformdirs" version = "4.2.2" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1598,6 +1662,7 @@ type = ["mypy (>=1.8)"] name = "plotly" version = "5.24.0" description = "An open-source, interactive data visualization library for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1613,6 +1678,7 @@ tenacity = ">=6.2.0" name = "pluggy" version = "1.5.0" description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1628,6 +1694,7 @@ testing = ["pytest", "pytest-benchmark"] name = "pre-commit" version = "3.5.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1646,6 +1713,7 @@ virtualenv = ">=20.10.0" name = "psutil" version = "6.0.0" description = "Cross-platform lib for process and system monitoring in Python." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -1675,6 +1743,7 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "py-cpuinfo" version = "9.0.0" description = "Get CPU info with pure Python" +category = "dev" optional = false python-versions = "*" files = [ @@ -1686,6 +1755,7 @@ files = [ name = "pycparser" version = "2.22" description = "C parser in Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1697,6 +1767,7 @@ files = [ name = "pydantic" version = "2.9.0" description = "Data validation using Python type hints" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1720,6 +1791,7 @@ email = ["email-validator (>=2.0.0)"] name = "pydantic-core" version = "2.23.2" description = "Core functionality for Pydantic validation and serialization" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1821,6 +1893,7 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" name = "pygments" version = "2.18.0" description = "Pygments is a syntax highlighting package written in Python." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1835,6 +1908,7 @@ windows-terminal = ["colorama (>=0.4.6)"] name = "pyproject-hooks" version = "1.1.0" description = "Wrappers to call pyproject.toml-based build backend hooks." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1846,6 +1920,7 @@ files = [ name = "pyright" version = "1.1.334" description = "Command line wrapper for pyright" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1864,6 +1939,7 @@ dev = ["twine (>=3.4.1)"] name = "pysocks" version = "1.7.1" description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1876,6 +1952,7 @@ files = [ name = "pytest" version = "7.4.4" description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1898,6 +1975,7 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-asyncio" version = "0.21.2" description = "Pytest support for asyncio" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1916,6 +1994,7 @@ testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy name = "pytest-benchmark" version = "4.0.0" description = "A ``pytest`` fixture for benchmarking code. It will group the tests into rounds that are calibrated to the chosen timer." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1936,6 +2015,7 @@ histogram = ["pygal", "pygaljs"] name = "pytest-cov" version = "4.1.0" description = "Pytest plugin for measuring coverage." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1954,6 +2034,7 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-mock" version = "3.14.0" description = "Thin-wrapper around the mock package for easier use with pytest" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1971,6 +2052,7 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] name = "python-dateutil" version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -1985,6 +2067,7 @@ six = ">=1.5" name = "python-engineio" version = "4.9.1" description = "Engine.IO server and client for Python" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2004,6 +2087,7 @@ docs = ["sphinx"] name = "python-multipart" version = "0.0.9" description = "A streaming multipart parser for Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2018,6 +2102,7 @@ dev = ["atomicwrites (==1.4.1)", "attrs (==23.2.0)", "coverage (==7.4.1)", "hatc name = "python-socketio" version = "5.11.4" description = "Socket.IO server and client for Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2038,6 +2123,7 @@ docs = ["sphinx"] name = "pytz" version = "2024.1" description = "World timezone definitions, modern and historical" +category = "dev" optional = false python-versions = "*" files = [ @@ -2049,6 +2135,7 @@ files = [ name = "pywin32-ctypes" version = "0.2.3" description = "A (partial) reimplementation of pywin32 using ctypes/cffi" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2060,6 +2147,7 @@ files = [ name = "pyyaml" version = "6.0.2" description = "YAML parser and emitter for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2122,6 +2210,7 @@ files = [ name = "readme-renderer" version = "43.0" description = "readme_renderer is a library for rendering readme descriptions for Warehouse" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2141,6 +2230,7 @@ md = ["cmarkgfm (>=0.8.0)"] name = "redis" version = "5.0.8" description = "Python client for Redis database and key-value store" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2157,13 +2247,14 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" [[package]] name = "reflex-chakra" -version = "0.6.0a5" +version = "0.6.0a6" description = "reflex using chakra components" +category = "main" optional = false python-versions = "<4.0,>=3.8" files = [ - {file = "reflex_chakra-0.6.0a5-py3-none-any.whl", hash = "sha256:9d502ddf3bd606baef4f0ff6453dcefb5e19dab4cfaf7c23df069fab70687a63"}, - {file = "reflex_chakra-0.6.0a5.tar.gz", hash = "sha256:b44e73478462052f09c9677d3fd7726891b4af87711b4b6a2171f010049308c9"}, + {file = "reflex_chakra-0.6.0a6-py3-none-any.whl", hash = "sha256:a526f5db8a457c68c24317d007172e77b323a34abf03f05eeb8d92c014563bfb"}, + {file = "reflex_chakra-0.6.0a6.tar.gz", hash = "sha256:124a780ea96d36d31f46b4c97bb0c0f111f2fb6e0d66a142e1577dad740f6e35"}, ] [package.dependencies] @@ -2173,6 +2264,7 @@ reflex = ">=0.6.0a" name = "reflex-hosting-cli" version = "0.1.13" description = "Reflex Hosting CLI" +category = "main" optional = false python-versions = "<4.0,>=3.8" files = [ @@ -2196,6 +2288,7 @@ websockets = ">=10.4" name = "requests" version = "2.32.3" description = "Python HTTP for Humans." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2217,6 +2310,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "requests-toolbelt" version = "1.0.0" description = "A utility belt for advanced users of python-requests" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2231,6 +2325,7 @@ requests = ">=2.0.1,<3.0.0" name = "rfc3986" version = "2.0.0" description = "Validating URI References per RFC 3986" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2245,6 +2340,7 @@ idna2008 = ["idna"] name = "rich" version = "13.8.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -2264,6 +2360,7 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] name = "ruff" version = "0.4.10" description = "An extremely fast Python linter and code formatter, written in Rust." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2290,6 +2387,7 @@ files = [ name = "secretstorage" version = "3.3.3" description = "Python bindings to FreeDesktop.org Secret Service API" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2305,6 +2403,7 @@ jeepney = ">=0.6" name = "selenium" version = "4.24.0" description = "Official Python bindings for Selenium WebDriver" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2324,6 +2423,7 @@ websocket-client = ">=1.8,<2.0" name = "setuptools" version = "70.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2339,6 +2439,7 @@ testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metad name = "shellingham" version = "1.5.4" description = "Tool to Detect Surrounding Shell" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2350,6 +2451,7 @@ files = [ name = "simple-websocket" version = "1.0.0" description = "Simple WebSocket server and client for Python" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2367,6 +2469,7 @@ docs = ["sphinx"] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2378,6 +2481,7 @@ files = [ name = "sniffio" version = "1.3.1" description = "Sniff out which async library your code is running under" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2389,6 +2493,7 @@ files = [ name = "sortedcontainers" version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" +category = "dev" optional = false python-versions = "*" files = [ @@ -2400,6 +2505,7 @@ files = [ name = "sqlalchemy" version = "2.0.34" description = "Database Abstraction Library" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2455,7 +2561,7 @@ files = [ ] [package.dependencies] -greenlet = {version = "!=0.4.17", markers = "python_version < \"3.13\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} +greenlet = {version = "!=0.4.17", markers = "python_version < \"3.13\" and platform_machine == \"aarch64\" or python_version < \"3.13\" and platform_machine == \"ppc64le\" or python_version < \"3.13\" and platform_machine == \"x86_64\" or python_version < \"3.13\" and platform_machine == \"amd64\" or python_version < \"3.13\" and platform_machine == \"AMD64\" or python_version < \"3.13\" and platform_machine == \"win32\" or python_version < \"3.13\" and platform_machine == \"WIN32\""} typing-extensions = ">=4.6.0" [package.extras] @@ -2487,6 +2593,7 @@ sqlcipher = ["sqlcipher3_binary"] name = "sqlmodel" version = "0.0.22" description = "SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2502,6 +2609,7 @@ SQLAlchemy = ">=2.0.14,<2.1.0" name = "starlette" version = "0.38.4" description = "The little ASGI library that shines." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2520,6 +2628,7 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7 name = "starlette-admin" version = "0.14.1" description = "Fast, beautiful and extensible administrative interface framework for Starlette/FastApi applications" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2543,6 +2652,7 @@ test = ["aiomysql (>=0.1.1,<0.3.0)", "aiosqlite (>=0.17.0,<0.21.0)", "arrow (>=1 name = "tabulate" version = "0.9.0" description = "Pretty-print tabular data" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2557,6 +2667,7 @@ widechars = ["wcwidth"] name = "tenacity" version = "9.0.0" description = "Retry code until it succeeds" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2572,6 +2683,7 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2583,6 +2695,7 @@ files = [ name = "tomli" version = "2.0.1" description = "A lil' TOML parser" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2594,6 +2707,7 @@ files = [ name = "tomlkit" version = "0.13.2" description = "Style preserving TOML library" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2605,6 +2719,7 @@ files = [ name = "trio" version = "0.26.2" description = "A friendly Python library for async concurrency and I/O" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2625,6 +2740,7 @@ sortedcontainers = "*" name = "trio-websocket" version = "0.11.1" description = "WebSocket library for Trio" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2641,6 +2757,7 @@ wsproto = ">=0.14" name = "twine" version = "5.1.1" description = "Collection of utilities for publishing packages on PyPI" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2663,6 +2780,7 @@ urllib3 = ">=1.26.0" name = "typer" version = "0.12.5" description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2680,6 +2798,7 @@ typing-extensions = ">=3.7.4.3" name = "typing-extensions" version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2691,6 +2810,7 @@ files = [ name = "tzdata" version = "2024.1" description = "Provider of IANA time zone data" +category = "main" optional = false python-versions = ">=2" files = [ @@ -2702,6 +2822,7 @@ files = [ name = "urllib3" version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2722,6 +2843,7 @@ zstd = ["zstandard (>=0.18.0)"] name = "uvicorn" version = "0.30.6" description = "The lightning-fast ASGI server." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2741,6 +2863,7 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", name = "virtualenv" version = "20.26.3" description = "Virtual Python Environment builder" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2761,6 +2884,7 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "websocket-client" version = "1.8.0" description = "WebSocket client for Python with low level API options" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2777,6 +2901,7 @@ test = ["websockets"] name = "websockets" version = "13.0.1" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2872,6 +2997,7 @@ files = [ name = "wheel" version = "0.44.0" description = "A built-package format for Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2886,6 +3012,7 @@ test = ["pytest (>=6.0.0)", "setuptools (>=65)"] name = "wrapt" version = "1.16.0" description = "Module for decorators, wrappers and monkey patching." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2965,6 +3092,7 @@ files = [ name = "wsproto" version = "1.2.0" description = "WebSockets state-machine based protocol implementation" +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -2979,6 +3107,7 @@ h11 = ">=0.9.0,<1" name = "zipp" version = "3.20.1" description = "Backport of pathlib-compatible object wrapper for zip files" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2997,4 +3126,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "0bd98b6baa48d41ec50bfa0903d89005129211f6e429d7b62504ee880f8ba523" +content-hash = "7a8990e432a404802c3ace9a81c3c8c33cdd60596f26cdc38e2de424cb1126dd" diff --git a/pyproject.toml b/pyproject.toml index c8598a479..9643b69e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,7 +59,7 @@ httpx = ">=0.25.1,<1.0" twine = ">=4.0.0,<6.0" tomlkit = ">=0.12.4,<1.0" lazy_loader = ">=0.4" -reflex-chakra = ">=0.6.0a" +reflex-chakra = ">=0.6.0a6" [tool.poetry.group.dev.dependencies] pytest = ">=7.1.2,<8.0" diff --git a/reflex/.templates/jinja/web/pages/_app.js.jinja2 b/reflex/.templates/jinja/web/pages/_app.js.jinja2 index d4322b171..654f7a2a4 100644 --- a/reflex/.templates/jinja/web/pages/_app.js.jinja2 +++ b/reflex/.templates/jinja/web/pages/_app.js.jinja2 @@ -27,7 +27,7 @@ function AppWrap({children}) { export default function MyApp({ Component, pageProps }) { return ( - + diff --git a/reflex/.templates/web/components/reflex/chakra_color_mode_provider.js b/reflex/.templates/web/components/reflex/chakra_color_mode_provider.js deleted file mode 100644 index ad41d5134..000000000 --- a/reflex/.templates/web/components/reflex/chakra_color_mode_provider.js +++ /dev/null @@ -1,36 +0,0 @@ -import { useColorMode as chakraUseColorMode } from "@chakra-ui/react"; -import { useTheme } from "next-themes"; -import { useEffect, useState } from "react"; -import { ColorModeContext, defaultColorMode } from "/utils/context.js"; - -export default function ChakraColorModeProvider({ children }) { - const { theme, resolvedTheme, setTheme } = useTheme(); - const { colorMode, toggleColorMode } = chakraUseColorMode(); - const [resolvedColorMode, setResolvedColorMode] = useState(colorMode); - - useEffect(() => { - if (colorMode != resolvedTheme) { - toggleColorMode(); - } - setResolvedColorMode(resolvedTheme); - }, [theme, resolvedTheme]); - - const rawColorMode = colorMode; - const setColorMode = (mode) => { - const allowedModes = ["light", "dark", "system"]; - if (!allowedModes.includes(mode)) { - console.error( - `Invalid color mode "${mode}". Defaulting to "${defaultColorMode}".` - ); - mode = defaultColorMode; - } - setTheme(mode); - }; - return ( - - {children} - - ); -} diff --git a/reflex/__init__.pyi b/reflex/__init__.pyi index 22c7298fe..b11da5fb0 100644 --- a/reflex/__init__.pyi +++ b/reflex/__init__.pyi @@ -132,6 +132,7 @@ from .components.radix.themes.layout.container import container as container from .components.radix.themes.layout.flex import flex as flex from .components.radix.themes.layout.grid import grid as grid from .components.radix.themes.layout.list import list_item as list_item +from .components.radix.themes.layout.list import list_ns as list # noqa from .components.radix.themes.layout.list import ordered_list as ordered_list from .components.radix.themes.layout.list import unordered_list as unordered_list from .components.radix.themes.layout.section import section as section diff --git a/reflex/components/radix/__init__.pyi b/reflex/components/radix/__init__.pyi index 8ba6c242b..f4e81666a 100644 --- a/reflex/components/radix/__init__.pyi +++ b/reflex/components/radix/__init__.pyi @@ -55,6 +55,7 @@ from .themes.layout.container import container as container from .themes.layout.flex import flex as flex from .themes.layout.grid import grid as grid from .themes.layout.list import list_item as list_item +from .themes.layout.list import list_ns as list # noqa from .themes.layout.list import ordered_list as ordered_list from .themes.layout.list import unordered_list as unordered_list from .themes.layout.section import section as section diff --git a/reflex/components/radix/themes/base.py b/reflex/components/radix/themes/base.py index 5a7fb2d99..82bb3c036 100644 --- a/reflex/components/radix/themes/base.py +++ b/reflex/components/radix/themes/base.py @@ -262,26 +262,6 @@ class ThemePanel(RadixThemesComponent): """ return {"react": "useEffect"} - def add_hooks(self) -> list[str]: - """Add a hook on the ThemePanel to clear chakra-ui-color-mode. - - Returns: - The hooks to render. - """ - # The panel freezes the tab if the user color preference differs from the - # theme "appearance", so clear it out when theme panel is used. - return [ - """ - useEffect(() => { - if (typeof window !== 'undefined') { - window.onbeforeunload = () => { - localStorage.removeItem('chakra-ui-color-mode'); - } - window.onbeforeunload(); - } - }, [])""" - ] - class RadixThemesColorModeProvider(Component): """Next-themes integration for radix themes components.""" diff --git a/reflex/components/radix/themes/base.pyi b/reflex/components/radix/themes/base.pyi index c79557024..fd0b7e092 100644 --- a/reflex/components/radix/themes/base.pyi +++ b/reflex/components/radix/themes/base.pyi @@ -583,7 +583,6 @@ class Theme(RadixThemesComponent): class ThemePanel(RadixThemesComponent): def add_imports(self) -> dict[str, str]: ... - def add_hooks(self) -> list[str]: ... @overload @classmethod def create( # type: ignore diff --git a/reflex/components/radix/themes/layout/__init__.pyi b/reflex/components/radix/themes/layout/__init__.pyi index 1420299e0..6712a3068 100644 --- a/reflex/components/radix/themes/layout/__init__.pyi +++ b/reflex/components/radix/themes/layout/__init__.pyi @@ -9,6 +9,7 @@ from .container import container as container from .flex import flex as flex from .grid import grid as grid from .list import list_item as list_item +from .list import list_ns as list # noqa from .list import ordered_list as ordered_list from .list import unordered_list as unordered_list from .section import section as section diff --git a/reflex/style.py b/reflex/style.py index b29160cb2..5e5503e66 100644 --- a/reflex/style.py +++ b/reflex/style.py @@ -290,7 +290,6 @@ def _format_emotion_style_pseudo_selector(key: str) -> str: """ prefix = None if key.startswith("_"): - # Handle pseudo selectors in chakra style format. prefix = "&:" key = key[1:] if key.startswith(":"): diff --git a/reflex/utils/pyi_generator.py b/reflex/utils/pyi_generator.py index cc60418a9..bd0d9f118 100644 --- a/reflex/utils/pyi_generator.py +++ b/reflex/utils/pyi_generator.py @@ -903,7 +903,13 @@ class PyiGenerator: # construct the import statement and handle special cases for aliases sub_mod_attrs_imports = [ f"from .{path} import {mod if not isinstance(mod, tuple) else mod[0]} as {mod if not isinstance(mod, tuple) else mod[1]}" - + (" # type: ignore" if mod in pyright_ignore_imports else "") + + ( + " # type: ignore" + if mod in pyright_ignore_imports + else " # noqa" # ignore ruff formatting here for cases like rx.list. + if isinstance(mod, tuple) + else "" + ) for mod, path in sub_mod_attrs.items() ] sub_mod_attrs_imports.append("") diff --git a/tests/components/datadisplay/test_table.py b/tests/components/datadisplay/test_table.py deleted file mode 100644 index 8740d4b8c..000000000 --- a/tests/components/datadisplay/test_table.py +++ /dev/null @@ -1,177 +0,0 @@ -import sys -from typing import List, Tuple - -import pytest -from reflex_chakra.components.datadisplay.table import Tbody, Tfoot, Thead - -from reflex.state import BaseState - -PYTHON_GT_V38 = sys.version_info.major >= 3 and sys.version_info.minor > 8 - - -class TableState(BaseState): - """Test State class.""" - - rows_List_List_str: List[List[str]] = [["random", "row"]] - rows_List_List: List[List] = [["random", "row"]] - rows_List_str: List[str] = ["random", "row"] - rows_Tuple_List_str: Tuple[List[str]] = (["random", "row"],) - rows_Tuple_List: Tuple[List] = ["random", "row"] # type: ignore - rows_Tuple_str_str: Tuple[str, str] = ( - "random", - "row", - ) - rows_Tuple_Tuple_str_str: Tuple[Tuple[str, str]] = ( - ( - "random", - "row", - ), - ) - rows_Tuple_Tuple: Tuple[Tuple] = ( - ( - "random", - "row", - ), - ) - rows_str: str = "random, row" - headers_List_str: List[str] = ["header1", "header2"] - headers_Tuple_str_str: Tuple[str, str] = ( - "header1", - "header2", - ) - headers_str: str = "headers1, headers2" - footers_List_str: List[str] = ["footer1", "footer2"] - footers_Tuple_str_str: Tuple[str, str] = ( - "footer1", - "footer2", - ) - footers_str: str = "footer1, footer2" - - if sys.version_info.major >= 3 and sys.version_info.minor > 8: - rows_list_list_str: list[list[str]] = [["random", "row"]] - rows_list_list: list[list] = [["random", "row"]] - rows_list_str: list[str] = ["random", "row"] - rows_tuple_list_str: tuple[list[str]] = (["random", "row"],) - rows_tuple_list: tuple[list] = ["random", "row"] # type: ignore - rows_tuple_str_str: tuple[str, str] = ( - "random", - "row", - ) - rows_tuple_tuple_str_str: tuple[tuple[str, str]] = ( - ( - "random", - "row", - ), - ) - rows_tuple_tuple: tuple[tuple] = ( - ( - "random", - "row", - ), - ) - - -valid_extras = ( - [ - TableState.rows_list_list_str, - TableState.rows_list_list, - TableState.rows_tuple_list_str, - TableState.rows_tuple_list, - TableState.rows_tuple_tuple_str_str, - TableState.rows_tuple_tuple, - ] - if PYTHON_GT_V38 - else [] -) -invalid_extras = ( - [TableState.rows_list_str, TableState.rows_tuple_str_str] if PYTHON_GT_V38 else [] -) - - -@pytest.mark.parametrize( - "rows", - [ - [["random", "row"]], - TableState.rows_List_List_str, - TableState.rows_List_List, - TableState.rows_Tuple_List_str, - TableState.rows_Tuple_List, - TableState.rows_Tuple_Tuple_str_str, - TableState.rows_Tuple_Tuple, - *valid_extras, - ], -) -def test_create_table_body_with_valid_rows_prop(rows): - render_dict = Tbody.create(rows=rows).render() - assert render_dict["name"] == "Tbody" - assert len(render_dict["children"]) == 1 - - -@pytest.mark.parametrize( - "rows", - [ - ["random", "row"], - "random, rows", - TableState.rows_List_str, - TableState.rows_Tuple_str_str, - TableState.rows_str, - *invalid_extras, - ], -) -def test_create_table_body_with_invalid_rows_prop(rows): - with pytest.raises(TypeError): - Tbody.create(rows=rows) - - -@pytest.mark.parametrize( - "headers", - [ - ["random", "header"], - TableState.headers_List_str, - TableState.headers_Tuple_str_str, - ], -) -def test_create_table_head_with_valid_headers_prop(headers): - render_dict = Thead.create(headers=headers).render() - assert render_dict["name"] == "Thead" - assert len(render_dict["children"]) == 1 - assert render_dict["children"][0]["name"] == "Tr" - - -@pytest.mark.parametrize( - "headers", - [ - "random, header", - TableState.headers_str, - ], -) -def test_create_table_head_with_invalid_headers_prop(headers): - with pytest.raises(TypeError): - Thead.create(headers=headers) - - -@pytest.mark.parametrize( - "footers", - [ - ["random", "footers"], - TableState.footers_List_str, - TableState.footers_Tuple_str_str, - ], -) -def test_create_table_footer_with_valid_footers_prop(footers): - render_dict = Tfoot.create(footers=footers).render() - assert render_dict["name"] == "Tfoot" - assert len(render_dict["children"]) == 1 - assert render_dict["children"][0]["name"] == "Tr" - - -@pytest.mark.parametrize( - "footers", - [ - "random, footers", - TableState.footers_str, - ], -) -def test_create_table_footer_with_invalid_footers_prop(footers): - with pytest.raises(TypeError): - Tfoot.create(footers=footers) diff --git a/tests/components/forms/test_form.py b/tests/components/forms/test_form.py index efb31b97a..0611c6994 100644 --- a/tests/components/forms/test_form.py +++ b/tests/components/forms/test_form.py @@ -1,5 +1,4 @@ -from reflex_chakra.components.forms.form import Form - +from reflex.components.radix.primitives.form import Form from reflex.event import EventChain from reflex.ivars.base import ImmutableVar diff --git a/tests/components/media/test_icon.py b/tests/components/media/test_icon.py deleted file mode 100644 index 6a152c587..000000000 --- a/tests/components/media/test_icon.py +++ /dev/null @@ -1,55 +0,0 @@ -import pytest -from reflex_chakra.components.media.icon import ICON_LIST, Icon - -from reflex.utils import format - - -def test_no_tag_errors(): - """Test that an icon without a tag raises an error.""" - with pytest.raises(AttributeError): - Icon.create() - - -def test_children_errors(): - """Test that an icon with children raises an error.""" - with pytest.raises(AttributeError): - Icon.create("child", tag="search") - - -@pytest.mark.parametrize( - "tag", - ICON_LIST, -) -def test_valid_icon(tag: str): - """Test that a valid icon does not raise an error. - - Args: - tag: The icon tag. - """ - icon = Icon.create(tag=tag) - assert icon.tag == format.to_title_case(tag) + "Icon" - - -@pytest.mark.parametrize("tag", ["", " ", "invalid", 123]) -def test_invalid_icon(tag): - """Test that an invalid icon raises an error. - - Args: - tag: The icon tag. - """ - with pytest.raises(ValueError): - Icon.create(tag=tag) - - -@pytest.mark.parametrize( - "tag", - ["Check", "Close", "eDit"], -) -def test_tag_with_capital(tag: str): - """Test that an icon that tag with capital does not raise an error. - - Args: - tag: The icon tag. - """ - icon = Icon.create(tag=tag) - assert icon.tag == format.to_title_case(tag) + "Icon" diff --git a/tests/components/test_component.py b/tests/components/test_component.py index 3ce5decad..592e1ca6e 100644 --- a/tests/components/test_component.py +++ b/tests/components/test_component.py @@ -2,8 +2,6 @@ from contextlib import nullcontext from typing import Any, Dict, List, Optional, Type, Union import pytest -import reflex_chakra as rc -from reflex_chakra.components.layout.box import Box import reflex as rx from reflex.base import Base @@ -16,6 +14,7 @@ from reflex.components.component import ( StatefulComponent, custom_component, ) +from reflex.components.radix.themes.layout.box import Box from reflex.constants import EventTriggers from reflex.event import EventChain, EventHandler, parse_args_spec from reflex.ivars.base import ImmutableVar, LiteralVar @@ -1114,8 +1113,8 @@ def test_component_with_only_valid_children(fixture, request): [ (rx.text("hi"), '\n {"hi"}\n'), ( - rx.box(rc.heading("test", size="md")), - '\n \n {"test"}\n\n', + rx.box(rx.heading("test", size="3")), + '\n \n {"test"}\n\n', ), ], ) diff --git a/tests/components/typography/test_markdown.py b/tests/components/typography/test_markdown.py index 2ef6fbce4..5e9abbb1f 100644 --- a/tests/components/typography/test_markdown.py +++ b/tests/components/typography/test_markdown.py @@ -1,5 +1,4 @@ import pytest -import reflex_chakra as rc import reflex as rx from reflex.components.markdown import Markdown @@ -37,9 +36,7 @@ def test_get_component(tag, expected): def test_set_component_map(): """Test setting the component map.""" component_map = { - "h1": lambda value: rx.box( - rc.heading(value, as_="h1", size="2xl"), padding="1em" - ), + "h1": lambda value: rx.box(rx.heading(value, as_="h1"), padding="1em"), "p": lambda value: rx.box(rx.text(value), padding="1em"), } md = Markdown.create("# Hello", component_map=component_map) diff --git a/tests/test_app.py b/tests/test_app.py index 0c81f1e2c..5544736bf 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -13,7 +13,6 @@ from typing import Generator, List, Tuple, Type from unittest.mock import AsyncMock import pytest -import reflex_chakra as rc import sqlmodel from fastapi import FastAPI, UploadFile from starlette_admin.auth import AuthProvider @@ -1311,13 +1310,13 @@ def test_app_wrap_priority(compilable_app: tuple[App, Path]): tag = "Fragment1" def _get_app_wrap_components(self) -> dict[tuple[int, str], Component]: - return {(99, "Box"): rc.box()} + return {(99, "Box"): rx.box()} class Fragment2(Component): tag = "Fragment2" def _get_app_wrap_components(self) -> dict[tuple[int, str], Component]: - return {(50, "Text"): rc.text()} + return {(50, "Text"): rx.text()} class Fragment3(Component): tag = "Fragment3" @@ -1337,19 +1336,17 @@ def test_app_wrap_priority(compilable_app: tuple[App, Path]): assert ( "function AppWrap({children}) {" "return (" - "" - "" - "" - "" + "" + '' + "" "" "" "{children}" "" "" - "" - "" - "" - "" + "" + "" + "" ")" "}" ) in "".join(app_js_lines)