office-ui-fabric-react
Version:
Reusable React components for building experiences for Microsoft 365.
376 lines • 18.3 kB
JavaScript
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
;