UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Microsoft 365.

376 lines • 18.3 kB
"use strict"; var _this = this; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var React = require("react"); var Utilities_1 = require("../../Utilities"); var List_1 = require("../../List"); var Selection_1 = require("../../Selection"); var FocusZone_1 = require("../../FocusZone"); var GroupHeader_1 = require("./GroupHeader"); var GroupShowAll_1 = require("./GroupShowAll"); var GroupFooter_1 = require("./GroupFooter"); var flattenItems = function (groups, items, memoItems, getGroupItemLimit) { var _a; if (!groups) { return items; } if (memoItems.length < 1) { // Not the exact final size but gets us in the ballpark. // This helps avoid trashing memory when building // the flattened list. memoItems = new Array(items.length); } var index = 0; // const stack: IGroup[] = []; var stack = []; var j = groups.length - 1; while (j >= 0) { stack.push({ group: groups[j], groupIndex: j + 1 }); j--; } while (stack.length > 0) { // eslint-disable-next-line prefer-const var _b = stack.pop(), group = _b.group, groupIndex = _b.groupIndex; memoItems[index] = { group: group, groupId: Utilities_1.getId('GroupedListSection'), type: 'header', groupIndex: groupIndex, }; index++; while (group.isCollapsed !== true && ((_a = group) === null || _a === void 0 ? void 0 : _a.children) && group.children.length > 0) { j = group.children.length - 1; while (j > 0) { stack.push({ group: group.children[j], groupIndex: j + 1 }); j--; } group = group.children[0]; memoItems[index] = { group: group, groupId: Utilities_1.getId('GroupedListSection'), type: 'header', groupIndex: 1, }; index++; } if (group.isCollapsed !== true) { var itemIndex = group.startIndex; var renderCount = getGroupItemLimit ? getGroupItemLimit(group) : Infinity; var count = !group.isShowingAll ? group.count : items.length; var itemEnd = itemIndex + Math.min(count, renderCount); while (itemIndex < itemEnd) { memoItems[index] = { group: group, item: items[itemIndex], itemIndex: itemIndex, type: 'item', }; itemIndex++; index++; } var isShowAllVisible = !group.children && !group.isCollapsed && !group.isShowingAll && (group.count > renderCount || group.hasMoreData); if (isShowAllVisible) { memoItems[index] = { group: group, type: 'showAll', }; index++; } } // Placeholder for a potential footer. // Whether or not a footer is displayed is resolved // by the footer render function so this is just a marker // for where a footer may go. memoItems[index] = { group: group, type: 'footer', }; index++; } memoItems.length = index; // console.log('MEMO ITEMS', memoItems); return memoItems; }; var useIsGroupSelected = function (startIndex, count, selection, eventGroup) { var _a = React.useState(function () { var _a, _b; return _b = (_a = selection) === null || _a === void 0 ? void 0 : _a.isRangeSelected(startIndex, count), (_b !== null && _b !== void 0 ? _b : false); }), isSelected = _a[0], setIsSelected = _a[1]; React.useEffect(function () { if (selection && eventGroup) { var changeHandler_1 = function () { var _a, _b; setIsSelected((_b = (_a = selection) === null || _a === void 0 ? void 0 : _a.isRangeSelected(startIndex, count), (_b !== null && _b !== void 0 ? _b : false))); }; eventGroup.on(selection, Selection_1.SELECTION_CHANGE, changeHandler_1); return function () { var _a; (_a = eventGroup) === null || _a === void 0 ? void 0 : _a.off(selection, Selection_1.SELECTION_CHANGE, changeHandler_1); }; } }, [startIndex, count, selection, eventGroup]); return isSelected; }; var computeIsSomeGroupExpanded = function (groups) { return !!(groups && groups.some(function (group) { return (group.children ? computeIsSomeGroupExpanded(group.children) : !group.isCollapsed); })); }; var setGroupsCollapsedState = function (groups, isCollapsed) { if (groups === undefined) { return; } for (var groupIndex = 0; groupIndex < groups.length; groupIndex++) { groups[groupIndex].isCollapsed = isCollapsed; } }; var isInnerZoneKeystroke = function (ev) { // eslint-disable-next-line deprecation/deprecation return ev.which === Utilities_1.getRTLSafeKeyCode(Utilities_1.KeyCodes.right); }; var getClassNames = Utilities_1.classNamesFunction(); var getKey = function (item, _index) { var _a, _b; switch (item.type) { case 'item': return _b = (_a = item.item) === null || _a === void 0 ? void 0 : _a.key, (_b !== null && _b !== void 0 ? _b : null); case 'header': return item.group.key; case 'footer': return item.group.key + "-footer"; case 'showAll': return item.group.key + "-showAll"; } return null; }; var renderGroupHeader = function (props, _defaultRender) { return React.createElement(GroupHeader_1.GroupHeader, tslib_1.__assign({}, props)); }; var renderGroupShowAll = function (props, _defaultRender) { return React.createElement(GroupShowAll_1.GroupShowAll, tslib_1.__assign({}, props)); }; var renderGroupFooter = function (props, _defaultRender) { if (props.group && props.footerText) { return React.createElement(GroupFooter_1.GroupFooter, tslib_1.__assign({}, props)); } return null; }; exports.GroupedListV2FC = function (props) { var _a; var selection = props.selection, _b = props.selectionMode, selectionMode = _b === void 0 ? Selection_1.SelectionMode.multiple : _b, _c = props.groupProps, groupProps = _c === void 0 ? {} : _c, _d = props.compact, compact = _d === void 0 ? false : _d, _e = props.items, items = _e === void 0 ? [] : _e, groups = props.groups, onGroupExpandStateChanged = props.onGroupExpandStateChanged, className = props.className, usePageCache = props.usePageCache, onShouldVirtualize = props.onShouldVirtualize, theme = props.theme, _f = props.role, role = _f === void 0 ? 'treegrid' : _f, styles = props.styles, _g = props.focusZoneProps, focusZoneProps = _g === void 0 ? {} : _g, _h = props.rootListProps, rootListProps = _h === void 0 ? {} : _h, onRenderCell = props.onRenderCell, viewport = props.viewport, listRef = props.listRef, groupExpandedVersion = props.groupExpandedVersion, versionFromProps = props.version; var _j = groupProps.onRenderHeader, onRenderHeader = _j === void 0 ? renderGroupHeader : _j, _k = groupProps.onRenderFooter, onRenderFooter = _k === void 0 ? renderGroupFooter : _k, _l = groupProps.onRenderShowAll, onRenderShowAll = _l === void 0 ? renderGroupShowAll : _l; var classNames = getClassNames(styles, { theme: theme, className: className, compact: compact, }); var events = React.useRef(); var flatList = React.useRef([]); var isSomeGroupExpanded = React.useRef(computeIsSomeGroupExpanded(groups)); var _m = React.useState({}), version = _m[0], setVersion = _m[1]; var _o = React.useState({}), toggleVersion = _o[0], setToggleVersion = _o[1]; // eslint-disable-next-line deprecation/deprecation var _p = focusZoneProps.shouldEnterInnerZone, shouldEnterInnerZone = _p === void 0 ? isInnerZoneKeystroke : _p; var listView = React.useMemo(function () { var _a; return flattenItems(groups, items, flatList.current, (_a = groupProps) === null || _a === void 0 ? void 0 : _a.getGroupItemLimit); // eslint-disable-next-line react-hooks/exhaustive-deps }, [groups, (_a = groupProps) === null || _a === void 0 ? void 0 : _a.getGroupItemLimit, items, toggleVersion, flatList]); var getPageSpecification = React.useCallback(function (flattenedIndex) { var pageGroup = listView[flattenedIndex]; return { key: pageGroup.type === 'header' ? pageGroup.group.key : undefined, }; }, [listView]); React.useEffect(function () { var _a; if ((_a = groupProps) === null || _a === void 0 ? void 0 : _a.isAllGroupsCollapsed) { setGroupsCollapsedState(groups, groupProps.isAllGroupsCollapsed); } events.current = new Utilities_1.EventGroup(_this); return function () { var _a; (_a = events.current) === null || _a === void 0 ? void 0 : _a.dispose(); events.current = undefined; }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); React.useEffect(function () { setVersion({}); }, [versionFromProps]); React.useEffect(function () { var _a; var newIsSomeGroupExpanded = computeIsSomeGroupExpanded(groups); if (newIsSomeGroupExpanded !== isSomeGroupExpanded.current) { isSomeGroupExpanded.current = newIsSomeGroupExpanded; (_a = onGroupExpandStateChanged) === null || _a === void 0 ? void 0 : _a(newIsSomeGroupExpanded); } }, [groups, toggleVersion, onGroupExpandStateChanged, groupExpandedVersion]); var onToggleCollapse = React.useCallback(function (group) { var _a, _b, _c; var onToggleCollapseFn = (_b = (_a = groupProps) === null || _a === void 0 ? void 0 : _a.headerProps) === null || _b === void 0 ? void 0 : _b.onToggleCollapse; if (group) { (_c = onToggleCollapseFn) === null || _c === void 0 ? void 0 : _c(group); group.isCollapsed = !group.isCollapsed; setToggleVersion({}); setVersion({}); } }, [setToggleVersion, groupProps]); var onToggleSelectGroup = function (group) { if (group && selection && selectionMode === Selection_1.SelectionMode.multiple) { selection.toggleRangeSelected(group.startIndex, group.count); } }; var onToggleSummarize = function (group) { var _a, _b; var onToggleSummarizeFn = (_b = (_a = groupProps) === null || _a === void 0 ? void 0 : _a.showAllProps) === null || _b === void 0 ? void 0 : _b.onToggleSummarize; if (onToggleSummarizeFn) { onToggleSummarizeFn(group); } else { if (group) { group.isShowingAll = !group.isShowingAll; } setVersion({}); setToggleVersion({}); } }; var getDividerProps = function (group, flattenedIndex) { var _a; var dividerProps = { group: group, groupIndex: flattenedIndex, groupLevel: (_a = group.level, (_a !== null && _a !== void 0 ? _a : 0)), viewport: viewport, selectionMode: selectionMode, groups: groups, compact: compact, onToggleSelectGroup: onToggleSelectGroup, onToggleCollapse: onToggleCollapse, onToggleSummarize: onToggleSummarize, }; return dividerProps; }; var renderHeader = function (item, flattenedIndex) { var group = item.group; var ariaProps; if (role === 'treegrid') { // GroupedList default role ariaProps = { ariaLevel: group.level ? group.level + 1 : 1, ariaSetSize: groups ? groups.length : undefined, ariaPosInSet: item.groupIndex, }; } else { // Grouped DetailsList ariaProps = { ariaRowIndex: flattenedIndex, }; } var headerProps = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, groupProps.headerProps), getDividerProps(item.group, flattenedIndex)), { key: group.key, groupedListId: item.groupId }), ariaProps); return (React.createElement(GroupItem, { render: onRenderHeader, defaultRender: renderGroupHeader, item: item, selection: selection, eventGroup: events.current, props: headerProps })); }; var renderShowAll = function (item, flattenedIndex) { var group = item.group; var groupShowAllProps = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, groupProps.showAllProps), getDividerProps(group, flattenedIndex)), { key: group.key ? group.key + "-show-all" : undefined }); return onRenderShowAll(groupShowAllProps, renderGroupShowAll); }; var renderFooter = function (item, flattenedIndex) { var group = item.group; var groupFooterProps = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, groupProps.footerProps), getDividerProps(group, flattenedIndex)), { key: group.key ? group.key + "-footer" : undefined }); return onRenderFooter(groupFooterProps, renderGroupFooter); }; var renderItem = function (item, flattenedIndex) { var _a; if (item.type === 'header') { return renderHeader(item, flattenedIndex); } else if (item.type === 'showAll') { return renderShowAll(item, flattenedIndex); } else if (item.type === 'footer') { return renderFooter(item, flattenedIndex); } else { var level = item.group.level ? item.group.level + 1 : 1; return onRenderCell(level, item.item, (_a = item.itemIndex, (_a !== null && _a !== void 0 ? _a : flattenedIndex)), item.group); } }; return (React.createElement(FocusZone_1.FocusZone, tslib_1.__assign({ direction: FocusZone_1.FocusZoneDirection.vertical, "data-automationid": "GroupedList", "data-is-scrollable": "false", role: "presentation" }, focusZoneProps, { shouldEnterInnerZone: shouldEnterInnerZone, className: Utilities_1.css(classNames.root, focusZoneProps.className) }), React.createElement(List_1.List, tslib_1.__assign({ ref: listRef, role: role, items: listView, // eslint-disable-next-line onRenderCellConditional: renderItem, usePageCache: usePageCache, onShouldVirtualize: onShouldVirtualize, getPageSpecification: getPageSpecification, version: version, getKey: getKey }, rootListProps)))); }; var GroupItem = function (_a) { var render = _a.render, defaultRender = _a.defaultRender, item = _a.item, selection = _a.selection, eventGroup = _a.eventGroup, props = _a.props; var group = item.group; var isSelected = useIsGroupSelected(group.startIndex, group.count, selection, eventGroup); var mergedProps = tslib_1.__assign(tslib_1.__assign({}, props), { isSelected: isSelected, selected: isSelected }); return render(mergedProps, defaultRender); }; var GroupedListV2Wrapper = /** @class */ (function (_super) { tslib_1.__extends(GroupedListV2Wrapper, _super); function GroupedListV2Wrapper(props) { var _this = _super.call(this, props) || this; _this._list = React.createRef(); Utilities_1.initializeComponentRef(_this); var _a = props.listProps, _b = (_a === void 0 ? {} : _a).version, version = _b === void 0 ? {} : _b, groups = props.groups; _this.state = { version: version, groupExpandedVersion: {}, groups: groups, }; return _this; } GroupedListV2Wrapper.getDerivedStateFromProps = function (nextProps, previousState) { var groups = nextProps.groups, selectionMode = nextProps.selectionMode, compact = nextProps.compact, items = nextProps.items, listProps = nextProps.listProps; var nextListVersion = listProps && listProps.version; var nextState = tslib_1.__assign(tslib_1.__assign({}, previousState), { groups: groups }); if (nextListVersion !== previousState.version || items !== previousState.items || groups !== previousState.groups || selectionMode !== previousState.selectionMode || compact !== previousState.compact) { nextState.version = {}; } return nextState; }; GroupedListV2Wrapper.prototype.scrollToIndex = function (index, measureItem, scrollToMode) { if (this._list.current) { this._list.current.scrollToIndex(index, measureItem, scrollToMode); } }; GroupedListV2Wrapper.prototype.getStartItemIndexInView = function () { var _a; return ((_a = this._list.current) === null || _a === void 0 ? void 0 : _a.getStartItemIndexInView()) || 0; }; GroupedListV2Wrapper.prototype.render = function () { return React.createElement(exports.GroupedListV2FC, tslib_1.__assign({}, this.props, this.state, { listRef: this._list })); }; GroupedListV2Wrapper.prototype.forceUpdate = function () { _super.prototype.forceUpdate.call(this); this._forceListUpdate(); }; GroupedListV2Wrapper.prototype.toggleCollapseAll = function (allCollapsed) { var _a, _b, _c; var groups = this.state.groups; var groupProps = this.props.groupProps; if (groups && groups.length > 0) { (_c = (_a = groupProps) === null || _a === void 0 ? void 0 : (_b = _a).onToggleCollapseAll) === null || _c === void 0 ? void 0 : _c.call(_b, allCollapsed); setGroupsCollapsedState(groups, allCollapsed); this.setState({ groupExpandedVersion: {}, }); this.forceUpdate(); } }; GroupedListV2Wrapper.prototype._forceListUpdate = function () { this.setState({ version: {}, }); }; GroupedListV2Wrapper.displayName = 'GroupedListV2'; return GroupedListV2Wrapper; }(React.Component)); exports.GroupedListV2Wrapper = GroupedListV2Wrapper; //# sourceMappingURL=GroupedListV2.base.js.map