UNPKG

9.52 kBJavaScriptView Raw
1import { __assign, __extends } from "tslib";
2import * as React from 'react';
3import { FocusZone, FocusZoneDirection } from '@fluentui/react-focus';
4import { initializeComponentRef, classNamesFunction, divProperties, elementContains, focusFirstChild, getNativeProps, warnMutuallyExclusive, } from '../../Utilities';
5import { KeytipManager } from '../../utilities/keytips/KeytipManager';
6var getClassNames = classNamesFunction();
7var COMPONENT_NAME = 'OverflowSet';
8var OverflowSetBase = /** @class */ (function (_super) {
9 __extends(OverflowSetBase, _super);
10 function OverflowSetBase(props) {
11 var _this = _super.call(this, props) || this;
12 _this._focusZone = React.createRef();
13 _this._persistedKeytips = {};
14 _this._keytipManager = KeytipManager.getInstance();
15 _this._divContainer = React.createRef();
16 _this._onRenderItems = function (items) {
17 return items.map(function (item, i) {
18 return (React.createElement("div", { key: item.key, className: _this._classNames.item }, _this.props.onRenderItem(item)));
19 });
20 };
21 _this._onRenderOverflowButtonWrapper = function (items) {
22 var wrapperDivProps = {
23 className: _this._classNames.overflowButton,
24 };
25 var overflowKeytipSequences = _this.props.keytipSequences;
26 var newOverflowItems = [];
27 if (overflowKeytipSequences) {
28 items.forEach(function (overflowItem) {
29 var keytip = overflowItem.keytipProps;
30 if (keytip) {
31 // Create persisted keytip
32 var persistedKeytip = {
33 content: keytip.content,
34 keySequences: keytip.keySequences,
35 disabled: keytip.disabled || !!(overflowItem.disabled || overflowItem.isDisabled),
36 hasDynamicChildren: keytip.hasDynamicChildren,
37 hasMenu: keytip.hasMenu,
38 };
39 if (keytip.hasDynamicChildren || _this._getSubMenuForItem(overflowItem)) {
40 // If the keytip has a submenu or children nodes, change onExecute to persistedKeytipExecute
41 persistedKeytip.onExecute = _this._keytipManager.menuExecute.bind(_this._keytipManager, overflowKeytipSequences, overflowItem.keytipProps.keySequences);
42 }
43 else {
44 // If the keytip doesn't have a submenu, just execute the original function
45 persistedKeytip.onExecute = keytip.onExecute;
46 }
47 // Add this persisted keytip to our internal list, use a temporary uniqueID (its content)
48 // uniqueID will get updated on register
49 _this._persistedKeytips[persistedKeytip.content] = persistedKeytip;
50 // Add the overflow sequence to this item
51 var newOverflowItem = __assign(__assign({}, overflowItem), { keytipProps: __assign(__assign({}, keytip), { overflowSetSequence: overflowKeytipSequences }) });
52 newOverflowItems.push(newOverflowItem);
53 }
54 else {
55 // Nothing to change, add overflowItem to list
56 newOverflowItems.push(overflowItem);
57 }
58 });
59 }
60 else {
61 newOverflowItems = items;
62 }
63 return React.createElement("div", __assign({}, wrapperDivProps), _this.props.onRenderOverflowButton(newOverflowItems));
64 };
65 initializeComponentRef(_this);
66 warnMutuallyExclusive(COMPONENT_NAME, props, {
67 doNotContainWithinFocusZone: 'focusZoneProps',
68 });
69 return _this;
70 }
71 OverflowSetBase.prototype.render = function () {
72 var _a = this.props, items = _a.items, overflowItems = _a.overflowItems, className = _a.className,
73 // eslint-disable-next-line deprecation/deprecation
74 focusZoneProps = _a.focusZoneProps, styles = _a.styles, vertical = _a.vertical,
75 // eslint-disable-next-line deprecation/deprecation
76 doNotContainWithinFocusZone = _a.doNotContainWithinFocusZone, role = _a.role, _b = _a.overflowSide, overflowSide = _b === void 0 ? 'end' : _b;
77 this._classNames = getClassNames(styles, { className: className, vertical: vertical });
78 var Tag;
79 var uniqueComponentProps;
80 if (doNotContainWithinFocusZone) {
81 Tag = 'div';
82 uniqueComponentProps = __assign(__assign({}, getNativeProps(this.props, divProperties)), { ref: this._divContainer });
83 }
84 else {
85 Tag = FocusZone;
86 uniqueComponentProps = __assign(__assign(__assign({}, getNativeProps(this.props, divProperties)), focusZoneProps), { componentRef: this._focusZone, direction: vertical ? FocusZoneDirection.vertical : FocusZoneDirection.horizontal });
87 }
88 var showOverflow = overflowItems && overflowItems.length > 0;
89 return (React.createElement(Tag, __assign({ role: role || 'group', "aria-orientation": role === 'menubar' ? (vertical === true ? 'vertical' : 'horizontal') : undefined }, uniqueComponentProps, { className: this._classNames.root }),
90 overflowSide === 'start' && showOverflow && this._onRenderOverflowButtonWrapper(overflowItems),
91 items && this._onRenderItems(items),
92 overflowSide === 'end' && showOverflow && this._onRenderOverflowButtonWrapper(overflowItems)));
93 };
94 /**
95 * Sets focus to the first tabbable item in the OverflowSet.
96 * @param forceIntoFirstElement - If true, focus will be forced into the first element,
97 * even if focus is already in theOverflowSet
98 * @returns True if focus could be set to an active element, false if no operation was taken.
99 */
100 OverflowSetBase.prototype.focus = function (forceIntoFirstElement) {
101 var focusSucceeded = false;
102 // eslint-disable-next-line deprecation/deprecation
103 if (this.props.doNotContainWithinFocusZone) {
104 if (this._divContainer.current) {
105 focusSucceeded = focusFirstChild(this._divContainer.current);
106 }
107 }
108 else if (this._focusZone.current) {
109 focusSucceeded = this._focusZone.current.focus(forceIntoFirstElement);
110 }
111 return focusSucceeded;
112 };
113 /**
114 * Sets focus to a specific child element within the OverflowSet.
115 * @param childElement - The child element within the zone to focus.
116 * @returns True if focus could be set to an active element, false if no operation was taken.
117 */
118 OverflowSetBase.prototype.focusElement = function (childElement) {
119 var focusSucceeded = false;
120 if (!childElement) {
121 return false;
122 }
123 // eslint-disable-next-line deprecation/deprecation
124 if (this.props.doNotContainWithinFocusZone) {
125 if (this._divContainer.current && elementContains(this._divContainer.current, childElement)) {
126 childElement.focus();
127 focusSucceeded = document.activeElement === childElement;
128 }
129 }
130 else if (this._focusZone.current) {
131 focusSucceeded = this._focusZone.current.focusElement(childElement);
132 }
133 return focusSucceeded;
134 };
135 // Add keytip register/unregister handlers to lifecycle functions to correctly manage persisted keytips
136 OverflowSetBase.prototype.componentDidMount = function () {
137 this._registerPersistedKeytips();
138 };
139 OverflowSetBase.prototype.componentWillUnmount = function () {
140 this._unregisterPersistedKeytips();
141 };
142 OverflowSetBase.prototype.UNSAFE_componentWillUpdate = function () {
143 this._unregisterPersistedKeytips();
144 };
145 OverflowSetBase.prototype.componentDidUpdate = function () {
146 this._registerPersistedKeytips();
147 };
148 OverflowSetBase.prototype._registerPersistedKeytips = function () {
149 var _this = this;
150 Object.keys(this._persistedKeytips).forEach(function (key) {
151 var keytip = _this._persistedKeytips[key];
152 var uniqueID = _this._keytipManager.register(keytip, true);
153 // Update map
154 _this._persistedKeytips[uniqueID] = keytip;
155 delete _this._persistedKeytips[key];
156 });
157 };
158 OverflowSetBase.prototype._unregisterPersistedKeytips = function () {
159 var _this = this;
160 // Delete all persisted keytips saved
161 Object.keys(this._persistedKeytips).forEach(function (uniqueID) {
162 _this._keytipManager.unregister(_this._persistedKeytips[uniqueID], uniqueID, true);
163 });
164 this._persistedKeytips = {};
165 };
166 /**
167 * Gets the subMenu for an overflow item
168 * Checks if itemSubMenuProvider has been defined, if not defaults to subMenuProps
169 */
170 OverflowSetBase.prototype._getSubMenuForItem = function (item) {
171 if (this.props.itemSubMenuProvider) {
172 return this.props.itemSubMenuProvider(item);
173 }
174 if (item.subMenuProps) {
175 return item.subMenuProps.items;
176 }
177 return undefined;
178 };
179 return OverflowSetBase;
180}(React.Component));
181export { OverflowSetBase };
182//# sourceMappingURL=OverflowSet.base.js.map
\No newline at end of file