monday-ui-react-core
Version:
Official monday.com UI resources for application development in React.js
90 lines (75 loc) • 2.58 kB
JSX
import React, { useRef, forwardRef, useState, useCallback } from "react";
import PropTypes from "prop-types";
import cx from "classnames";
import useMergeRefs from "../../../hooks/useMergeRefs";
import { useFocusWithin, useKeyboard } from "@react-aria/interactions";
import "./TabList.scss";
const TabList = forwardRef(({ className, id, onTabChange, activeTabId, tabType, size, children }, ref) => {
const componentRef = useRef(null);
const mergedRef = useMergeRefs({ refs: [ref, componentRef] });
const [activeTab, setActiveTab] = useState(activeTabId);
const [focusTab, setFocusTab] = useState(-1);
function onTabSelect(tabId) {
setActiveTab(tabId);
onTabChange && onTabChange(tabId);
}
const onTabClick = useCallback((tabId) => {
onTabSelect(tabId);
setFocusTab(-1);
}, [onTabSelect, setFocusTab]);
function onKeyDown(keyCode) {
let newFocusTab = focusTab;
if (keyCode === 37 || keyCode === 39) { // left or right arrow
if (newFocusTab < 0) {
newFocusTab = activeTab;
}
}
if (keyCode === 37 && newFocusTab > 0) { // left arrow
setFocusTab(newFocusTab - 1);
} else if (keyCode === 39 && newFocusTab < children.length - 1) { // right arrow
setFocusTab(newFocusTab + 1);
} else if (keyCode === 13 || keyCode === 32) { // enter or space
onTabSelect(focusTab);
}
}
const { keyboardProps } = useKeyboard({
onKeyDown: (e) => {
onKeyDown(e.keyCode);
},
onKeyUp: (e) => {}
});
const { focusWithinProps } = useFocusWithin({
onFocusWithin: () => {
setFocusTab(activeTab);
},
onBlurWithin: () => {
setFocusTab(-1);
}
});
return (
<div ref={mergedRef} className={cx("tabs--wrapper", className, tabType)} id={id}>
<ul tabIndex={0} {...keyboardProps} {...focusWithinProps} className={cx("tabs-list", size)} role="tablist">
{React.Children.map(children, (child, index) => {
return React.cloneElement(child, { value: index, active: activeTab === index, focus: focusTab === index, onClick: onTabClick });
})}
</ul>
</div>
);
});
TabList.propTypes = {
className: PropTypes.string,
id: PropTypes.string,
onTabChange: PropTypes.func,
activeTabId: PropTypes.number,
tabType: PropTypes.string,
size: PropTypes.string
};
TabList.defaultProps = {
className: "",
id: "",
onTabChange: () => {},
activeTabId: 0,
tabType: "Compact"
};
TabList.isTabList = true;
export default TabList;