azure-devops-ui
Version:
React components for building web UI in Azure DevOps
69 lines (68 loc) • 3.32 kB
JavaScript
import "../../CommonImports";
import "../../Core/core.css";
import "./Tabs.css";
import * as React from "react";
import { Orientation, TabSize } from '../../Components/Tabs/Tabs.Props';
import { ObservableLike } from '../../Core/Observable';
import { FocusZone, FocusZoneDirection } from '../../FocusZone';
import { css } from '../../Util';
import { Tab } from "./Tab";
/**
* Renders all children as focusable, selectable elements and indicates whether or not they are
* currently selected.
*/
export class Tabs extends React.Component {
constructor(props) {
super(props);
this.onTabClick = (newTabId) => {
const { onSelectedTabChanged } = this.props;
if (onSelectedTabChanged) {
onSelectedTabChanged(newTabId);
}
};
this.onSelectedTabIdChanged = () => {
this.forceUpdate();
};
if (ObservableLike.isObservable(props.selectedTabId)) {
props.selectedTabId.subscribe(this.onSelectedTabIdChanged);
}
}
componentWillUnmount() {
if (ObservableLike.isObservable(this.props.selectedTabId)) {
this.props.selectedTabId.unsubscribe(this.onSelectedTabIdChanged);
}
}
render() {
const { tabSize = TabSize.Tall, orientation = Orientation.Horizontal } = this.props;
const selectedTabId = this.props.selectedTabId && ObservableLike.getValue(this.props.selectedTabId);
let childrenCount = 0;
let childIndex = 0;
const idToIndex = {};
let defaultId;
React.Children.map(this.props.children, (child) => {
if (child && child.type === Tab) {
idToIndex[child.props.id] = childIndex++;
childrenCount++;
if (!defaultId && child.props.id) {
defaultId = "tab-" + child.props.id;
}
}
});
const children = React.Children.map(this.props.children, (child) => {
if (child && typeof child.type !== "string") {
// We don't want to pass along the following props, unless the
// child is a React component that will presumably know what
// to do with them.
const isSelected = (child.props.id && child.props.id.toLocaleLowerCase()) === (selectedTabId && selectedTabId.toLocaleLowerCase());
const onClick = this.onTabClick;
return React.cloneElement(child, Object.assign(Object.assign({}, child.props), { isSelected,
onClick, index: idToIndex[child.props.id], setSize: childrenCount }));
}
return child;
});
const orientationClass = orientation === Orientation.Vertical ? "flex-column" : "flex-row";
const focusZoneDirection = orientation === Orientation.Vertical ? FocusZoneDirection.Vertical : FocusZoneDirection.Horizontal;
return (React.createElement(FocusZone, { direction: focusZoneDirection, focusGroupProps: { defaultElementId: defaultId } },
React.createElement("div", { "aria-label": this.props.ariaLabel, className: css(this.props.className, "bolt-tabs", orientationClass, tabSize), role: "tablist" }, children)));
}
}