UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Microsoft 365.

182 lines 9.52 kB
import { __assign, __extends } from "tslib"; import * as React from 'react'; import { FocusZone, FocusZoneDirection } from '@fluentui/react-focus'; import { initializeComponentRef, classNamesFunction, divProperties, elementContains, focusFirstChild, getNativeProps, warnMutuallyExclusive, } from '../../Utilities'; import { KeytipManager } from '../../utilities/keytips/KeytipManager'; var getClassNames = classNamesFunction(); var COMPONENT_NAME = 'OverflowSet'; var OverflowSetBase = /** @class */ (function (_super) { __extends(OverflowSetBase, _super); function OverflowSetBase(props) { var _this = _super.call(this, props) || this; _this._focusZone = React.createRef(); _this._persistedKeytips = {}; _this._keytipManager = KeytipManager.getInstance(); _this._divContainer = React.createRef(); _this._onRenderItems = function (items) { return items.map(function (item, i) { return (React.createElement("div", { key: item.key, className: _this._classNames.item }, _this.props.onRenderItem(item))); }); }; _this._onRenderOverflowButtonWrapper = function (items) { var wrapperDivProps = { className: _this._classNames.overflowButton, }; var overflowKeytipSequences = _this.props.keytipSequences; var newOverflowItems = []; if (overflowKeytipSequences) { items.forEach(function (overflowItem) { var keytip = overflowItem.keytipProps; if (keytip) { // Create persisted keytip var persistedKeytip = { content: keytip.content, keySequences: keytip.keySequences, disabled: keytip.disabled || !!(overflowItem.disabled || overflowItem.isDisabled), hasDynamicChildren: keytip.hasDynamicChildren, hasMenu: keytip.hasMenu, }; if (keytip.hasDynamicChildren || _this._getSubMenuForItem(overflowItem)) { // If the keytip has a submenu or children nodes, change onExecute to persistedKeytipExecute persistedKeytip.onExecute = _this._keytipManager.menuExecute.bind(_this._keytipManager, overflowKeytipSequences, overflowItem.keytipProps.keySequences); } else { // If the keytip doesn't have a submenu, just execute the original function persistedKeytip.onExecute = keytip.onExecute; } // Add this persisted keytip to our internal list, use a temporary uniqueID (its content) // uniqueID will get updated on register _this._persistedKeytips[persistedKeytip.content] = persistedKeytip; // Add the overflow sequence to this item var newOverflowItem = __assign(__assign({}, overflowItem), { keytipProps: __assign(__assign({}, keytip), { overflowSetSequence: overflowKeytipSequences }) }); newOverflowItems.push(newOverflowItem); } else { // Nothing to change, add overflowItem to list newOverflowItems.push(overflowItem); } }); } else { newOverflowItems = items; } return React.createElement("div", __assign({}, wrapperDivProps), _this.props.onRenderOverflowButton(newOverflowItems)); }; initializeComponentRef(_this); warnMutuallyExclusive(COMPONENT_NAME, props, { doNotContainWithinFocusZone: 'focusZoneProps', }); return _this; } OverflowSetBase.prototype.render = function () { var _a = this.props, items = _a.items, overflowItems = _a.overflowItems, className = _a.className, // eslint-disable-next-line deprecation/deprecation focusZoneProps = _a.focusZoneProps, styles = _a.styles, vertical = _a.vertical, // eslint-disable-next-line deprecation/deprecation doNotContainWithinFocusZone = _a.doNotContainWithinFocusZone, role = _a.role, _b = _a.overflowSide, overflowSide = _b === void 0 ? 'end' : _b; this._classNames = getClassNames(styles, { className: className, vertical: vertical }); var Tag; var uniqueComponentProps; if (doNotContainWithinFocusZone) { Tag = 'div'; uniqueComponentProps = __assign(__assign({}, getNativeProps(this.props, divProperties)), { ref: this._divContainer }); } else { Tag = FocusZone; uniqueComponentProps = __assign(__assign(__assign({}, getNativeProps(this.props, divProperties)), focusZoneProps), { componentRef: this._focusZone, direction: vertical ? FocusZoneDirection.vertical : FocusZoneDirection.horizontal }); } var showOverflow = overflowItems && overflowItems.length > 0; return (React.createElement(Tag, __assign({ role: role || 'group', "aria-orientation": role === 'menubar' ? (vertical === true ? 'vertical' : 'horizontal') : undefined }, uniqueComponentProps, { className: this._classNames.root }), overflowSide === 'start' && showOverflow && this._onRenderOverflowButtonWrapper(overflowItems), items && this._onRenderItems(items), overflowSide === 'end' && showOverflow && this._onRenderOverflowButtonWrapper(overflowItems))); }; /** * Sets focus to the first tabbable item in the OverflowSet. * @param forceIntoFirstElement - If true, focus will be forced into the first element, * even if focus is already in theOverflowSet * @returns True if focus could be set to an active element, false if no operation was taken. */ OverflowSetBase.prototype.focus = function (forceIntoFirstElement) { var focusSucceeded = false; // eslint-disable-next-line deprecation/deprecation if (this.props.doNotContainWithinFocusZone) { if (this._divContainer.current) { focusSucceeded = focusFirstChild(this._divContainer.current); } } else if (this._focusZone.current) { focusSucceeded = this._focusZone.current.focus(forceIntoFirstElement); } return focusSucceeded; }; /** * Sets focus to a specific child element within the OverflowSet. * @param childElement - The child element within the zone to focus. * @returns True if focus could be set to an active element, false if no operation was taken. */ OverflowSetBase.prototype.focusElement = function (childElement) { var focusSucceeded = false; if (!childElement) { return false; } // eslint-disable-next-line deprecation/deprecation if (this.props.doNotContainWithinFocusZone) { if (this._divContainer.current && elementContains(this._divContainer.current, childElement)) { childElement.focus(); focusSucceeded = document.activeElement === childElement; } } else if (this._focusZone.current) { focusSucceeded = this._focusZone.current.focusElement(childElement); } return focusSucceeded; }; // Add keytip register/unregister handlers to lifecycle functions to correctly manage persisted keytips OverflowSetBase.prototype.componentDidMount = function () { this._registerPersistedKeytips(); }; OverflowSetBase.prototype.componentWillUnmount = function () { this._unregisterPersistedKeytips(); }; OverflowSetBase.prototype.UNSAFE_componentWillUpdate = function () { this._unregisterPersistedKeytips(); }; OverflowSetBase.prototype.componentDidUpdate = function () { this._registerPersistedKeytips(); }; OverflowSetBase.prototype._registerPersistedKeytips = function () { var _this = this; Object.keys(this._persistedKeytips).forEach(function (key) { var keytip = _this._persistedKeytips[key]; var uniqueID = _this._keytipManager.register(keytip, true); // Update map _this._persistedKeytips[uniqueID] = keytip; delete _this._persistedKeytips[key]; }); }; OverflowSetBase.prototype._unregisterPersistedKeytips = function () { var _this = this; // Delete all persisted keytips saved Object.keys(this._persistedKeytips).forEach(function (uniqueID) { _this._keytipManager.unregister(_this._persistedKeytips[uniqueID], uniqueID, true); }); this._persistedKeytips = {}; }; /** * Gets the subMenu for an overflow item * Checks if itemSubMenuProvider has been defined, if not defaults to subMenuProps */ OverflowSetBase.prototype._getSubMenuForItem = function (item) { if (this.props.itemSubMenuProvider) { return this.props.itemSubMenuProvider(item); } if (item.subMenuProps) { return item.subMenuProps.items; } return undefined; }; return OverflowSetBase; }(React.Component)); export { OverflowSetBase }; //# sourceMappingURL=OverflowSet.base.js.map