Skip to content

Instantly share code, notes, and snippets.

@scwood
Created January 17, 2023 22:50
Show Gist options
  • Save scwood/78bbd92343dddd277a90138458d6d424 to your computer and use it in GitHub Desktop.
Save scwood/78bbd92343dddd277a90138458d6d424 to your computer and use it in GitHub Desktop.
Generic tabs component example
import { useState, Children, ReactElement, ReactNode } from "react";
export function App() {
return (
<Tabs>
<Tab name="Division">Division content!</Tab>
<Tab name="Wild card">Wild card content!</Tab>
<Tab name="Conference">Conference content!</Tab>
<Tab name="League">League content!</Tab>
</Tabs>
);
}
export interface TabsProps {
children: ReactElement<TabProps> | ReactElement<TabProps>[];
}
export function Tabs(props: TabsProps) {
const { children } = props;
const [selectedIndex, setSelectedIndex] = useState(0);
const tabNames = Children.map(children, (child) => child.props.name);
const tabContent = Children.map(children, (child) => child.props.children);
return (
<div>
<div>
{tabNames.map((name, index) => (
<button
key={index}
style={{
// Using text color as a simple way to show which tab is
// selected, replace with however ya'll do it
color: index === selectedIndex ? "crimson" : undefined,
}}
onClick={() => setSelectedIndex(index)}
>
{name}
</button>
))}
</div>
<div>{tabContent[selectedIndex]}</div>
</div>
);
}
export interface TabProps {
name: string;
children: ReactNode;
}
/**
* This component is kinda odd, because the parent component picks out the
* props, so we don't actually don't have to render anything in this component.
* Not sure if this is common pattern or not lol.
*/
export function Tab(props: TabProps) {
return <></>;
}
@scwood
Copy link
Author

scwood commented Jan 17, 2023

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment