diff --git a/docs/app/reflex.lock/bun.lock b/docs/app/reflex.lock/bun.lock index 0873ef2f6ed..00a5ef7e904 100644 --- a/docs/app/reflex.lock/bun.lock +++ b/docs/app/reflex.lock/bun.lock @@ -27,6 +27,7 @@ "ag-grid-community": "34.3.1", "ag-grid-enterprise": "34.3.1", "ag-grid-react": "34.3.1", + "clsx": "2.1.1", "clsx-for-tailwind": "1.0.0", "es-toolkit": "1.46.1", "gridjs": "6.2.0", @@ -72,6 +73,7 @@ "shiki": "3.3.0", "socket.io-client": "4.8.3", "sonner": "2.0.7", + "tailwind-merge": "3.6.0", "tailwindcss-animated": "2.0.0", "tailwindcss-scroll-mask": "0.0.3", "universal-cookie": "7.2.2", @@ -1941,7 +1943,7 @@ "tabbable": ["tabbable@6.4.0", "", {}, "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg=="], - "tailwind-merge": ["tailwind-merge@2.6.1", "", {}, "sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ=="], + "tailwind-merge": ["tailwind-merge@3.6.0", "", {}, "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w=="], "tailwindcss": ["tailwindcss@4.3.0", "", {}, "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q=="], @@ -2509,6 +2511,8 @@ "ag-grid-enterprise/ag-charts-enterprise": ["ag-charts-enterprise@12.3.1", "", { "dependencies": { "ag-charts-community": "12.3.1", "ag-charts-core": "12.3.1" } }, "sha512-2sQIwLfksRTcI4JVRjgQkyGq6z68UVTO/I91HKmtpukrQLsW/o0TzzHmgTtVJOXd9yO9gx2KWa2DMg0+FKdXEQ=="], + "clsx-for-tailwind/tailwind-merge": ["tailwind-merge@2.6.1", "", {}, "sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ=="], + "color-alpha/color-parse": ["color-parse@1.4.3", "", { "dependencies": { "color-name": "^1.0.0" } }, "sha512-BADfVl/FHkQkyo8sRBwMYBqemqsgnu7JZAwUgvBvuwwuNUZAhSvLTbsEErS5bQXzOjDR0dWzJ4vXN2Q+QoPx0A=="], "color-normalize/color-rgba": ["color-rgba@2.4.0", "", { "dependencies": { "color-parse": "^1.4.2", "color-space": "^2.0.0" } }, "sha512-Nti4qbzr/z2LbUWySr7H9dk3Rl7gZt7ihHAxlgT4Ho90EXWkjtkL1avTleu9yeGuqrt/chxTB6GKK8nZZ6V0+Q=="], diff --git a/docs/app/reflex.lock/package.json b/docs/app/reflex.lock/package.json index 4be32ab0fe6..a301082f7f8 100644 --- a/docs/app/reflex.lock/package.json +++ b/docs/app/reflex.lock/package.json @@ -28,6 +28,7 @@ "ag-grid-community": "34.3.1", "ag-grid-enterprise": "34.3.1", "ag-grid-react": "34.3.1", + "clsx": "2.1.1", "clsx-for-tailwind": "1.0.0", "es-toolkit": "1.46.1", "gridjs": "6.2.0", @@ -73,6 +74,7 @@ "shiki": "3.3.0", "socket.io-client": "4.8.3", "sonner": "2.0.7", + "tailwind-merge": "3.6.0", "tailwindcss-animated": "2.0.0", "tailwindcss-scroll-mask": "0.0.3", "universal-cookie": "7.2.2", diff --git a/packages/reflex-components-internal/src/reflex_components_internal/utils/twmerge.py b/packages/reflex-components-internal/src/reflex_components_internal/utils/twmerge.py index 688f59a65eb..149101176db 100644 --- a/packages/reflex-components-internal/src/reflex_components_internal/utils/twmerge.py +++ b/packages/reflex-components-internal/src/reflex_components_internal/utils/twmerge.py @@ -4,9 +4,14 @@ from reflex.vars import FunctionVar, Var from reflex.vars.base import VarData -CN = Var( - "cn", - _var_data=VarData(imports={"clsx-for-tailwind@1.0.0": ImportVar(tag="cn")}), +CLSX = Var( + "clsx", + _var_data=VarData(imports={"clsx@2.1.1": ImportVar(tag="clsx", is_default=True)}), +).to(FunctionVar) + +TW_MERGE = Var( + "twMerge", + _var_data=VarData(imports={"tailwind-merge@3.6.0": ImportVar(tag="twMerge")}), ).to(FunctionVar) @@ -22,4 +27,4 @@ def cn( Var: A Var representing the merged classes string. """ - return CN.call(*classes).to(str) + return TW_MERGE.call(CLSX.call(*classes)).to(str) diff --git a/tests/units/reflex_components_internal/utils/test_twmerge.py b/tests/units/reflex_components_internal/utils/test_twmerge.py new file mode 100644 index 00000000000..6e2d82a054f --- /dev/null +++ b/tests/units/reflex_components_internal/utils/test_twmerge.py @@ -0,0 +1,24 @@ +from reflex_base.utils.imports import ImportVar +from reflex_base.vars import Var +from reflex_components_internal.utils.twmerge import cn + + +def test_cn_uses_clsx_and_tailwind_merge() -> None: + """The class utility should flatten inputs before resolving Tailwind conflicts.""" + merged = cn( + "px-2", + Var("dynamic"), + ["px-4", None], + ("font-bold",), + ) + + assert ( + str(merged) + == '(twMerge((clsx("px-2", dynamic, ["px-4", null], ["font-bold"]))))' + ) + var_data = merged._get_all_var_data() + assert var_data is not None + assert dict(var_data.imports) == { + "clsx@2.1.1": (ImportVar(tag="clsx", is_default=True),), + "tailwind-merge@3.6.0": (ImportVar(tag="twMerge"),), + }