Skip to content

Instantly share code, notes, and snippets.

@DominikStyp
Created December 12, 2022 16:31
Show Gist options
  • Save DominikStyp/f28084244bce69f07405208ec17bbef4 to your computer and use it in GitHub Desktop.
Save DominikStyp/f28084244bce69f07405208ec17bbef4 to your computer and use it in GitHub Desktop.
React + TypeScript generic components
// App.tsx
// usage example
import { useState } from 'react';
import { TabBar } from '../../../shared/components/TabBar';
interface MySocial {
id: number;
name: string;
link: string;
}
const socials: MySocial[] = [
{ id: 11, name: 'WebSite', link: 'fabiobiondi.dev'},
{ id: 12, name: 'Youtube', link: 'YT'},
{ id: 13, name: 'Twitch', link: 'twitch'},
]
export const App = () => {
const [selectedSocial, setSelectedSocial] = useState<MySocial>(socials[0])
function selectHandler(item: MySocial, selectedIndex: number) {
setSelectedSocial(item)
}
return (
<div>
<h1>Tabbar Demo</h1>
<TabBar<MySocial>
selectedItem={selectedSocial}
items={socials}
onTabClick={selectHandler}
/>
<div className="border border-slate-200 border-solid rounded my-3 p-5">
<a href={selectedSocial.link}>Visit {selectedSocial.name}</a>
</div>
</div>
)
};
// TabBar.tsx
interface TabBarProps<T> {
items: T[];
selectedItem: T;
onTabClick: (item: T, selectedIndex: number) => void
}
export function TabBar<T extends { id: number, name: string}>(props: TabBarProps<T>) {
const { items, selectedItem, onTabClick} = props;
return (
<>
<div className="flex gap-x-3">
{
items.map((item, index) => {
const activeCls = item.id === selectedItem.id ? 'bg-slate-500 text-white' : ' bg-slate-200';
return <div
key={item.id}
className={'py-2 px-4 rounded ' + activeCls}
onClick={() => onTabClick(item, index)}
>
{item.name}
</div>
}
)
}
</div>
</>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment