From b58d3530e38bd6074f3b68afe27e280c6968f7f8 Mon Sep 17 00:00:00 2001 From: vaibhav0725 Date: Sun, 19 Jul 2026 20:50:44 +0530 Subject: [PATCH] refactor: replace CodeLangToggle with CodeExampleClient for improved language toggling in CodeExample component --- apps/marketing/src/components/CodeExample.tsx | 65 +++++++---------- .../src/components/CodeExampleClient.tsx | 70 +++++++++++++++++++ .../src/components/CodeLangToggle.tsx | 33 ++------- 3 files changed, 100 insertions(+), 68 deletions(-) create mode 100644 apps/marketing/src/components/CodeExampleClient.tsx diff --git a/apps/marketing/src/components/CodeExample.tsx b/apps/marketing/src/components/CodeExample.tsx index e6667fd2..9f03d5cf 100644 --- a/apps/marketing/src/components/CodeExample.tsx +++ b/apps/marketing/src/components/CodeExample.tsx @@ -1,7 +1,7 @@ import { Button } from "@usesend/ui/src/button"; import { CodeBlock } from "@usesend/ui/src/code-block"; import { CodeBlockWithCopy } from "@usesend/ui/src/code-block-with-copy"; -import { LangToggle } from "./CodeLangToggle"; +import { CodeExampleClient } from "./CodeExampleClient"; const TS_CODE = `import { UseSend } from "usesend-js"; @@ -82,8 +82,7 @@ if ($response === false) { } curl_close($ch);`; -export function CodeExample() { - const containerId = "code-example"; +export async function CodeExample() { const languages = [ { key: "ts", @@ -115,6 +114,19 @@ export function CodeExample() { }, ]; + const panels = Object.fromEntries( + await Promise.all( + languages.map(async (l) => [ + l.key, + + + {l.code} + + , + ]) + ) + ); + return (
@@ -128,44 +140,15 @@ export function CodeExample() {

-
-
- ({ - key, - label, - kind, - }))} - /> -
-
-
-
- {languages.map((l, idx) => ( -
- {/* Cast to any to align with shiki BundledLanguage without importing types here */} - - - {l.code} - - -
- ))} -
-
-
-
- Language example toggled -
+
+ ({ + key, + label, + kind, + }))} + panels={panels} + />
diff --git a/apps/marketing/src/components/CodeExampleClient.tsx b/apps/marketing/src/components/CodeExampleClient.tsx new file mode 100644 index 00000000..4c9b554b --- /dev/null +++ b/apps/marketing/src/components/CodeExampleClient.tsx @@ -0,0 +1,70 @@ +"use client"; + +import { useLayoutEffect, useRef, useState, type ReactNode } from "react"; +import { LangToggle } from "./CodeLangToggle"; + +type LangItem = { + key: string; + label: string; + kind: string; +}; + +export function CodeExampleClient({ + languages, + panels, +}: { + languages: LangItem[]; + panels: Record; +}) { + const [activeLang, setActiveLang] = useState(languages[0]?.key ?? "ts"); + const contentRef = useRef(null); + const [height, setHeight] = useState(); + + useLayoutEffect(() => { + const el = contentRef.current; + if (!el) return; + + const measure = () => setHeight(el.scrollHeight); + measure(); + + const observer = new ResizeObserver(measure); + observer.observe(el); + return () => observer.disconnect(); + }, [activeLang]); + + return ( + <> +
+ +
+
+
+
+
+ {languages.map((l) => ( +
+ {panels[l.key]} +
+ ))} +
+
+
+
+
+ Language example toggled +
+ + ); +} + +export default CodeExampleClient; diff --git a/apps/marketing/src/components/CodeLangToggle.tsx b/apps/marketing/src/components/CodeLangToggle.tsx index 08d04065..53528ce7 100644 --- a/apps/marketing/src/components/CodeLangToggle.tsx +++ b/apps/marketing/src/components/CodeLangToggle.tsx @@ -1,6 +1,6 @@ "use client"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import Image from "next/image"; import { Button } from "@usesend/ui/src/button"; @@ -11,35 +11,14 @@ type LangItem = { }; export function LangToggle({ - containerId, languages, - defaultLang, + active, + onActiveChange, }: { - containerId: string; languages: LangItem[]; - defaultLang: string; + active: string; + onActiveChange: (key: string) => void; }) { - const [active, setActive] = useState(defaultLang); - - useEffect(() => { - const container = document.getElementById(containerId); - if (!container) return; - - const slots = Array.from( - container.querySelectorAll("[data-lang-slot]") - ); - for (const el of slots) { - const key = el.getAttribute("data-lang-slot"); - if (key === active) { - el.classList.remove("hidden"); - el.classList.add("block"); - } else { - el.classList.add("hidden"); - el.classList.remove("block"); - } - } - }, [active, containerId]); - return (
{languages.map((l) => ( @@ -54,7 +33,7 @@ export function LangToggle({ : "border-input") } aria-pressed={active === l.key} - onClick={() => setActive(l.key)} + onClick={() => onActiveChange(l.key)} > {l.label}