@fluentui/react
Version:
Reusable React components for building web experiences.
206 lines • 11.8 kB
JavaScript
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