From 065b78fa3e89d4b8a13d8889232943a3686989e4 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Tue, 16 Jun 2026 17:55:37 +0200 Subject: [PATCH] fix(widgets): prevent TabsContainer state reset on data refetch react-jsx-parser auto-generates random keys on every render, causing full remounts that reset uncontrolled Tabs to defaultValue. Fix by: - Adding disableKeyGeneration to preserve React reconciliation - Memoizing bindings to avoid unnecessary re-parses - Converting TabsContainer to controlled Tabs with useState - Validating defaultTab against actual panel values - Clearing stale parseErrors when template/data changes --- packages/widgets/src/custom-api/custom-jsx-display.tsx | 10 ++++++++-- .../src/custom-api/jsx-interactive-components.tsx | 5 ++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/widgets/src/custom-api/custom-jsx-display.tsx b/packages/widgets/src/custom-api/custom-jsx-display.tsx index 43ed33c78..1a6bf2f93 100644 --- a/packages/widgets/src/custom-api/custom-jsx-display.tsx +++ b/packages/widgets/src/custom-api/custom-jsx-display.tsx @@ -1,6 +1,6 @@ "use client"; -import { useCallback, useState } from "react"; +import { useCallback, useEffect, useMemo, useState } from "react"; import JsxParser from "react-jsx-parser"; import { Alert, Stack, Text } from "@mantine/core"; import { IconAlertTriangle } from "@tabler/icons-react"; @@ -19,6 +19,11 @@ export default function CustomJsxDisplay({ data }: { data: Record([]); + const bindings = useMemo(() => SAFE_BINDINGS(apiData), [apiData]); + + useEffect(() => { + setParseErrors([]); + }, [template, bindings]); const handleError = useCallback((error: Error) => { setParseErrors((prev) => appendParseError(prev, error.message)); @@ -39,7 +44,8 @@ export default function CustomJsxDisplay({ data }: { data: Record p.props.value)); + const initialTab = (defaultTab && panelValues.has(defaultTab) ? defaultTab : firstPanel?.props.value) ?? null; + const [activeTab, setActiveTab] = useState(initialTab); return ( - + {panels.map((panel) => (