206 lines
12 KiB
JavaScript
206 lines
12 KiB
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
|