From eb4e0bddabb41f36a994e90f13c531034df780ca Mon Sep 17 00:00:00 2001 From: Krishna Tripathi Date: Fri, 31 Oct 2025 18:01:14 +0530 Subject: [PATCH 1/3] fix: support lowercase member expressions in JSX elements This fixes issue #1165 where JSX elements using member expressions with lowercase variable names (e.g., form.Button) were incorrectly treated as HTML element strings instead of React component identifiers. The compiler was only checking if element names started with an uppercase letter, which broke common library patterns like Tanstack Forms that use lowercase variables with member expressions. Changes: - Updated jsx-scope-inject.ts to check for member expressions (containing dots) before checking case sensitivity - Now both 'form.Button' and 'Form.Button' are correctly treated as component identifiers - Added test component demonstrating the fix works with both cases This allows developers to use standard library conventions without being forced to use uppercase variable names as a workaround. Fixes #1165 --- .../src/components/tanstack-form-test.tsx | 123 ++++++++++++++++++ packages/compiler/src/jsx-scope-inject.ts | 5 +- 2 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 demo/vite-project/src/components/tanstack-form-test.tsx diff --git a/demo/vite-project/src/components/tanstack-form-test.tsx b/demo/vite-project/src/components/tanstack-form-test.tsx new file mode 100644 index 000000000..7cd350245 --- /dev/null +++ b/demo/vite-project/src/components/tanstack-form-test.tsx @@ -0,0 +1,123 @@ +import React from 'react'; + +// Simulating Tanstack Forms pattern +function useForm() { + return { + AppForm: ({ children }: { children: React.ReactNode }) => ( +
{children}
+ ), + CancelButton: ({ children, onClick }: { children: React.ReactNode; onClick?: () => void }) => ( + + ), + SubmitButton: ({ children }: { children: React.ReactNode }) => ( + + ), + }; +} + +// Simulating uppercase workaround +function useFormUppercase() { + return { + AppForm: ({ children }: { children: React.ReactNode }) => ( +
{children}
+ ), + CancelButton: ({ children, onClick }: { children: React.ReactNode; onClick?: () => void }) => ( + + ), + SubmitButton: ({ children }: { children: React.ReactNode }) => ( + + ), + }; +} + +export default function TanstackFormTest() { + const form = useForm(); + const FormContent = useFormUppercase(); + + const handleCancel = () => { + alert('Cancel clicked!'); + }; + + return ( +
+

Tanstack Forms + Lingo.dev Compiler Issue #1165

+ +
+

❌ Broken: Lowercase variable name (form)

+

Using: const form = useForm()

+

Expected: Blue border, styled buttons with click functionality

+ +
+ Cancel + Submit +
+
+
+ +
+

✅ Working: Uppercase variable name (FormContent)

+

Using: const FormContent = useFormUppercase()

+

Expected: Green border, styled buttons with click functionality

+ +
+ Cancel + Submit +
+
+
+
+ ); +} + diff --git a/packages/compiler/src/jsx-scope-inject.ts b/packages/compiler/src/jsx-scope-inject.ts index d1003a68a..87e52b18d 100644 --- a/packages/compiler/src/jsx-scope-inject.ts +++ b/packages/compiler/src/jsx-scope-inject.ts @@ -55,7 +55,10 @@ export const lingoJsxScopeInjectMutation = createCodeMutation((payload) => { } as any; // Add $as prop - const as = /^[A-Z]/.test(originalJsxElementName) + // Check if it's a member expression (contains dot) or starts with uppercase + const isMemberExpression = originalJsxElementName.includes("."); + const isComponent = /^[A-Z]/.test(originalJsxElementName); + const as = isMemberExpression || isComponent ? t.identifier(originalJsxElementName) : originalJsxElementName; setJsxAttributeValue(newNodePath, "$as", as); From 862c0feb41f80dee21faca2f30261cc402854dc1 Mon Sep 17 00:00:00 2001 From: Krishna Tripathi <121955562+codesmith17@users.noreply.github.com> Date: Fri, 31 Oct 2025 18:07:40 +0530 Subject: [PATCH 2/3] Update tanstack-form-test.tsx --- demo/vite-project/src/components/tanstack-form-test.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/vite-project/src/components/tanstack-form-test.tsx b/demo/vite-project/src/components/tanstack-form-test.tsx index 7cd350245..709b2916d 100644 --- a/demo/vite-project/src/components/tanstack-form-test.tsx +++ b/demo/vite-project/src/components/tanstack-form-test.tsx @@ -95,7 +95,7 @@ export default function TanstackFormTest() {

Tanstack Forms + Lingo.dev Compiler Issue #1165

-

❌ Broken: Lowercase variable name (form)

+

Broken: Lowercase variable name (form)

Using: const form = useForm()

Expected: Blue border, styled buttons with click functionality

@@ -107,7 +107,7 @@ export default function TanstackFormTest() {
-

✅ Working: Uppercase variable name (FormContent)

+

Working: Uppercase variable name (FormContent)

Using: const FormContent = useFormUppercase()

Expected: Green border, styled buttons with click functionality

From c9e7eb4d60badfc0f6d24775c4ca9e6613832418 Mon Sep 17 00:00:00 2001 From: Krishna Tripathi Date: Fri, 14 Nov 2025 10:38:40 +0530 Subject: [PATCH 3/3] fix: properly handle member expressions in AST generation - Add createMemberExpressionFromString() helper to build correct AST nodes - Fix bug where t.identifier() was incorrectly used with dotted strings like 'form.Button' - Improve code comments to explain member expression handling rationale - Update demo heading to reflect that the issue is now fixed This addresses all review comments from PR #1474 --- .../src/components/tanstack-form-test.tsx | 36 +++++++++---------- packages/compiler/src/jsx-scope-inject.ts | 25 +++++++++++-- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/demo/vite-project/src/components/tanstack-form-test.tsx b/demo/vite-project/src/components/tanstack-form-test.tsx index 709b2916d..247060b8b 100644 --- a/demo/vite-project/src/components/tanstack-form-test.tsx +++ b/demo/vite-project/src/components/tanstack-form-test.tsx @@ -7,12 +7,12 @@ function useForm() {
{children}
), CancelButton: ({ children, onClick }: { children: React.ReactNode; onClick?: () => void }) => ( -