"use client"; import { ChatGPT } from "@/components/examples/chatgpt"; import { Claude } from "@/components/examples/claude"; import { Perplexity } from "@/components/examples/perplexity"; import { Base } from "@/components/examples/base"; import { Tab } from "@/components/shared/tab"; import { DocsRuntimeProvider } from "@/contexts/DocsRuntimeProvider"; import { Gemini } from "@/components/examples/gemini"; import { Grok } from "@/components/examples/grok"; import { analytics } from "@/lib/analytics"; import { Button } from "@/components/ui/radix/button"; import { cn } from "@/lib/utils"; import { ArrowUpRightIcon, Maximize2Icon, XIcon } from "lucide-react"; import Link from "next/link"; import React from "react"; import { flushSync } from "react-dom"; const ExampleWrapper = ({ children }: { children: React.ReactNode }) => (
{children}
); const EXAMPLE_TABS = [ { label: "Base", slug: "base", value: ( ), }, { label: "ChatGPT", slug: "chatgpt", value: ( ), }, { label: "Claude", slug: "claude", value: ( ), }, { label: "Grok", slug: "grok", value: ( ), }, { label: "Gemini", slug: "gemini", value: ( ), }, { label: "Perplexity", slug: "perplexity", value: ( ), }, { label: "Explore More →", href: "/examples", }, ]; const prefersReducedMotion = () => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches; export function ExampleShowcase() { const sectionRef = React.useRef(null); const panelRef = React.useRef(null); const animationRef = React.useRef(null); const [activeIndex, setActiveIndex] = React.useState(0); const [isFullscreen, setIsFullscreen] = React.useState(false); // FLIP: measure the panel before and after toggling between its inline // `absolute` slot and `fixed inset-0`, then tween width/height plus a // translate offset. The content keeps its real pixel size throughout (no // scaling), so nothing stretches the way a View Transition's bitmap morph — // or a non-uniform transform scale across the aspect-ratio change — would. const toggleFullscreen = React.useCallback(() => { const el = panelRef.current; if (!el || prefersReducedMotion()) { setIsFullscreen((value) => !value); return; } const first = el.getBoundingClientRect(); flushSync(() => setIsFullscreen((value) => !value)); const last = el.getBoundingClientRect(); const expanding = last.height > first.height; animationRef.current?.cancel(); animationRef.current = el.animate( [ { transform: `translate(${first.left - last.left}px, ${first.top - last.top}px)`, width: `${first.width}px`, height: `${first.height}px`, }, { transform: "translate(0px, 0px)", width: `${last.width}px`, height: `${last.height}px`, }, ], { duration: expanding ? 350 : 250, easing: "cubic-bezier(0.32, 0.72, 0, 1)", }, ); }, []); // Radix portals mount into , so a portaled dropdown's contents fail // the shell containment check; require the target to sit inside the panel. const isOutsideShell = React.useCallback( (target: EventTarget | null) => target instanceof Element && panelRef.current?.contains(target) === true && !target.closest( '[data-slot="example-shell"], [data-slot="tab-item"], [data-slot="tab-actions"]', ), [], ); // Inline, the demo is a static preview: clicking anywhere except the tab bar // expands it to fullscreen, where it becomes interactive. Fullscreen, the // same click on the padding around the shell exits. const handlePanelClick = (e: React.MouseEvent) => { if (isFullscreen) { if (e.defaultPrevented) return; if (isOutsideShell(e.target)) toggleFullscreen(); return; } if ((e.target as HTMLElement).closest('[data-slot="tab-list"]')) return; toggleFullscreen(); }; React.useEffect(() => { if (!isFullscreen) return; const handleKeyDown = (e: KeyboardEvent) => { // An open Radix layer (dropdown, popover, dialog) handles Escape in the // capture phase and preventDefaults it; let that close first, don't unzoom. if (e.defaultPrevented) return; if (e.key === "Escape") toggleFullscreen(); }; // Page scroll is locked, so a wheel gesture outside the shell can only // mean "get back to the page". The deltaY check keeps horizontal trackpad // swipes over the overflow-x tab bar from exiting. const handleWheel = (e: WheelEvent) => { if (Math.abs(e.deltaY) <= Math.abs(e.deltaX)) return; if (isOutsideShell(e.target)) toggleFullscreen(); }; document.addEventListener("keydown", handleKeyDown); document.addEventListener("wheel", handleWheel, { passive: true }); document.body.style.overflow = "hidden"; // The homepage
creates a z-2 stacking context, which would paint // the overlay beneath the sticky z-50 site header. const stackingAncestor = sectionRef.current?.closest("main"); if (stackingAncestor instanceof HTMLElement) { stackingAncestor.style.zIndex = "50"; } // The panel stays in the page's DOM (no portal), so keep Tab focus inside // by inerting every element outside its ancestor chain. Radix portals // opened while zoomed mount into afterwards and stay interactive. const inertedSiblings: HTMLElement[] = []; for ( let node: HTMLElement | null = panelRef.current; node && node !== document.body; node = node.parentElement ) { for (const sibling of node.parentElement?.children ?? []) { if ( sibling !== node && sibling instanceof HTMLElement && !sibling.inert ) { sibling.inert = true; inertedSiblings.push(sibling); } } } return () => { document.removeEventListener("keydown", handleKeyDown); document.removeEventListener("wheel", handleWheel); document.body.style.overflow = ""; if (stackingAncestor instanceof HTMLElement) { stackingAncestor.style.zIndex = ""; } for (const sibling of inertedSiblings) { sibling.inert = false; } }; }, [isFullscreen, isOutsideShell, toggleFullscreen]); const activeSlug = EXAMPLE_TABS[activeIndex]?.slug; return (
{/* Placeholder reserves the inline height so the page doesn't jump when the panel detaches to fullscreen. */}
{ setActiveIndex(index); analytics.example.tabSwitched(label); }} actions={ <> {activeSlug && ( )} } />
); }