feat: Tabs (0.7.0)
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
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>
|
||||
);
|
||||
Reference in New Issue
Block a user