UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

107 lines (106 loc) 5.06 kB
import "../../CommonImports"; import "../../Core/core.css"; import "./Tabs.css"; import * as React from "react"; import { FocusGroupContext } from '../../FocusGroup'; import { FocusZoneContext } from '../../FocusZone'; import { Icon } from '../../Icon'; import { Observer } from '../../Observer'; import { Tooltip } from '../../TooltipEx'; import { css, getSafeId, KeyCode } from '../../Util'; import { getFriendlyDisplayValue } from '../../Utilities/FriendlyNumber'; import { TabBadge } from "./TabBadge"; /** * Presentational component that represents a single tab. */ export class Tab extends React.Component { constructor() { super(...arguments); this.onClick = (event) => { const { url } = this.props; let updatePivot = true; // If ctrl-click is pressed, and there is a URL specified for this item, then // don't handle the click here, allowing the browser to perform a navigation // (i.e. open in a new tab/window) if (event.ctrlKey) { if (url) { updatePivot = false; } } if (updatePivot) { event.preventDefault(); this.updateSelectedItem(event); } }; this.onKeyDown = (event) => { if (!event.defaultPrevented) { if (event.which === KeyCode.space || event.which === KeyCode.enter) { event.preventDefault(); this.updateSelectedItem(event); } } }; } render() { const { ariaLabel, index, setSize, iconProps, id, isSelected, renderBadge, url } = this.props; const TagName = url ? "a" : "div"; return (React.createElement(Observer, { name: this.props.name, badgeCount: this.props.badgeCount }, (props) => { const name = props.name; return (React.createElement(FocusGroupContext.Consumer, null, focusGroupContext => (React.createElement(FocusZoneContext.Consumer, null, zoneContext => { const badge = renderBadge ? renderBadge() : this.renderBadge(props.badgeCount); const icon = iconProps !== undefined && Icon(Object.assign({ className: "bolt-tab-icon" }, iconProps)); const text = name && (React.createElement("span", { className: "bolt-tab-text", "data-content": name }, name)); const tooltipProps = icon && !name && ariaLabel ? { text: ariaLabel, overflowOnly: false } : { text: name, overflowDetected, overflowOnly: true }; return (React.createElement(Tooltip, Object.assign({}, tooltipProps), React.createElement(TagName, { "aria-label": ariaLabel, "aria-posinset": index !== undefined ? index + 1 : undefined, "aria-selected": isSelected, "aria-setsize": setSize, className: css(this.props.className, "bolt-tab focus-treatment flex-noshrink", isSelected && "selected"), "data-focuszone": zoneContext.focuszoneId, href: url, id: getSafeId("tab-" + id), key: id, onClick: this.onClick, onKeyDown: this.onKeyDown, role: "tab", tabIndex: focusGroupContext.focusedElementId === "tab-" + id ? 0 : -1, onFocus: this.props.onFocus }, React.createElement("span", { className: "bolt-tab-inner-container" }, icon, text, badge)))); })))); })); } renderBadge(badgeCount) { const badgeDisplayValue = badgeCount !== undefined ? getFriendlyDisplayValue(badgeCount) : undefined; let badgeTooltip = undefined; if (badgeCount && badgeDisplayValue !== badgeCount.toString()) { badgeTooltip = badgeCount.toString(); } let badge = null; if (badgeDisplayValue) { const tooltipProps = badgeTooltip ? { text: badgeTooltip } : undefined; badge = React.createElement(TabBadge, { tooltipProps: tooltipProps }, badgeDisplayValue); } return badge; } /** * Updates the state with the new selected pivot. */ updateSelectedItem(ev) { const { onClick } = this.props; if (ev && this.props.onBeforeTabChange && !this.props.onBeforeTabChange(ev, this.props.id, this.props.url)) { ev.preventDefault(); return; } // Update notifiers if (onClick) { onClick(this.props.id); } } } function overflowDetected(anchorElement) { const overflowElement = anchorElement.querySelector(".bolt-tab-text"); if (overflowElement) { return overflowElement && overflowElement.scrollWidth > Math.ceil(overflowElement.offsetWidth); } return false; }