UNPKG

@fluentui/react

Version:

Reusable React components for building web experiences.

394 lines 21.5 kB
define(["require", "exports", "tslib", "react", "../../Utilities", "../../List", "../../Selection", "../../FocusZone", "./GroupHeader", "./GroupShowAll", "./GroupFooter"], function (require, exports, tslib_1, React, Utilities_1, List_1, Selection_1, FocusZone_1, GroupHeader_1, GroupShowAll_1, GroupFooter_1) { "use strict"; var _this = this; Object.defineProperty(exports, "__esModule", { value: true }); exports.GroupedListV2Wrapper = exports.GroupedListV2FC = void 0; var flattenItems = function (groups, items, memoItems, getGroupItemLimit) { 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; 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 _a = stack.pop(), group = _a.group, groupIndex = _a.groupIndex; memoItems[index] = { group: group, groupId: (0, Utilities_1.getId)('GroupedListSection'), type: 'header', groupIndex: groupIndex, }; index++; while (group.isCollapsed !== true && (group === null || group === void 0 ? void 0 : group.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: (0, 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; return (_a = selection === null || selection === void 0 ? void 0 : selection.isRangeSelected(startIndex, count)) !== null && _a !== void 0 ? _a : false; }), isSelected = _a[0], setIsSelected = _a[1]; React.useEffect(function () { if (selection && eventGroup) { var changeHandler_1 = function () { var _a; setIsSelected((_a = selection === null || selection === void 0 ? void 0 : selection.isRangeSelected(startIndex, count)) !== null && _a !== void 0 ? _a : false); }; eventGroup.on(selection, Selection_1.SELECTION_CHANGE, changeHandler_1); return function () { eventGroup === null || eventGroup === void 0 ? void 0 : eventGroup.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 === (0, Utilities_1.getRTLSafeKeyCode)(Utilities_1.KeyCodes.right); }; var getClassNames = (0, 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) !== null && _b !== void 0 ? _b : null; case 'header': return item.group.key; case 'footer': return "".concat(item.group.key, "-footer"); case 'showAll': return "".concat(item.group.key, "-showAll"); } return null; }; var renderGroupHeader = function (props) { return React.createElement(GroupHeader_1.GroupHeader, tslib_1.__assign({}, props)); }; var renderGroupShowAll = function (props) { return React.createElement(GroupShowAll_1.GroupShowAll, tslib_1.__assign({}, props)); }; var renderGroupFooter = function (props) { if (props.group && props.footerText) { return React.createElement(GroupFooter_1.GroupFooter, tslib_1.__assign({}, props)); } return null; }; var GroupedListV2FC = function (props) { var selection = props.selection, _a = props.selectionMode, selectionMode = _a === void 0 ? Selection_1.SelectionMode.multiple : _a, _b = props.groupProps, groupProps = _b === void 0 ? {} : _b, _c = props.compact, compact = _c === void 0 ? false : _c, _d = props.items, items = _d === void 0 ? [] : _d, groups = props.groups, onGroupExpandStateChanged = props.onGroupExpandStateChanged, listProps = props.listProps, className = props.className, usePageCache = props.usePageCache, onShouldVirtualize = props.onShouldVirtualize, theme = props.theme, _e = props.role, role = _e === void 0 ? 'treegrid' : _e, styles = props.styles, _f = props.focusZoneProps, focusZoneProps = _f === void 0 ? {} : _f, _g = props.rootListProps, rootListProps = _g === void 0 ? {} : _g, onRenderCell = props.onRenderCell, viewport = props.viewport, groupedListRef = props.groupedListRef, groupExpandedVersion = props.groupExpandedVersion, versionFromProps = props.version; var _h = groupProps.onRenderHeader, onRenderHeader = _h === void 0 ? renderGroupHeader : _h, _j = groupProps.onRenderFooter, onRenderFooter = _j === void 0 ? renderGroupFooter : _j, _k = groupProps.onRenderShowAll, onRenderShowAll = _k === void 0 ? renderGroupShowAll : _k; 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 listRef = React.useRef(null); var _l = React.useState({}), version = _l[0], setVersion = _l[1]; var _m = React.useState({}), toggleVersion = _m[0], setToggleVersion = _m[1]; // eslint-disable-next-line deprecation/deprecation var _o = focusZoneProps.shouldEnterInnerZone, shouldEnterInnerZone = _o === void 0 ? isInnerZoneKeystroke : _o; var listView = React.useMemo(function () { return flattenItems(groups, items, flatList.current, groupProps === null || groupProps === void 0 ? void 0 : groupProps.getGroupItemLimit); // eslint-disable-next-line react-hooks/exhaustive-deps }, [groups, groupProps === null || groupProps === void 0 ? void 0 : groupProps.getGroupItemLimit, items, toggleVersion, flatList, groupExpandedVersion]); var getPageSpecification = React.useCallback(function (flattenedIndex) { var pageGroup = listView[flattenedIndex]; return { key: pageGroup.type === 'header' ? pageGroup.group.key : undefined, }; }, [listView]); React.useImperativeHandle(groupedListRef, function () { var indexMap; return { scrollToIndex: function (index, measureItem, scrollToMode) { var _a; indexMap = indexMap !== null && indexMap !== void 0 ? indexMap : listView.reduce(function (map, item, listIndex) { if (item.type === 'item') { map[item.itemIndex] = listIndex; } return map; }, []); var scrollIndex = indexMap[index]; var measure = typeof measureItem === 'function' ? function (itemIndex) { var _a; if (((_a = listView[itemIndex]) === null || _a === void 0 ? void 0 : _a.type) === 'item') { return measureItem(listView[itemIndex].itemIndex); } return 0; } : undefined; (_a = listRef.current) === null || _a === void 0 ? void 0 : _a.scrollToIndex(scrollIndex, measure, scrollToMode); }, getStartItemIndexInView: function () { var _a; return ((_a = listRef.current) === null || _a === void 0 ? void 0 : _a.getStartItemIndexInView()) || 0; }, }; }, [listView, listRef]); React.useEffect(function () { if (groupProps === null || groupProps === void 0 ? void 0 : groupProps.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 newIsSomeGroupExpanded = computeIsSomeGroupExpanded(groups); if (newIsSomeGroupExpanded !== isSomeGroupExpanded.current) { isSomeGroupExpanded.current = newIsSomeGroupExpanded; onGroupExpandStateChanged === null || onGroupExpandStateChanged === void 0 ? void 0 : onGroupExpandStateChanged(newIsSomeGroupExpanded); } }, [groups, toggleVersion, onGroupExpandStateChanged, groupExpandedVersion]); var onToggleCollapse = React.useCallback(function (group) { var _a; var onToggleCollapseFn = (_a = groupProps === null || groupProps === void 0 ? void 0 : groupProps.headerProps) === null || _a === void 0 ? void 0 : _a.onToggleCollapse; if (group) { onToggleCollapseFn === null || onToggleCollapseFn === void 0 ? void 0 : onToggleCollapseFn(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; var onToggleSummarizeFn = (_a = groupProps === null || groupProps === void 0 ? void 0 : groupProps.showAllProps) === null || _a === void 0 ? void 0 : _a.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) !== 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 ? "".concat(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 ? "".concat(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) !== 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: (0, 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 }, listProps, rootListProps)))); }; exports.GroupedListV2FC = GroupedListV2FC; 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 = exports.GroupedListV2Wrapper = /** @class */ (function (_super) { tslib_1.__extends(GroupedListV2Wrapper, _super); function GroupedListV2Wrapper(props) { var _a, _b, _c; var _this = _super.call(this, props) || this; _this._groupedList = React.createRef(); (0, Utilities_1.initializeComponentRef)(_this); var version = (_a = props.listProps, _b = _a === void 0 ? {} : _a, _c = _b.version, _c === void 0 ? {} : _c), 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) { var _a; (_a = this._groupedList.current) === null || _a === void 0 ? void 0 : _a.scrollToIndex(index, measureItem, scrollToMode); }; GroupedListV2Wrapper.prototype.getStartItemIndexInView = function () { var _a; return ((_a = this._groupedList.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, { groupedListRef: this._groupedList })); }; GroupedListV2Wrapper.prototype.forceUpdate = function () { _super.prototype.forceUpdate.call(this); this._forceListUpdate(); }; GroupedListV2Wrapper.prototype.toggleCollapseAll = function (allCollapsed) { var _a; var groups = this.state.groups; var groupProps = this.props.groupProps; if (groups && groups.length > 0) { (_a = groupProps === null || groupProps === void 0 ? void 0 : groupProps.onToggleCollapseAll) === null || _a === void 0 ? void 0 : _a.call(groupProps, allCollapsed); setGroupsCollapsedState(groups, allCollapsed); this.setState({ groupExpandedVersion: {}, }); this.forceUpdate(); } }; GroupedListV2Wrapper.prototype._forceListUpdate = function () { this.setState({ version: {}, }); }; GroupedListV2Wrapper.displayName = 'GroupedListV2'; return GroupedListV2Wrapper; }(React.Component)); }); //# sourceMappingURL=GroupedListV2.base.js.map