UNPKG

@fluentui/react

Version:

Reusable React components for building web experiences.

206 lines 11.8 kB
define(["require", "exports", "tslib", "react", "@fluentui/react-hooks", "@fluentui/utilities", "../../Button", "../../utilities/useOverflow", "../../FocusZone", "../ContextualMenu/ContextualMenu.types", "../Icon/Icon", "./PivotItem"], function (require, exports, tslib_1, React, react_hooks_1, utilities_1, Button_1, useOverflow_1, FocusZone_1, ContextualMenu_types_1, Icon_1, PivotItem_1) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PivotBase = void 0; var getClassNames = (0, utilities_1.classNamesFunction)(); var COMPONENT_NAME = 'Pivot'; var getTabId = function (props, pivotId, itemKey, index) { if (props.getTabId) { return props.getTabId(itemKey, index); } return pivotId + "-Tab".concat(index); }; // Gets the set of PivotLinks as array of IPivotItemProps // The set of Links is determined by child components of type PivotItem var getLinkItems = function (props, pivotId) { var result = { links: [], keyToIndexMapping: {}, keyToTabIdMapping: {}, }; React.Children.forEach(React.Children.toArray(props.children), function (child, index) { if (isPivotItem(child)) { var _a = child.props, // eslint-disable-next-line @typescript-eslint/no-deprecated linkText = _a.linkText, pivotItemProps = tslib_1.__rest(_a, ["linkText"]); var itemKey = child.props.itemKey || index.toString(); result.links.push(tslib_1.__assign(tslib_1.__assign({ headerText: linkText }, pivotItemProps), { itemKey: itemKey })); result.keyToIndexMapping[itemKey] = index; result.keyToTabIdMapping[itemKey] = getTabId(props, pivotId, itemKey, index); } else if (child) { (0, utilities_1.warn)('The children of a Pivot component must be of type PivotItem to be rendered.'); } }); return result; }; var isPivotItem = function (item) { var _a; return React.isValidElement(item) && ((_a = item.type) === null || _a === void 0 ? void 0 : _a.name) === PivotItem_1.PivotItem.name; }; exports.PivotBase = React.forwardRef(function (props, ref) { var focusZoneRef = React.useRef(null); var overflowMenuButtonComponentRef = React.useRef(null); var pivotId = (0, react_hooks_1.useId)('Pivot'); var _a = (0, react_hooks_1.useControllableValue)(props.selectedKey, props.defaultSelectedKey), selectedKey = _a[0], setSelectedKey = _a[1]; var componentRef = props.componentRef, theme = props.theme, linkSize = props.linkSize, linkFormat = props.linkFormat, overflowBehavior = props.overflowBehavior, overflowAriaLabel = props.overflowAriaLabel, focusZoneProps = props.focusZoneProps, overflowButtonAs = props.overflowButtonAs; // eslint-disable-next-line prefer-const var classNames; var nameProps = { 'aria-label': props['aria-label'], 'aria-labelledby': props['aria-labelledby'], }; var divProps = (0, utilities_1.getNativeProps)(props, utilities_1.divProperties, [ 'aria-label', 'aria-labelledby', ]); var linkCollection = getLinkItems(props, pivotId); React.useImperativeHandle(componentRef, function () { return ({ focus: function () { var _a; (_a = focusZoneRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, }); }); var renderLinkContent = function (link) { if (!link) { return null; } var itemCount = link.itemCount, itemIcon = link.itemIcon, headerText = link.headerText; return (React.createElement("span", { className: classNames.linkContent }, itemIcon !== undefined && (React.createElement("span", { className: classNames.icon }, React.createElement(Icon_1.Icon, { iconName: itemIcon }))), headerText !== undefined && React.createElement("span", { className: classNames.text }, " ", link.headerText), itemCount !== undefined && React.createElement("span", { className: classNames.count }, " (", itemCount, ")"))); }; var renderPivotLink = function (renderLinkCollection, link, renderPivotLinkSelectedKey, className) { var itemKey = link.itemKey, headerButtonProps = link.headerButtonProps, onRenderItemLink = link.onRenderItemLink; var tabId = renderLinkCollection.keyToTabIdMapping[itemKey]; var linkContent; var isSelected = renderPivotLinkSelectedKey === itemKey; if (onRenderItemLink) { linkContent = onRenderItemLink(link, renderLinkContent); } else { linkContent = renderLinkContent(link); } var contentString = link.headerText || ''; contentString += link.itemCount ? ' (' + link.itemCount + ')' : ''; // Adding space supplementary for icon contentString += link.itemIcon ? ' xx' : ''; var itemSemantics = link.role && link.role !== 'tab' ? { role: link.role, } : { role: 'tab', 'aria-selected': isSelected, }; return (React.createElement(Button_1.CommandButton, tslib_1.__assign({}, headerButtonProps, itemSemantics, { id: tabId, key: itemKey, className: (0, utilities_1.css)(className, isSelected && classNames.linkIsSelected), // eslint-disable-next-line react/jsx-no-bind onClick: function (ev) { return onLinkClick(itemKey, ev); }, // eslint-disable-next-line react/jsx-no-bind onKeyDown: function (ev) { return onKeyDown(itemKey, ev); }, "aria-label": link.ariaLabel, name: link.headerText, keytipProps: link.keytipProps, "data-content": contentString }), linkContent)); }; var onLinkClick = function (itemKey, ev) { ev.preventDefault(); updateSelectedItem(itemKey, ev); }; var onKeyDown = function (itemKey, ev) { // eslint-disable-next-line @typescript-eslint/no-deprecated if (ev.which === utilities_1.KeyCodes.enter) { ev.preventDefault(); updateSelectedItem(itemKey, ev); } }; var updateSelectedItem = function (itemKey, ev) { var _a; setSelectedKey(itemKey); linkCollection = getLinkItems(props, pivotId); if (props.onLinkClick && linkCollection.keyToIndexMapping[itemKey] >= 0) { var selectedIndex = linkCollection.keyToIndexMapping[itemKey]; var item = React.Children.toArray(props.children)[selectedIndex]; if (isPivotItem(item)) { props.onLinkClick(item, ev); } } (_a = overflowMenuButtonComponentRef.current) === null || _a === void 0 ? void 0 : _a.dismissMenu(); }; var renderPivotItem = function (itemKey, isActive) { if (props.headersOnly || !itemKey) { return null; } var index = linkCollection.keyToIndexMapping[itemKey]; var selectedTabId = linkCollection.keyToTabIdMapping[itemKey]; return (React.createElement("div", { role: "tabpanel", hidden: !isActive, key: itemKey, "aria-hidden": !isActive, "aria-labelledby": selectedTabId, className: classNames.itemContainer }, React.Children.toArray(props.children)[index])); }; var isKeyValid = function (itemKey) { return itemKey === null || (itemKey !== undefined && linkCollection.keyToIndexMapping[itemKey] !== undefined); }; var getSelectedKey = function () { if (isKeyValid(selectedKey)) { return selectedKey; } if (linkCollection.links.length) { return linkCollection.links[0].itemKey; } return undefined; }; classNames = getClassNames(props.styles, { theme: theme, linkSize: linkSize, linkFormat: linkFormat, }); var renderedSelectedKey = getSelectedKey(); var renderedSelectedIndex = renderedSelectedKey ? linkCollection.keyToIndexMapping[renderedSelectedKey] : 0; var items = linkCollection.links.map(function (l) { return renderPivotLink(linkCollection, l, renderedSelectedKey, classNames.link); }); // The overflow menu starts empty and items[] is updated as the overflow items change var overflowMenuProps = React.useMemo(function () { return ({ items: [], alignTargetEdge: true, directionalHint: ContextualMenu_types_1.DirectionalHint.bottomRightEdge, }); }, []); var overflowMenuButtonRef = (0, useOverflow_1.useOverflow)({ onOverflowItemsChanged: function (overflowIndex, elements) { // Set data-is-overflowing on each item elements.forEach(function (_a) { var ele = _a.ele, isOverflowing = _a.isOverflowing; return (ele.dataset.isOverflowing = "".concat(isOverflowing)); }); // Update the menu items overflowMenuProps.items = linkCollection.links .slice(overflowIndex) .filter(function (link) { return link.itemKey !== renderedSelectedKey; }) .map(function (link, index) { link.role = 'menuitem'; return { key: link.itemKey || "".concat(overflowIndex + index), onRender: function () { return renderPivotLink(linkCollection, link, renderedSelectedKey, classNames.linkInMenu); }, }; }); }, rtl: (0, utilities_1.getRTL)(theme), pinnedIndex: renderedSelectedIndex, }).menuButtonRef; var OverflowButton = overflowButtonAs ? overflowButtonAs : Button_1.CommandButton; return (React.createElement("div", tslib_1.__assign({ ref: ref }, divProps), React.createElement(FocusZone_1.FocusZone, tslib_1.__assign({ componentRef: focusZoneRef, role: "tablist" }, nameProps, { direction: FocusZone_1.FocusZoneDirection.horizontal }, focusZoneProps, { className: (0, utilities_1.css)(classNames.root, focusZoneProps === null || focusZoneProps === void 0 ? void 0 : focusZoneProps.className) }), items, overflowBehavior === 'menu' && (React.createElement(OverflowButton, { className: (0, utilities_1.css)(classNames.link, classNames.overflowMenuButton), // eslint-disable-next-line @typescript-eslint/no-deprecated elementRef: overflowMenuButtonRef, componentRef: overflowMenuButtonComponentRef, menuProps: overflowMenuProps, menuIconProps: { iconName: 'More', style: { color: 'inherit' } }, ariaLabel: overflowAriaLabel, role: "tab" }))), renderedSelectedKey && linkCollection.links.map(function (link) { return (link.alwaysRender === true || renderedSelectedKey === link.itemKey) && renderPivotItem(link.itemKey, renderedSelectedKey === link.itemKey); }))); }); exports.PivotBase.displayName = COMPONENT_NAME; }); //# sourceMappingURL=Pivot.base.js.map