color-q/src/components/Tab.tsx
2025-02-17 13:11:21 +08:00

55 lines
1.5 KiB
TypeScript

import cx from 'clsx';
import { isEqual, isNil } from 'lodash-es';
import { useCallback, useEffect, useState } from 'react';
import styles from './Tab.module.css';
type TabOption = {
title: string;
id: string;
};
type TabProps = {
tabs: TabOption[];
activeTab?: unknown;
onActive?: (id: TabOption['id']) => void;
disabled?: Record<TabOption['id'], boolean>;
};
export function Tab({ tabs = [], activeTab, onActive, disabled }: TabProps) {
const [active, setActive] = useState(() =>
isNil(activeTab) ? 0 : tabs.findIndex((tab) => isEqual(tab.id, activeTab)),
);
const handleActivate = useCallback(
(index: number) => {
if (disabled?.[tabs[index].id] ?? false) return;
setActive(index);
onActive?.(tabs[index].id);
},
[tabs, onActive, disabled],
);
useEffect(() => {
const activeIndex = tabs.findIndex((tab) => isEqual(tab.id, activeTab));
if (!isNil(activeIndex) && !isEqual(activeIndex, -1) && !isEqual(activeIndex, active)) {
setActive(activeIndex);
}
}, [activeTab]);
return (
<div className={styles.tabs_container}>
{tabs.map((tab, index) => (
<div
key={`tab_${index}_${tab.id}`}
className={cx(
styles.tab,
isEqual(index, active) && styles.actived,
(disabled?.[tab.id] ?? false) && styles.disabled,
)}
onClick={() => handleActivate(index)}>
{tab.title}
</div>
))}
</div>
);
}