"use client" import * as React from "react" import { cn } from "../../lib/utils" import { Tabs, TabsContent, TabsList, TabsTrigger } from "./tabs" /** * A drop-in replacement for `@wordpress/components`' ``, built on `ui/tabs`. * *: 38 files, 143 tabs. WP's signature is kept EXACTLY so each conversion is a one-line * import swap rather than a hand rewrite inside a dense clinical form. * * The supported surface is measured from the real call sites, not invented: every tab carries * `name` + `title`, `disabled` appears on 2 of 143, and the render prop reads only `tab.name`. * WP's `onSelect`/`icon`/`activeClass`/`orientation` are deliberately NOT reproduced - nothing uses * them, and an unused option is a promise this adapter would have to keep. * * ONLY THE ACTIVE TAB'S CONTENT IS CONSTRUCTED, and that is the whole point of this file. * WP renders one panel and calls `children(selectedTab)` once * (`@wordpress/components/build/tab-panel/index.js`: `selectedTab && jsx(Ariakit.TabPanel, { * children: children(selectedTab) })`). * * The obvious Radix shape - a `` per tab - LOOKS equivalent and is not: JSX evaluates * `children(t)` eagerly for every tab, so inactive tabs' trees get built even though Radix never * displays them. These are react-hook-form clinical forms, where constructing a field registers it: * a tab nobody opened would start contributing form state. Hence the single, active-only panel below. * Pinned by the "render prop ONLY for the active tab" test. */ export interface TabPanelTab { name: string title: string disabled?: boolean } function TabPanel({ initialTabName, tabs, className, variant, listClassName, children, }: { initialTabName?: string tabs: TabPanelTab[] className?: string variant?: "default" | "line" listClassName?: string children: (tab: TabPanelTab) => React.ReactNode }) { const firstEnabled = tabs.find((t) => !t.disabled)?.name const [value, setValue] = React.useState( () => initialTabName ?? firstEnabled ?? tabs[0]?.name ?? "", ) // Fall back rather than render an empty panel if a caller passes an unknown initialTabName. const active = tabs.find((t) => t.name === value) ?? tabs.find((t) => t.name === firstEnabled) return ( {/* A form's strip wraps inside its sheet: on a phone a row of tabs wider than the sheet would scroll the form sideways. */} {tabs.map((t) => ( {t.title} ))} {active ? ( // ONE panel, for the ACTIVE tab only - see the note above before changing this to a map. {children(active)} ) : null} ) } export { TabPanel }