2022-11-16 10:08:09 +01:00
|
|
|
import { ReactNode, useEffect, useState } from 'react';
|
|
|
|
import * as React from 'react';
|
2022-11-22 17:43:19 +01:00
|
|
|
import _ from 'lodash';
|
|
|
|
import { usePrevious } from '../../lib/use-previous';
|
2022-11-14 17:54:14 +01:00
|
|
|
|
|
|
|
type tabId = string|number;
|
|
|
|
|
|
|
|
interface Tab {
|
|
|
|
id: tabId,
|
|
|
|
title: ReactNode,
|
|
|
|
content: ReactNode,
|
|
|
|
onSelected?: () => void,
|
|
|
|
}
|
|
|
|
|
|
|
|
interface FabTabsProps {
|
|
|
|
tabs: Array<Tab>,
|
|
|
|
defaultTab?: tabId,
|
|
|
|
className?: string
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tabulation system
|
|
|
|
*/
|
|
|
|
export const FabTabs: React.FC<FabTabsProps> = ({ tabs, defaultTab, className }) => {
|
|
|
|
const [active, setActive] = useState<Tab>(tabs.filter(Boolean).find(t => t.id === defaultTab) || tabs.filter(Boolean)[0]);
|
2022-11-22 17:43:19 +01:00
|
|
|
const previousTabs = usePrevious<Tab[]>(tabs);
|
2022-11-14 17:54:14 +01:00
|
|
|
|
|
|
|
useEffect(() => {
|
2022-11-22 17:43:19 +01:00
|
|
|
if (!_.isEqual(previousTabs?.filter(Boolean).map(t => t.id), tabs?.filter(Boolean).map(t => t?.id))) {
|
|
|
|
setActive(tabs.filter(Boolean).find(t => t.id === defaultTab) || tabs.filter(Boolean)[0]);
|
|
|
|
}
|
2022-11-14 17:54:14 +01:00
|
|
|
}, [tabs]);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback triggered when a tab a selected
|
|
|
|
*/
|
|
|
|
const onTabSelected = (tab: Tab) => {
|
|
|
|
setActive(tab);
|
|
|
|
if (typeof tab.onSelected === 'function') tab.onSelected();
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className={`fab-tabs ${className || ''}`}>
|
|
|
|
<div className="tabs">
|
|
|
|
{tabs.filter(Boolean).map((tab, index) => (
|
|
|
|
<p key={index} className={active?.id === tab.id ? 'is-active' : ''} onClick={() => onTabSelected(tab)}>{tab.title}</p>
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
{active?.content}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|