Files
tnsu-ui-kit/src/Tabs/Tabs.tsx
T
Тимур Городецкий 6bf198f8f2 feat: Tabs (0.7.0)
2026-08-17 10:17:50 +05:00

46 lines
1.6 KiB
TypeScript

import * as React from 'react';
import styles from './Tabs.module.scss';
import { Icon } from '../Icon/Icon';
import { IconName } from '../Icon/iconNames';
export interface ITab {
id: string | number;
label: React.ReactNode;
/** Счётчик после подписи, напр. «(71)». undefined/0 — не показывать. */
count?: number;
/** Иконка слева (необязательно). */
icon?: IconName;
}
export interface ITabsProps {
tabs: ITab[];
activeId: string | number;
onChange: (id: string | number) => void;
}
/**
* Горизонтальные вкладки: активная — navy с золотым подчёркиванием. Управляемый.
* На узких экранах прокручивается вбок (не ломается). Подходит и для очередей со
* счётчиками (реестр), и для категорий с иконками.
*/
export const Tabs: React.FC<ITabsProps> = ({ tabs, activeId, onChange }) => (
<nav className={styles.tabs} aria-label="Вкладки">
{tabs.map((t) => {
const isActive = t.id === activeId;
return (
<button
key={t.id}
type="button"
className={[styles.tab, isActive ? styles.active : ''].filter(Boolean).join(' ')}
aria-current={isActive ? 'page' : undefined}
onClick={() => onChange(t.id)}
>
{t.icon && <Icon name={t.icon} size="sm" />}
<span>{t.label}</span>
{!!t.count && <span className={styles.count}>({t.count})</span>}
</button>
);
})}
</nav>
);