1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import React, { useEffect, useState } from 'react';
6 import { Tabs, Tab, List, ListItem, StyleRulesCallback, withStyles } from '@material-ui/core';
7 import { WithStyles } from '@material-ui/core';
8 import classNames from 'classnames';
9 import { ArvadosTheme } from 'common/custom-theme';
11 type TabbedListClasses = 'root' | 'tabs' | 'list' | 'listItem';
13 const tabbedListStyles: StyleRulesCallback<TabbedListClasses> = (theme: ArvadosTheme) => ({
18 backgroundColor: theme.palette.background.paper,
22 borderBottom: '1px solid lightgrey',
32 type SingleTabProps<T> = {
37 type TabPanelProps = {
38 children: React.ReactNode;
43 type TabbedListProps<T> = {
44 tabbedListContents: SingleTabProps<T>[];
45 renderListItem?: (item: T) => React.ReactNode;
46 injectedStyles?: string;
47 keypress?: { key: string };
48 selectedIndex?: number;
51 export const TabbedList = withStyles(tabbedListStyles)(<T, _>({ tabbedListContents, renderListItem, selectedIndex, keypress, injectedStyles, classes }: TabbedListProps<T> & WithStyles<TabbedListClasses>) => {
52 const [tabNr, setTabNr] = useState(0);
55 if (keypress) handleKeyPress(keypress.key);
58 const handleKeyPress = (keypress: string) => {
59 const numTabs = tabbedListContents.length;
60 if (keypress === 'Tab') {
61 setTabNr((tabNr + 1) % numTabs);
65 const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
66 event.preventDefault();
71 <div className={classNames(classes.root, injectedStyles)}>
72 <div className={classes.tabs}>
75 onChange={handleTabChange}
78 {tabbedListContents.map((tab) => (
79 <Tab label={tab.label} />
87 <List className={classes.list}>
88 {tabbedListContents[tabNr].items.map((item, i) => (
90 className={classes.listItem}
91 selected={i === selectedIndex}
93 {renderListItem ? renderListItem(item) : JSON.stringify(item)}
102 const TabPanel = ({ children, value, index }: TabPanelProps) => {
103 return <div hidden={value !== index}>{value === index && children}</div>;