UNPKG

10.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.PivotBase = void 0;
4var tslib_1 = require("tslib");
5var React = require("react");
6var react_hooks_1 = require("@fluentui/react-hooks");
7var utilities_1 = require("@fluentui/utilities");
8var Button_1 = require("../../Button");
9var useOverflow_1 = require("../../utilities/useOverflow");
10var FocusZone_1 = require("../../FocusZone");
11var ContextualMenu_types_1 = require("../ContextualMenu/ContextualMenu.types");
12var Icon_1 = require("../Icon/Icon");
13var PivotItem_1 = require("./PivotItem");
14var getClassNames = utilities_1.classNamesFunction();
15var COMPONENT_NAME = 'Pivot';
16var getTabId = function (props, pivotId, itemKey, index) {
17 if (props.getTabId) {
18 return props.getTabId(itemKey, index);
19 }
20 return pivotId + ("-Tab" + index);
21};
22// Gets the set of PivotLinks as array of IPivotItemProps
23// The set of Links is determined by child components of type PivotItem
24var getLinkItems = function (props, pivotId) {
25 var result = {
26 links: [],
27 keyToIndexMapping: {},
28 keyToTabIdMapping: {},
29 };
30 React.Children.forEach(React.Children.toArray(props.children), function (child, index) {
31 if (isPivotItem(child)) {
32 // eslint-disable-next-line deprecation/deprecation
33 var _a = child.props, linkText = _a.linkText, pivotItemProps = tslib_1.__rest(_a, ["linkText"]);
34 var itemKey = child.props.itemKey || index.toString();
35 result.links.push(tslib_1.__assign(tslib_1.__assign({ headerText: linkText }, pivotItemProps), { itemKey: itemKey }));
36 result.keyToIndexMapping[itemKey] = index;
37 result.keyToTabIdMapping[itemKey] = getTabId(props, pivotId, itemKey, index);
38 }
39 else if (child) {
40 utilities_1.warn('The children of a Pivot component must be of type PivotItem to be rendered.');
41 }
42 });
43 return result;
44};
45var isPivotItem = function (item) {
46 var _a;
47 return React.isValidElement(item) && ((_a = item.type) === null || _a === void 0 ? void 0 : _a.name) === PivotItem_1.PivotItem.name;
48};
49exports.PivotBase = React.forwardRef(function (props, ref) {
50 var focusZoneRef = React.useRef(null);
51 var overflowMenuButtonComponentRef = React.useRef(null);
52 var pivotId = react_hooks_1.useId('Pivot');
53 var _a = react_hooks_1.useControllableValue(props.selectedKey, props.defaultSelectedKey), selectedKey = _a[0], setSelectedKey = _a[1];
54 var componentRef = props.componentRef, theme = props.theme, linkSize = props.linkSize, linkFormat = props.linkFormat, overflowBehavior = props.overflowBehavior, overflowAriaLabel = props.overflowAriaLabel, focusZoneProps = props.focusZoneProps;
55 var classNames;
56 var nameProps = {
57 'aria-label': props['aria-label'],
58 'aria-labelledby': props['aria-labelledby'],
59 };
60 var divProps = utilities_1.getNativeProps(props, utilities_1.divProperties, [
61 'aria-label',
62 'aria-labelledby',
63 ]);
64 var linkCollection = getLinkItems(props, pivotId);
65 React.useImperativeHandle(componentRef, function () { return ({
66 focus: function () {
67 var _a;
68 (_a = focusZoneRef.current) === null || _a === void 0 ? void 0 : _a.focus();
69 },
70 }); });
71 var renderLinkContent = function (link) {
72 if (!link) {
73 return null;
74 }
75 var itemCount = link.itemCount, itemIcon = link.itemIcon, headerText = link.headerText;
76 return (React.createElement("span", { className: classNames.linkContent },
77 itemIcon !== undefined && (React.createElement("span", { className: classNames.icon },
78 React.createElement(Icon_1.Icon, { iconName: itemIcon }))),
79 headerText !== undefined && React.createElement("span", { className: classNames.text },
80 " ",
81 link.headerText),
82 itemCount !== undefined && React.createElement("span", { className: classNames.count },
83 " (",
84 itemCount,
85 ")")));
86 };
87 var renderPivotLink = function (renderLinkCollection, link, renderPivotLinkSelectedKey, className) {
88 var itemKey = link.itemKey, headerButtonProps = link.headerButtonProps, onRenderItemLink = link.onRenderItemLink;
89 var tabId = renderLinkCollection.keyToTabIdMapping[itemKey];
90 var linkContent;
91 var isSelected = renderPivotLinkSelectedKey === itemKey;
92 if (onRenderItemLink) {
93 linkContent = onRenderItemLink(link, renderLinkContent);
94 }
95 else {
96 linkContent = renderLinkContent(link);
97 }
98 var contentString = link.headerText || '';
99 contentString += link.itemCount ? ' (' + link.itemCount + ')' : '';
100 // Adding space supplementary for icon
101 contentString += link.itemIcon ? ' xx' : '';
102 var itemSemantics = link.role && link.role !== 'tab'
103 ? {
104 role: link.role,
105 }
106 : {
107 role: 'tab',
108 'aria-selected': isSelected,
109 };
110 return (React.createElement(Button_1.CommandButton, tslib_1.__assign({}, headerButtonProps, itemSemantics, { id: tabId, key: itemKey, className: utilities_1.css(className, isSelected && classNames.linkIsSelected),
111 // eslint-disable-next-line react/jsx-no-bind
112 onClick: function (ev) { return onLinkClick(itemKey, ev); },
113 // eslint-disable-next-line react/jsx-no-bind
114 onKeyDown: function (ev) { return onKeyDown(itemKey, ev); }, "aria-label": link.ariaLabel, name: link.headerText, keytipProps: link.keytipProps, "data-content": contentString }), linkContent));
115 };
116 var onLinkClick = function (itemKey, ev) {
117 ev.preventDefault();
118 updateSelectedItem(itemKey, ev);
119 };
120 var onKeyDown = function (itemKey, ev) {
121 // eslint-disable-next-line deprecation/deprecation
122 if (ev.which === utilities_1.KeyCodes.enter) {
123 ev.preventDefault();
124 updateSelectedItem(itemKey);
125 }
126 };
127 var updateSelectedItem = function (itemKey, ev) {
128 var _a;
129 setSelectedKey(itemKey);
130 linkCollection = getLinkItems(props, pivotId);
131 if (props.onLinkClick && linkCollection.keyToIndexMapping[itemKey] >= 0) {
132 var selectedIndex = linkCollection.keyToIndexMapping[itemKey];
133 var item = React.Children.toArray(props.children)[selectedIndex];
134 if (isPivotItem(item)) {
135 props.onLinkClick(item, ev);
136 }
137 }
138 (_a = overflowMenuButtonComponentRef.current) === null || _a === void 0 ? void 0 : _a.dismissMenu();
139 };
140 var renderPivotItem = function (itemKey, isActive) {
141 if (props.headersOnly || !itemKey) {
142 return null;
143 }
144 var index = linkCollection.keyToIndexMapping[itemKey];
145 var selectedTabId = linkCollection.keyToTabIdMapping[itemKey];
146 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]));
147 };
148 var isKeyValid = function (itemKey) {
149 return itemKey === null || (itemKey !== undefined && linkCollection.keyToIndexMapping[itemKey] !== undefined);
150 };
151 var getSelectedKey = function () {
152 if (isKeyValid(selectedKey)) {
153 return selectedKey;
154 }
155 if (linkCollection.links.length) {
156 return linkCollection.links[0].itemKey;
157 }
158 return undefined;
159 };
160 classNames = getClassNames(props.styles, {
161 theme: theme,
162 linkSize: linkSize,
163 linkFormat: linkFormat,
164 });
165 var renderedSelectedKey = getSelectedKey();
166 var renderedSelectedIndex = renderedSelectedKey ? linkCollection.keyToIndexMapping[renderedSelectedKey] : 0;
167 var items = linkCollection.links.map(function (l) {
168 return renderPivotLink(linkCollection, l, renderedSelectedKey, classNames.link);
169 });
170 // The overflow menu starts empty and items[] is updated as the overflow items change
171 var overflowMenuProps = React.useMemo(function () { return ({
172 items: [],
173 alignTargetEdge: true,
174 directionalHint: ContextualMenu_types_1.DirectionalHint.bottomRightEdge,
175 }); }, []);
176 var overflowMenuButtonRef = useOverflow_1.useOverflow({
177 onOverflowItemsChanged: function (overflowIndex, elements) {
178 // Set data-is-overflowing on each item
179 elements.forEach(function (_a) {
180 var ele = _a.ele, isOverflowing = _a.isOverflowing;
181 return (ele.dataset.isOverflowing = "" + isOverflowing);
182 });
183 // Update the menu items
184 overflowMenuProps.items = linkCollection.links
185 .slice(overflowIndex)
186 .filter(function (link) { return link.itemKey !== renderedSelectedKey; })
187 .map(function (link, index) {
188 link.role = 'menuitem';
189 return {
190 key: link.itemKey || "" + (overflowIndex + index),
191 onRender: function () { return renderPivotLink(linkCollection, link, renderedSelectedKey, classNames.linkInMenu); },
192 };
193 });
194 },
195 rtl: utilities_1.getRTL(theme),
196 pinnedIndex: renderedSelectedIndex,
197 }).menuButtonRef;
198 return (React.createElement("div", tslib_1.__assign({ ref: ref }, divProps),
199 React.createElement(FocusZone_1.FocusZone, tslib_1.__assign({ componentRef: focusZoneRef, role: "tablist" }, nameProps, { direction: FocusZone_1.FocusZoneDirection.horizontal }, focusZoneProps, { className: utilities_1.css(classNames.root, focusZoneProps === null || focusZoneProps === void 0 ? void 0 : focusZoneProps.className) }),
200 items,
201 overflowBehavior === 'menu' && (React.createElement(Button_1.CommandButton, { className: utilities_1.css(classNames.link, classNames.overflowMenuButton), elementRef: overflowMenuButtonRef, componentRef: overflowMenuButtonComponentRef, menuProps: overflowMenuProps, menuIconProps: { iconName: 'More', style: { color: 'inherit' } }, ariaLabel: overflowAriaLabel }))),
202 renderedSelectedKey &&
203 linkCollection.links.map(function (link) {
204 return (link.alwaysRender === true || renderedSelectedKey === link.itemKey) &&
205 renderPivotItem(link.itemKey, renderedSelectedKey === link.itemKey);
206 })));
207});
208exports.PivotBase.displayName = COMPONENT_NAME;
209//# sourceMappingURL=Pivot.base.js.map
\No newline at end of file