UNPKG

@itwin/core-react

Version:

A react component library of iTwin.js UI general purpose components

119 lines 5.93 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Tabs */ import classnames from "classnames"; import * as React from "react"; import { Orientation } from "../enums/Orientation.js"; import { ItemKeyboardNavigator } from "../focus/ItemKeyboardNavigator.js"; import { IconHelper } from "../utils/IconHelper.js"; function isTabLabelWithIcon(item) { return typeof item !== "string" && !!item.icon; } function isTabLabel(item) { return typeof item !== "string"; } /** Tabs meant to represent the current position in a page/section * @public * @deprecated in 4.12.0. Use {@link https://itwinui.bentley.com/docs/tabs iTwinUI Tabs} instead. */ export class Tabs extends React.PureComponent { _anchorRefs = []; _itemKeyboardNavigator; constructor(props) { super(props); const activeIndex = this.validateActiveIndex(props.activeIndex); this.state = { activeIndex, }; props.labels.forEach(() => this._anchorRefs.push(React.createRef())); this._itemKeyboardNavigator = new ItemKeyboardNavigator(this._handleFocusItem, this._activateTab); } validateActiveIndex(idx) { let activeIndex = 0; if (idx && idx >= 0 && idx < this.props.labels.length) activeIndex = idx; return activeIndex; } componentDidMount() { this._itemKeyboardNavigator.itemCount = this.props.labels.length; this._itemKeyboardNavigator.orientation = this.props.orientation; } /** @internal */ componentDidUpdate(prevProps) { if (prevProps.labels !== this.props.labels) this._itemKeyboardNavigator.itemCount = this.props.labels.length; if (prevProps.orientation !== this.props.orientation) this._itemKeyboardNavigator.orientation = this.props.orientation; if (prevProps.activeIndex !== this.props.activeIndex) { let hadFocus = false; const element = this._anchorRefs[this.state.activeIndex].current; if (element && document.activeElement === element) hadFocus = true; const activeIndex = this.validateActiveIndex(this.props.activeIndex); this.setState(() => ({ activeIndex }), () => { if (hadFocus) { const newElement = this._anchorRefs[activeIndex].current; if (newElement) newElement.focus(); } }); } } _handleFocusItem = (index) => { const itemRef = this._anchorRefs[index]; if (itemRef && itemRef.current) itemRef.current.focus(); }; _handleTabClick = (index) => { this._activateTab(index); }; /** Handle keydown on tabs */ _handleKeyDownEvent(event, index) { this._itemKeyboardNavigator.handleKeyDownEvent(event, index); } /** Handle keyup on tabs */ _handleKeyUpEvent(event, index) { this._itemKeyboardNavigator.handleKeyUpEvent(event, index); } _activateTab = (index) => { this.props.onActivateTab && this.props.onActivateTab(index); this.setState({ activeIndex: index }); }; render() { const ulClassNames = classnames(this.props.mainClassName, this.props.green && "uicore-tabs-green", this.props.className); const anyIconsPresent = this.props.labels.reduce((a, b) => a + (isTabLabelWithIcon(b) ? 1 : 0), 0) > 0; return (React.createElement("ul", { className: ulClassNames, style: this.props.style, role: "tablist", "aria-orientation": this.props.orientation === Orientation.Vertical ? "vertical" : "horizontal" }, this.props.labels.map((label, index) => { let disabled; let tooltipElement; let title; let subLabel; let tabId = ""; let icon; if (isTabLabel(label)) { icon = IconHelper.getIconReactNode(label.icon); subLabel = label.subLabel; disabled = label.disabled; tabId = label.tabId; if (React.isValidElement(label.tooltip)) tooltipElement = label.tooltip; else if (typeof label.tooltip === "string") title = label.tooltip; } return (React.createElement("li", { key: index, title: title, className: classnames(index === this.state.activeIndex && "core-active", disabled && "core-tab-item-disabled"), role: "tab", "aria-selected": index === this.state.activeIndex, "data-for": `${tabId}` }, tooltipElement, React.createElement("a", { ref: this._anchorRefs[index], tabIndex: index === this.state.activeIndex ? 0 : -1, onClick: () => this._handleTabClick(index), onKeyDown: (event) => this._handleKeyDownEvent(event, index), onKeyUp: (event) => this._handleKeyUpEvent(event, index), "data-testid": `${tabId}`, role: "button" }, React.createElement("div", { className: classnames("uicore-tabs-inline-label", disabled && "core-tab-item-disabled") }, anyIconsPresent && (React.createElement("span", { className: "uicore-tabs-icon" }, icon)), React.createElement("div", { className: "uicore-tabs-label-subLabel-container" }, React.createElement("span", null, typeof label === "string" ? label : label.label), subLabel && (React.createElement("span", { className: "uicore-tabs-subLabel" }, subLabel))))))); }))); } } //# sourceMappingURL=Tabs.js.map