From f18753f408751006252bb37b037c9ae1b4387986 Mon Sep 17 00:00:00 2001 From: Harsh Thakare Date: Sun, 30 Aug 2026 20:41:34 +0530 Subject: [PATCH 1/8] Migrate react-moment to 2.0.2 --- docs/app/reflex.lock/bun.lock | 7 +- docs/app/reflex.lock/package.json | 3 +- .../news/7003.bugfix.md | 1 + .../src/reflex_components_moment/moment.py | 9 ++- pyi_hashes.json | 2 +- tests/integration/test_moment.py | 77 +++++++++++++++++++ tests/units/compiler/test_memoize_plugin.py | 18 +++++ 7 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 packages/reflex-components-moment/news/7003.bugfix.md create mode 100644 tests/integration/test_moment.py diff --git a/docs/app/reflex.lock/bun.lock b/docs/app/reflex.lock/bun.lock index 29c56559121..64e906ef608 100644 --- a/docs/app/reflex.lock/bun.lock +++ b/docs/app/reflex.lock/bun.lock @@ -38,6 +38,7 @@ "lucide-react": "1.26.0", "mergician": "v2.0.2", "moment": "2.30.1", + "moment-duration-format": "2.2.2", "moment-timezone": "0.6.2", "plotly.js": "3.7.0", "plotly.js-locales": "3.7.0", @@ -51,7 +52,7 @@ "react-helmet": "6.1.0", "react-leaflet": "5.0.0", "react-markdown": "10.1.0", - "react-moment": "1.2.2", + "react-moment": "2.0.2", "react-player": "3.4.0", "react-plotly.js": "4.0.0", "react-responsive-carousel": "3.2.23", @@ -1368,6 +1369,8 @@ "moment": ["moment@2.30.1", "", {}, "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how=="], + "moment-duration-format": ["moment-duration-format@2.2.2", "", {}, "sha512-NR6qiYywjQ6UdLCpfpg1WhaWdpAg4EHIaUGaTTgTLrPVooUKp7Q7eN/gmcUxp/dIL7+Rya+P0ApI/Ve1Nq7ycw=="], + "moment-timezone": ["moment-timezone@0.6.2", "", { "dependencies": { "moment": "^2.29.4" } }, "sha512-lDsQv8FoGdBUdf0+TjGsq2orxKuXdwFlQ6Zw6TX3xIcTwTfEpCLyKqvEauvCHJ8iu3KBV8+uPhlv70YsNGdUBQ=="], "mouse-event-offset": ["mouse-event-offset@3.0.2", "", {}, "sha512-s9sqOs5B1Ykox3Xo8b3Ss2IQju4UwlW6LSR+Q5FXWpprJ5fzMLefIIItr3PH8RwzfGy6gxs/4GAmiNuZScE25w=="], @@ -1524,7 +1527,7 @@ "react-merge-refs": ["react-merge-refs@2.1.1", "", {}, "sha512-jLQXJ/URln51zskhgppGJ2ub7b2WFKGq3cl3NYKtlHoTG+dN2q7EzWrn3hN3EgPsTMvpR9tpq5ijdp7YwFZkag=="], - "react-moment": ["react-moment@1.2.2", "", { "peerDependencies": { "moment": "^2.29.0", "prop-types": "^15.7.0", "react": "^16.0 || ^17.0.0 || ^18.0.0" } }, "sha512-F5/YLsygduvR5+mpYdHMD9HzyljQFudcoAfL5XmJhGBkZVzJANIx/5PN+kvWO5KELifXXtndXeMCUxH4eB+E9Q=="], + "react-moment": ["react-moment@2.0.2", "", { "peerDependencies": { "moment": "^2.29.0", "moment-duration-format": "^2.2.2", "react": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["moment-duration-format"] }, "sha512-aogeei/erGX9iL7kAwQceaxdW2JR0/XbITYBEN1mFHG0Z02y8G0Wrl2PgbfIPs5EbVFhUB2F2+FopW9UPuP1qg=="], "react-number-format": ["react-number-format@5.4.5", "", { "peerDependencies": { "react": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-y8O2yHHj3w0aE9XO8d2BCcUOOdQTRSVq+WIuMlLVucAm5XNjJAy+BoOJiuQMldVYVOKTMyvVNfnbl2Oqp+YxGw=="], diff --git a/docs/app/reflex.lock/package.json b/docs/app/reflex.lock/package.json index 474c46acd19..93440a453fd 100644 --- a/docs/app/reflex.lock/package.json +++ b/docs/app/reflex.lock/package.json @@ -39,6 +39,7 @@ "lucide-react": "1.26.0", "mergician": "v2.0.2", "moment": "2.30.1", + "moment-duration-format": "2.2.2", "moment-timezone": "0.6.2", "plotly.js": "3.7.0", "plotly.js-locales": "3.7.0", @@ -52,7 +53,7 @@ "react-helmet": "6.1.0", "react-leaflet": "5.0.0", "react-markdown": "10.1.0", - "react-moment": "1.2.2", + "react-moment": "2.0.2", "react-player": "3.4.0", "react-plotly.js": "4.0.0", "react-responsive-carousel": "3.2.23", diff --git a/packages/reflex-components-moment/news/7003.bugfix.md b/packages/reflex-components-moment/news/7003.bugfix.md new file mode 100644 index 00000000000..3cb1ffc171f --- /dev/null +++ b/packages/reflex-components-moment/news/7003.bugfix.md @@ -0,0 +1 @@ +Migrate `rx.moment` to `react-moment` 2.0.2 and include its duration-format dependency. diff --git a/packages/reflex-components-moment/src/reflex_components_moment/moment.py b/packages/reflex-components-moment/src/reflex_components_moment/moment.py index 067c9d9ea63..b2265bd52d6 100644 --- a/packages/reflex-components-moment/src/reflex_components_moment/moment.py +++ b/packages/reflex-components-moment/src/reflex_components_moment/moment.py @@ -4,6 +4,7 @@ import dataclasses import datetime +from typing import Any from reflex_base.components.component import MemoizationLeaf, NoSSRComponent, field from reflex_base.event import EventHandler, passthrough_event_spec @@ -31,8 +32,8 @@ class Moment(NoSSRComponent, MemoizationLeaf): tag: str | None = "Moment" is_default = True - library: str | None = "react-moment@1.2.2" - lib_dependencies: list[str] = ["moment@2.30.1"] + library: str | None = "react-moment@2.0.2" + lib_dependencies: list[str] = ["moment@2.30.1", "moment-duration-format@2.2.2"] interval: Var[int] = field( doc="How often the date update (how often time update / 0 to disable)." @@ -42,11 +43,11 @@ class Moment(NoSSRComponent, MemoizationLeaf): doc="Formats the date according to the given format string." ) - trim: Var[bool] = field( + trim: Var[bool | str] = field( doc="When formatting duration time, the largest-magnitude tokens are automatically trimmed when they have no value." ) - parse: Var[str] = field( + parse: Var[str | list[Any]] = field( doc=" Use the parse attribute to tell moment how to parse the given date when non-standard." ) diff --git a/pyi_hashes.json b/pyi_hashes.json index 8936d040427..6751ae3be03 100644 --- a/pyi_hashes.json +++ b/pyi_hashes.json @@ -41,7 +41,7 @@ "packages/reflex-components-gridjs/src/reflex_components_gridjs/datatable.pyi": "2ce1c076ecf5c2fa4945b4abdbf2f91d", "packages/reflex-components-lucide/src/reflex_components_lucide/icon.pyi": "1e331a3d6420b97e5b1ce7f63ad53de8", "packages/reflex-components-markdown/src/reflex_components_markdown/markdown.pyi": "79d0a59b1ba12a2f2c4a09fa6b5c776f", - "packages/reflex-components-moment/src/reflex_components_moment/moment.pyi": "85d515f5254bb4c188075873ec4d8a51", + "packages/reflex-components-moment/src/reflex_components_moment/moment.pyi": "b9b01a266a21fa7cbd400777adb37ab7", "packages/reflex-components-plotly/src/reflex_components_plotly/plotly.pyi": "beb057e382e527224597c320dbb72385", "packages/reflex-components-radix/src/reflex_components_radix/__init__.pyi": "a77352f60fb6f4135b5d08a6e56efa6d", "packages/reflex-components-radix/src/reflex_components_radix/primitives/__init__.pyi": "bbd4d1a4fa73275a882c33ba485d0165", diff --git a/tests/integration/test_moment.py b/tests/integration/test_moment.py new file mode 100644 index 00000000000..82baa29f356 --- /dev/null +++ b/tests/integration/test_moment.py @@ -0,0 +1,77 @@ +"""Integration tests for the Moment component.""" + +from collections.abc import Generator + +import pytest +from selenium.webdriver.common.by import By + +from reflex.testing import AppHarness, WebDriver + + +def MomentApp(): + """Create an app that exercises the react-moment 2.x prop changes.""" + import reflex as rx + + app = rx.App() + + class State(rx.State): + """State used to wait for the browser connection before asserting output.""" + + @app.add_page + def index(): + return rx.vstack( + rx.el.input( + id="token", + value=State.router.session.client_token, + is_read_only=True, + ), + rx.moment( + "2026-08-30", + format="YYYY-MM-DD", + parse=["YYYY-MM-DD"], + trim="h [hours]", + id="moment", + ), + ) + + +@pytest.fixture(scope="module") +def moment_app( + tmp_path_factory, app_harness_env: type[AppHarness] +) -> Generator[AppHarness, None, None]: + """Start the Moment integration app. + + Yields: + The running Moment app harness. + """ + with app_harness_env.create( + root=tmp_path_factory.mktemp("moment"), app_source=MomentApp + ) as harness: + assert harness.app_instance is not None, "app is not running" + yield harness + + +@pytest.fixture +def driver(moment_app: AppHarness) -> Generator[WebDriver, None, None]: + """Open the Moment integration app in a browser. + + Yields: + The browser driver connected to the Moment app. + """ + driver = moment_app.frontend() + try: + token = AppHarness.poll_for_or_raise_timeout( + lambda: driver.find_element(By.ID, "token") + ) + AppHarness.poll_for_or_raise_timeout(lambda: token.get_attribute("value")) + yield driver + finally: + driver.quit() + + +def test_moment_2_props_render(driver: WebDriver) -> None: + """Changed react-moment 2.x props should render without a client error.""" + moment = AppHarness.poll_for_or_raise_timeout( + lambda: driver.find_element(By.ID, "moment") + ) + assert moment.text == "2026-08-30" diff --git a/tests/units/compiler/test_memoize_plugin.py b/tests/units/compiler/test_memoize_plugin.py index 0098e49bd76..2d14f799c85 100644 --- a/tests/units/compiler/test_memoize_plugin.py +++ b/tests/units/compiler/test_memoize_plugin.py @@ -1841,6 +1841,24 @@ def test_moment_with_stateful_var_child_does_not_wrap_bare_independently() -> No ) +def test_moment_uses_react_moment_2_props_and_dependencies() -> None: + """The wrapper should support the changed react-moment 2.x prop types.""" + + assert Moment.library == "react-moment@2.0.2" + assert Moment.lib_dependencies == [ + "moment@2.30.1", + "moment-duration-format@2.2.2", + ] + + moment = Moment.create( + "2026-08-30", + trim="h [hours]", + parse=["YYYY-MM-DD"], + ) + assert str(moment.trim) == '"h [hours]"' + assert str(moment.parse) == '["YYYY-MM-DD"]' + + def test_moment_memo_body_renders_text_interpolation_not_bare_component() -> None: """The moment's memo body must interpolate the state Var as text, not a Bare wrapper.""" ctx, _page_ctx = _compile_single_page( From 9bfaf328f6d925bb25efd4408c5aa9eee5753299 Mon Sep 17 00:00:00 2001 From: Harsh Thakare Date: Sun, 30 Aug 2026 21:41:28 +0530 Subject: [PATCH 2/8] Stabilize Moment integration assertion --- tests/integration/test_moment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_moment.py b/tests/integration/test_moment.py index 82baa29f356..3f996579e36 100644 --- a/tests/integration/test_moment.py +++ b/tests/integration/test_moment.py @@ -74,4 +74,4 @@ def test_moment_2_props_render(driver: WebDriver) -> None: moment = AppHarness.poll_for_or_raise_timeout( lambda: driver.find_element(By.ID, "moment") ) - assert moment.text == "2026-08-30" + AppHarness.expect(lambda: moment.text == "2026-08-30") From c85abb25b72a73ca1428e4d0438c2eddfb86c72a Mon Sep 17 00:00:00 2001 From: Farhan Date: Tue, 1 Sep 2026 11:47:52 +0500 Subject: [PATCH 3/8] Fix lint and pyright failures in Moment prop test Remove a blank line after a docstring flagged by ruff, assert the widened trim/parse props through render() so the assertion type-checks against the generated stub, and regenerate the stale moment.pyi hash. Claude-Session: https://claude.ai/code/session_01MoV7fVgzsa5dRLRzFZU9s8 --- pyi_hashes.json | 2 +- tests/units/compiler/test_memoize_plugin.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyi_hashes.json b/pyi_hashes.json index 6751ae3be03..4be878964e0 100644 --- a/pyi_hashes.json +++ b/pyi_hashes.json @@ -41,7 +41,7 @@ "packages/reflex-components-gridjs/src/reflex_components_gridjs/datatable.pyi": "2ce1c076ecf5c2fa4945b4abdbf2f91d", "packages/reflex-components-lucide/src/reflex_components_lucide/icon.pyi": "1e331a3d6420b97e5b1ce7f63ad53de8", "packages/reflex-components-markdown/src/reflex_components_markdown/markdown.pyi": "79d0a59b1ba12a2f2c4a09fa6b5c776f", - "packages/reflex-components-moment/src/reflex_components_moment/moment.pyi": "b9b01a266a21fa7cbd400777adb37ab7", + "packages/reflex-components-moment/src/reflex_components_moment/moment.pyi": "880ae7095693e0709ba4f5584ccae2d5", "packages/reflex-components-plotly/src/reflex_components_plotly/plotly.pyi": "beb057e382e527224597c320dbb72385", "packages/reflex-components-radix/src/reflex_components_radix/__init__.pyi": "a77352f60fb6f4135b5d08a6e56efa6d", "packages/reflex-components-radix/src/reflex_components_radix/primitives/__init__.pyi": "bbd4d1a4fa73275a882c33ba485d0165", diff --git a/tests/units/compiler/test_memoize_plugin.py b/tests/units/compiler/test_memoize_plugin.py index 2d14f799c85..2ec88b4c8ca 100644 --- a/tests/units/compiler/test_memoize_plugin.py +++ b/tests/units/compiler/test_memoize_plugin.py @@ -1843,7 +1843,6 @@ def test_moment_with_stateful_var_child_does_not_wrap_bare_independently() -> No def test_moment_uses_react_moment_2_props_and_dependencies() -> None: """The wrapper should support the changed react-moment 2.x prop types.""" - assert Moment.library == "react-moment@2.0.2" assert Moment.lib_dependencies == [ "moment@2.30.1", @@ -1855,8 +1854,9 @@ def test_moment_uses_react_moment_2_props_and_dependencies() -> None: trim="h [hours]", parse=["YYYY-MM-DD"], ) - assert str(moment.trim) == '"h [hours]"' - assert str(moment.parse) == '["YYYY-MM-DD"]' + props = moment.render()["props"] + assert 'trim:"h [hours]"' in props + assert 'parse:["YYYY-MM-DD"]' in props def test_moment_memo_body_renders_text_interpolation_not_bare_component() -> None: From bd58635caf34c1cffc5f32f0b1201d4092b8a793 Mon Sep 17 00:00:00 2001 From: Harsh Thakare Date: Tue, 1 Sep 2026 14:42:47 +0530 Subject: [PATCH 4/8] Fix react-moment duration plugin loading --- .../src/reflex_components_moment/moment.py | 4 +++- tests/integration/test_moment.py | 12 +++++++++++- tests/units/compiler/test_memoize_plugin.py | 4 ++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/reflex-components-moment/src/reflex_components_moment/moment.py b/packages/reflex-components-moment/src/reflex_components_moment/moment.py index b2265bd52d6..22802f5922e 100644 --- a/packages/reflex-components-moment/src/reflex_components_moment/moment.py +++ b/packages/reflex-components-moment/src/reflex_components_moment/moment.py @@ -8,7 +8,7 @@ from reflex_base.components.component import MemoizationLeaf, NoSSRComponent, field from reflex_base.event import EventHandler, passthrough_event_spec -from reflex_base.utils.imports import ImportDict +from reflex_base.utils.imports import ImportDict, ImportVar from reflex_base.vars.base import LiteralVar, Var @@ -133,5 +133,7 @@ def add_imports(self) -> ImportDict: imports[""] = "moment/min/locales" if self.tz is not None: imports["moment-timezone@0.6.2"] = "" + if self.duration is not None or self.duration_from_now is not None: + imports["moment-duration-format@2.2.2"] = ImportVar(tag=None) return imports diff --git a/tests/integration/test_moment.py b/tests/integration/test_moment.py index 3f996579e36..c24087641ca 100644 --- a/tests/integration/test_moment.py +++ b/tests/integration/test_moment.py @@ -29,9 +29,15 @@ def index(): "2026-08-30", format="YYYY-MM-DD", parse=["YYYY-MM-DD"], - trim="h [hours]", + trim="large", id="moment", ), + rx.moment( + date="2026-08-30T05:30:00", + duration="2026-08-30T00:00:00", + format="h [hrs] m [min]", + id="moment-duration", + ), ) @@ -75,3 +81,7 @@ def test_moment_2_props_render(driver: WebDriver) -> None: lambda: driver.find_element(By.ID, "moment") ) AppHarness.expect(lambda: moment.text == "2026-08-30") + moment_duration = AppHarness.poll_for_or_raise_timeout( + lambda: driver.find_element(By.ID, "moment-duration") + ) + AppHarness.expect(lambda: moment_duration.text == "5 hrs 30 min") diff --git a/tests/units/compiler/test_memoize_plugin.py b/tests/units/compiler/test_memoize_plugin.py index 2ec88b4c8ca..97233f6de7e 100644 --- a/tests/units/compiler/test_memoize_plugin.py +++ b/tests/units/compiler/test_memoize_plugin.py @@ -1851,11 +1851,11 @@ def test_moment_uses_react_moment_2_props_and_dependencies() -> None: moment = Moment.create( "2026-08-30", - trim="h [hours]", + trim="large", parse=["YYYY-MM-DD"], ) props = moment.render()["props"] - assert 'trim:"h [hours]"' in props + assert 'trim:"large"' in props assert 'parse:["YYYY-MM-DD"]' in props From 1b67baa3c3ceb0f8c63690575bb5cf76eb027ca5 Mon Sep 17 00:00:00 2001 From: Harsh Thakare Date: Tue, 1 Sep 2026 14:49:28 +0530 Subject: [PATCH 5/8] Strengthen moment duration regression coverage --- tests/units/compiler/test_memoize_plugin.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/units/compiler/test_memoize_plugin.py b/tests/units/compiler/test_memoize_plugin.py index 97233f6de7e..935db16ea6f 100644 --- a/tests/units/compiler/test_memoize_plugin.py +++ b/tests/units/compiler/test_memoize_plugin.py @@ -22,6 +22,7 @@ from reflex_base.constants.compiler import MemoizationDisposition, MemoizationMode from reflex_base.plugins import CompileContext, CompilerHooks, PageContext from reflex_base.utils import memo_paths +from reflex_base.utils.imports import ImportVar from reflex_base.vars import VarData from reflex_base.vars.base import Field, LiteralVar, Var, field from reflex_components_core.base.bare import Bare @@ -1842,7 +1843,7 @@ def test_moment_with_stateful_var_child_does_not_wrap_bare_independently() -> No def test_moment_uses_react_moment_2_props_and_dependencies() -> None: - """The wrapper should support the changed react-moment 2.x prop types.""" + """The wrapper exposes the react-moment 2.x props and dependencies.""" assert Moment.library == "react-moment@2.0.2" assert Moment.lib_dependencies == [ "moment@2.30.1", @@ -1858,6 +1859,14 @@ def test_moment_uses_react_moment_2_props_and_dependencies() -> None: assert 'trim:"large"' in props assert 'parse:["YYYY-MM-DD"]' in props + duration_from_now = Moment.create( + "2026-08-30", + duration_from_now=True, + ) + assert duration_from_now.add_imports()["moment-duration-format@2.2.2"] == ImportVar( + tag=None + ) + def test_moment_memo_body_renders_text_interpolation_not_bare_component() -> None: """The moment's memo body must interpolate the state Var as text, not a Bare wrapper.""" From 740c5d5e69c26d93fe731f3528cf4ae917b78dc0 Mon Sep 17 00:00:00 2001 From: Harsh Thakare Date: Tue, 1 Sep 2026 14:58:53 +0530 Subject: [PATCH 6/8] Cover moment duration trim behavior --- tests/integration/test_moment.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integration/test_moment.py b/tests/integration/test_moment.py index c24087641ca..c7457d54612 100644 --- a/tests/integration/test_moment.py +++ b/tests/integration/test_moment.py @@ -29,13 +29,13 @@ def index(): "2026-08-30", format="YYYY-MM-DD", parse=["YYYY-MM-DD"], - trim="large", id="moment", ), rx.moment( - date="2026-08-30T05:30:00", + date="2026-08-30T00:30:00", duration="2026-08-30T00:00:00", format="h [hrs] m [min]", + trim="large", id="moment-duration", ), ) @@ -84,4 +84,4 @@ def test_moment_2_props_render(driver: WebDriver) -> None: moment_duration = AppHarness.poll_for_or_raise_timeout( lambda: driver.find_element(By.ID, "moment-duration") ) - AppHarness.expect(lambda: moment_duration.text == "5 hrs 30 min") + AppHarness.expect(lambda: moment_duration.text == "30 mins") From 054c45c6f115cd4947ffbf5c650d5c862e33dc0a Mon Sep 17 00:00:00 2001 From: Farhan Date: Tue, 1 Sep 2026 20:18:22 +0500 Subject: [PATCH 7/8] Tighten Moment parse type and document widened props Narrow `parse` from `Var[str | list[Any]]` to `Var[str | list[str]]` to match react-moment's `MomentFormatSpecification`, which is a format string or a list of format strings. This drops the now-unused `Any` import. Document the widened forms of both props that this migration enables: `trim` also accepts a trim template ("large", "small", "both", "all", "final", "left", "right"), and `parse` also accepts a list of formats to try. Regenerate the Moment stub hash. --- .../src/reflex_components_moment/moment.py | 7 +++---- pyi_hashes.json | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/reflex-components-moment/src/reflex_components_moment/moment.py b/packages/reflex-components-moment/src/reflex_components_moment/moment.py index 22802f5922e..85832c7eecd 100644 --- a/packages/reflex-components-moment/src/reflex_components_moment/moment.py +++ b/packages/reflex-components-moment/src/reflex_components_moment/moment.py @@ -4,7 +4,6 @@ import dataclasses import datetime -from typing import Any from reflex_base.components.component import MemoizationLeaf, NoSSRComponent, field from reflex_base.event import EventHandler, passthrough_event_spec @@ -44,11 +43,11 @@ class Moment(NoSSRComponent, MemoizationLeaf): ) trim: Var[bool | str] = field( - doc="When formatting duration time, the largest-magnitude tokens are automatically trimmed when they have no value." + doc='When formatting duration time, the largest-magnitude tokens are automatically trimmed when they have no value. Also accepts a trim template: "large", "small", "both", "all", "final", "left" or "right".' ) - parse: Var[str | list[Any]] = field( - doc=" Use the parse attribute to tell moment how to parse the given date when non-standard." + parse: Var[str | list[str]] = field( + doc=" Use the parse attribute to tell moment how to parse the given date when non-standard. Accepts a single format string or a list of formats to try." ) add: Var[MomentDelta] = field( diff --git a/pyi_hashes.json b/pyi_hashes.json index 4be878964e0..42fc3e1c083 100644 --- a/pyi_hashes.json +++ b/pyi_hashes.json @@ -41,7 +41,7 @@ "packages/reflex-components-gridjs/src/reflex_components_gridjs/datatable.pyi": "2ce1c076ecf5c2fa4945b4abdbf2f91d", "packages/reflex-components-lucide/src/reflex_components_lucide/icon.pyi": "1e331a3d6420b97e5b1ce7f63ad53de8", "packages/reflex-components-markdown/src/reflex_components_markdown/markdown.pyi": "79d0a59b1ba12a2f2c4a09fa6b5c776f", - "packages/reflex-components-moment/src/reflex_components_moment/moment.pyi": "880ae7095693e0709ba4f5584ccae2d5", + "packages/reflex-components-moment/src/reflex_components_moment/moment.pyi": "92cc72695f0868cdbcec912e916541f2", "packages/reflex-components-plotly/src/reflex_components_plotly/plotly.pyi": "beb057e382e527224597c320dbb72385", "packages/reflex-components-radix/src/reflex_components_radix/__init__.pyi": "a77352f60fb6f4135b5d08a6e56efa6d", "packages/reflex-components-radix/src/reflex_components_radix/primitives/__init__.pyi": "bbd4d1a4fa73275a882c33ba485d0165", From 6c2b5286f01ab1661f61efd45d7809dd89109849 Mon Sep 17 00:00:00 2001 From: Harsh Thakare Date: Wed, 2 Sep 2026 11:48:25 +0530 Subject: [PATCH 8/8] Make Moment duration dependency conditional --- docs/app/reflex.lock/bun.lock | 3 --- docs/app/reflex.lock/package.json | 3 +-- .../src/reflex_components_moment/moment.py | 2 +- tests/units/compiler/test_memoize_plugin.py | 2 +- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/app/reflex.lock/bun.lock b/docs/app/reflex.lock/bun.lock index 64e906ef608..374eb444bcb 100644 --- a/docs/app/reflex.lock/bun.lock +++ b/docs/app/reflex.lock/bun.lock @@ -38,7 +38,6 @@ "lucide-react": "1.26.0", "mergician": "v2.0.2", "moment": "2.30.1", - "moment-duration-format": "2.2.2", "moment-timezone": "0.6.2", "plotly.js": "3.7.0", "plotly.js-locales": "3.7.0", @@ -1369,8 +1368,6 @@ "moment": ["moment@2.30.1", "", {}, "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how=="], - "moment-duration-format": ["moment-duration-format@2.2.2", "", {}, "sha512-NR6qiYywjQ6UdLCpfpg1WhaWdpAg4EHIaUGaTTgTLrPVooUKp7Q7eN/gmcUxp/dIL7+Rya+P0ApI/Ve1Nq7ycw=="], - "moment-timezone": ["moment-timezone@0.6.2", "", { "dependencies": { "moment": "^2.29.4" } }, "sha512-lDsQv8FoGdBUdf0+TjGsq2orxKuXdwFlQ6Zw6TX3xIcTwTfEpCLyKqvEauvCHJ8iu3KBV8+uPhlv70YsNGdUBQ=="], "mouse-event-offset": ["mouse-event-offset@3.0.2", "", {}, "sha512-s9sqOs5B1Ykox3Xo8b3Ss2IQju4UwlW6LSR+Q5FXWpprJ5fzMLefIIItr3PH8RwzfGy6gxs/4GAmiNuZScE25w=="], diff --git a/docs/app/reflex.lock/package.json b/docs/app/reflex.lock/package.json index 93440a453fd..b02e87b2670 100644 --- a/docs/app/reflex.lock/package.json +++ b/docs/app/reflex.lock/package.json @@ -39,7 +39,6 @@ "lucide-react": "1.26.0", "mergician": "v2.0.2", "moment": "2.30.1", - "moment-duration-format": "2.2.2", "moment-timezone": "0.6.2", "plotly.js": "3.7.0", "plotly.js-locales": "3.7.0", @@ -92,4 +91,4 @@ "vite": "8.2.0" }, "overrides": {} -} \ No newline at end of file +} diff --git a/packages/reflex-components-moment/src/reflex_components_moment/moment.py b/packages/reflex-components-moment/src/reflex_components_moment/moment.py index 85832c7eecd..734450f76e2 100644 --- a/packages/reflex-components-moment/src/reflex_components_moment/moment.py +++ b/packages/reflex-components-moment/src/reflex_components_moment/moment.py @@ -32,7 +32,7 @@ class Moment(NoSSRComponent, MemoizationLeaf): tag: str | None = "Moment" is_default = True library: str | None = "react-moment@2.0.2" - lib_dependencies: list[str] = ["moment@2.30.1", "moment-duration-format@2.2.2"] + lib_dependencies: list[str] = ["moment@2.30.1"] interval: Var[int] = field( doc="How often the date update (how often time update / 0 to disable)." diff --git a/tests/units/compiler/test_memoize_plugin.py b/tests/units/compiler/test_memoize_plugin.py index 935db16ea6f..c7b8615423d 100644 --- a/tests/units/compiler/test_memoize_plugin.py +++ b/tests/units/compiler/test_memoize_plugin.py @@ -1847,7 +1847,6 @@ def test_moment_uses_react_moment_2_props_and_dependencies() -> None: assert Moment.library == "react-moment@2.0.2" assert Moment.lib_dependencies == [ "moment@2.30.1", - "moment-duration-format@2.2.2", ] moment = Moment.create( @@ -1866,6 +1865,7 @@ def test_moment_uses_react_moment_2_props_and_dependencies() -> None: assert duration_from_now.add_imports()["moment-duration-format@2.2.2"] == ImportVar( tag=None ) + assert "moment-duration-format@2.2.2" not in moment.add_imports() def test_moment_memo_body_renders_text_interpolation_not_bare_component() -> None: