|
|
|
@ -17,10 +17,13 @@ const HORIZONTAL_PADDING = 8;
|
|
|
|
|
const AnimatedContext = React.createContext(null);
|
|
|
|
|
|
|
|
|
|
interface IAnimatedInterface {
|
|
|
|
|
/** Callback when a tab is chosen. */
|
|
|
|
|
onChange(index: number): void,
|
|
|
|
|
/** Default tab index. */
|
|
|
|
|
defaultIndex: number
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Tabs with a sliding active state. */
|
|
|
|
|
const AnimatedTabs: React.FC<IAnimatedInterface> = ({ children, ...rest }) => {
|
|
|
|
|
const [activeRect, setActiveRect] = React.useState(null);
|
|
|
|
|
const ref = React.useRef();
|
|
|
|
@ -58,13 +61,19 @@ const AnimatedTabs: React.FC<IAnimatedInterface> = ({ children, ...rest }) => {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
interface IAnimatedTab {
|
|
|
|
|
/** ARIA role. */
|
|
|
|
|
role: 'button',
|
|
|
|
|
/** Element to represent the tab. */
|
|
|
|
|
as: 'a' | 'button',
|
|
|
|
|
/** Route to visit when the tab is chosen. */
|
|
|
|
|
href?: string,
|
|
|
|
|
/** Tab title text. */
|
|
|
|
|
title: string,
|
|
|
|
|
/** Index value of the tab. */
|
|
|
|
|
index: number
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** A single animated tab. */
|
|
|
|
|
const AnimatedTab: React.FC<IAnimatedTab> = ({ index, ...props }) => {
|
|
|
|
|
// get the currently selected index from useTabsContext
|
|
|
|
|
const { selectedIndex } = useTabsContext();
|
|
|
|
@ -91,20 +100,32 @@ const AnimatedTab: React.FC<IAnimatedTab> = ({ index, ...props }) => {
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** Structure to represent a tab. */
|
|
|
|
|
type Item = {
|
|
|
|
|
/** Tab text. */
|
|
|
|
|
text: React.ReactNode,
|
|
|
|
|
/** Tab tooltip text. */
|
|
|
|
|
title?: string,
|
|
|
|
|
/** URL to visit when the tab is selected. */
|
|
|
|
|
href?: string,
|
|
|
|
|
/** Route to visit when the tab is selected. */
|
|
|
|
|
to?: string,
|
|
|
|
|
/** Callback when the tab is selected. */
|
|
|
|
|
action?: () => void,
|
|
|
|
|
/** Display a counter over the tab. */
|
|
|
|
|
count?: number,
|
|
|
|
|
/** Unique name for this tab. */
|
|
|
|
|
name: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface ITabs {
|
|
|
|
|
/** Array of structured tab items. */
|
|
|
|
|
items: Item[],
|
|
|
|
|
/** Name of the active tab item. */
|
|
|
|
|
activeItem: string,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Animated tabs component. */
|
|
|
|
|
const Tabs = ({ items, activeItem }: ITabs) => {
|
|
|
|
|
const defaultIndex = items.findIndex(({ name }) => name === activeItem);
|
|
|
|
|
|
|
|
|
|