UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

69 lines (68 loc) 3.32 kB
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))); } }