Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | /**
* @packageDocumentation
*
* Tabbed panel component for the editor sidebars. Renders a gradient
* header with clickable tabs and a content area that switches between
* the active tab's children.
*/
import { Flex } from "@radix-ui/themes";
import { useState, type ReactNode } from "react";
interface TabDef {
label: string;
content: ReactNode;
}
interface SidebarPanelProps {
tabs: TabDef[];
}
export function SidebarPanel({ tabs }: SidebarPanelProps) {
const [activeIndex, setActiveIndex] = useState(0);
return (
<Flex direction="column" style={{ marginBottom: 16 }}>
{/* Panel header with gradient */}
<Flex
style={{
padding: "8px 8px 0",
background: "linear-gradient(to bottom, var(--gray-3), var(--gray-4))",
}}
>
{tabs.map((tab, i) => {
const isActive = i === activeIndex;
return (
<button
key={tab.label}
type="button"
onClick={() => setActiveIndex(i)}
style={{
padding: "6px 12px",
fontSize: 11,
fontWeight: 700,
letterSpacing: "0.05em",
textTransform: "uppercase",
cursor: "pointer",
border: isActive ? "1px solid var(--gray-4)" : "1px solid transparent",
borderBottom: "none",
borderRadius: "4px 4px 0 0",
background: isActive
? "linear-gradient(to bottom, var(--gray-3), var(--gray-1))"
: "transparent",
color: isActive ? "var(--accent-9)" : "var(--gray-11)",
outline: "none",
fontFamily: "inherit",
lineHeight: 1,
}}
>
{tab.label}
</button>
);
})}
</Flex>
{/* Content area */}
<div
style={{
padding: "12px 8px",
background: "var(--gray-1)",
borderTop: "1px solid var(--gray-4)",
}}
>
{tabs.map((tab, i) => (
<div key={i} style={{ display: i === activeIndex ? undefined : "none" }}>
{tab.content}
</div>
))}
</div>
</Flex>
);
}
|