@fluentui/react
Version:
Reusable React components for building web experiences.
278 lines • 19 kB
JavaScript
define(["require", "exports", "tslib", "react", "../../Utilities", "./DetailsList.types", "./DetailsRowCheck", "../GroupedList/GroupSpacer", "./DetailsRowFields", "../../FocusZone", "../../Selection", "../../Utilities", "../../Utilities"], function (require, exports, tslib_1, React, Utilities_1, DetailsList_types_1, DetailsRowCheck_1, GroupSpacer_1, DetailsRowFields_1, FocusZone_1, Selection_1, Utilities_2, Utilities_3) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DetailsRowBase = void 0;
var getClassNames = (0, Utilities_2.classNamesFunction)();
var DEFAULT_DROPPING_CSS_CLASS = 'is-dropping';
var NO_COLUMNS = [];
var DetailsRowBase = /** @class */ (function (_super) {
tslib_1.__extends(DetailsRowBase, _super);
function DetailsRowBase(props) {
var _this = _super.call(this, props) || this;
_this._root = React.createRef();
_this._cellMeasurer = React.createRef();
_this._focusZone = React.createRef();
_this._onSelectionChanged = function () {
var selectionState = getSelectionState(_this.props);
if (!(0, Utilities_1.shallowCompare)(selectionState, _this.state.selectionState)) {
_this.setState({ selectionState: selectionState });
}
};
/**
* update isDropping state based on the input value, which is used to change style during drag and drop
*
* when change to true, that means drag enter. we will add default dropping class name
* or the custom dropping class name (return result from onDragEnter) to the root elemet.
*
* when change to false, that means drag leave. we will remove the dropping class name from root element.
*
* @param newValue - New isDropping state value
* @param event - The event trigger dropping state change which can be dragenter, dragleave etc
*/
_this._updateDroppingState = function (newValue, event) {
var isDropping = _this.state.isDropping;
var _a = _this.props, dragDropEvents = _a.dragDropEvents, item = _a.item;
if (!newValue) {
if (dragDropEvents.onDragLeave) {
dragDropEvents.onDragLeave(item, event);
}
}
else if (dragDropEvents.onDragEnter) {
_this._droppingClassNames = dragDropEvents.onDragEnter(item, event);
}
if (isDropping !== newValue) {
_this.setState({ isDropping: newValue });
}
};
(0, Utilities_1.initializeComponentRef)(_this);
_this._events = new Utilities_1.EventGroup(_this);
_this.state = {
selectionState: getSelectionState(props),
columnMeasureInfo: undefined,
isDropping: false,
};
_this._droppingClassNames = '';
return _this;
}
DetailsRowBase.getDerivedStateFromProps = function (nextProps, previousState) {
return tslib_1.__assign(tslib_1.__assign({}, previousState), { selectionState: getSelectionState(nextProps) });
};
DetailsRowBase.prototype.componentDidMount = function () {
var _a = this.props, dragDropHelper = _a.dragDropHelper, selection = _a.selection, item = _a.item, onDidMount = _a.onDidMount;
if (dragDropHelper && this._root.current) {
this._dragDropSubscription = dragDropHelper.subscribe(this._root.current, this._events, this._getRowDragDropOptions());
}
if (selection) {
this._events.on(selection, Selection_1.SELECTION_CHANGE, this._onSelectionChanged);
}
if (onDidMount && item) {
// If the item appears later, we should wait for it before calling this method.
this._onDidMountCalled = true;
onDidMount(this);
}
};
DetailsRowBase.prototype.componentDidUpdate = function (previousProps) {
var state = this.state;
var _a = this.props, item = _a.item, onDidMount = _a.onDidMount;
var columnMeasureInfo = state.columnMeasureInfo;
if (this.props.itemIndex !== previousProps.itemIndex ||
this.props.item !== previousProps.item ||
this.props.dragDropHelper !== previousProps.dragDropHelper) {
if (this._dragDropSubscription) {
this._dragDropSubscription.dispose();
delete this._dragDropSubscription;
}
if (this.props.dragDropHelper && this._root.current) {
this._dragDropSubscription = this.props.dragDropHelper.subscribe(this._root.current, this._events, this._getRowDragDropOptions());
}
}
if (columnMeasureInfo && columnMeasureInfo.index >= 0 && this._cellMeasurer.current) {
var newWidth = this._cellMeasurer.current.getBoundingClientRect().width;
columnMeasureInfo.onMeasureDone(newWidth);
this.setState({
columnMeasureInfo: undefined,
});
}
if (item && onDidMount && !this._onDidMountCalled) {
this._onDidMountCalled = true;
onDidMount(this);
}
};
DetailsRowBase.prototype.componentWillUnmount = function () {
var _a = this.props, item = _a.item, onWillUnmount = _a.onWillUnmount;
// Only call the onWillUnmount callback if we have an item.
if (onWillUnmount && item) {
onWillUnmount(this);
}
if (this._dragDropSubscription) {
this._dragDropSubscription.dispose();
delete this._dragDropSubscription;
}
this._events.dispose();
};
DetailsRowBase.prototype.shouldComponentUpdate = function (nextProps, nextState) {
if (this.props.useReducedRowRenderer) {
var newSelectionState = getSelectionState(nextProps);
if (this.state.selectionState.isSelected !== newSelectionState.isSelected) {
return true;
}
return !(0, Utilities_1.shallowCompare)(this.props, nextProps);
}
else {
return true;
}
};
DetailsRowBase.prototype.render = function () {
var _a, _b;
var _c = this.props, className = _c.className, _d = _c.columns, columns = _d === void 0 ? NO_COLUMNS : _d, dragDropEvents = _c.dragDropEvents, item = _c.item, itemIndex = _c.itemIndex, id = _c.id, _e = _c.flatIndexOffset, flatIndexOffset = _e === void 0 ? 2 : _e, _f = _c.onRenderCheck, onRenderCheck = _f === void 0 ? this._onRenderCheck : _f, onRenderDetailsCheckbox = _c.onRenderDetailsCheckbox, onRenderItemColumn = _c.onRenderItemColumn, onRenderField = _c.onRenderField, getCellValueKey = _c.getCellValueKey, selectionMode = _c.selectionMode, checkboxVisibility = _c.checkboxVisibility, getRowAriaLabel = _c.getRowAriaLabel, getRowAriaDescription = _c.getRowAriaDescription, getRowAriaDescribedBy = _c.getRowAriaDescribedBy, isGridRow = _c.isGridRow, checkButtonAriaLabel = _c.checkButtonAriaLabel, checkboxCellClassName = _c.checkboxCellClassName,
/** Alias rowFieldsAs as RowFields and default to DetailsRowFields if rowFieldsAs does not exist */
rowFieldsAs = _c.rowFieldsAs, selection = _c.selection, indentWidth = _c.indentWidth, enableUpdateAnimations = _c.enableUpdateAnimations, compact = _c.compact, theme = _c.theme, styles = _c.styles, cellsByColumn = _c.cellsByColumn, groupNestingDepth = _c.groupNestingDepth, _g = _c.useFastIcons, useFastIcons = _g === void 0 ? true : _g, cellStyleProps = _c.cellStyleProps, group = _c.group, focusZoneProps = _c.focusZoneProps, _h = _c.disabled, disabled = _h === void 0 ? false : _h;
var _j = this.state, columnMeasureInfo = _j.columnMeasureInfo, isDropping = _j.isDropping;
var _k = this.state.selectionState, _l = _k.isSelected, isSelected = _l === void 0 ? false : _l, _m = _k.isSelectionModal, isSelectionModal = _m === void 0 ? false : _m;
var isDraggable = dragDropEvents ? !!(dragDropEvents.canDrag && dragDropEvents.canDrag(item)) : undefined;
var droppingClassName = isDropping ? this._droppingClassNames || DEFAULT_DROPPING_CSS_CLASS : '';
var ariaLabel = getRowAriaLabel ? getRowAriaLabel(item) : undefined;
var ariaRowDescription = getRowAriaDescription ? getRowAriaDescription(item) : undefined;
var ariaDescribedBy = getRowAriaDescribedBy ? getRowAriaDescribedBy(item) : undefined;
var canSelect = !!selection && selection.canSelectItem(item, itemIndex) && !disabled;
var isContentUnselectable = selectionMode === Selection_1.SelectionMode.multiple;
var showCheckbox = selectionMode !== Selection_1.SelectionMode.none && checkboxVisibility !== DetailsList_types_1.CheckboxVisibility.hidden;
var ariaSelected = selectionMode === Selection_1.SelectionMode.none ? undefined : isSelected;
var ariaPositionInSet = group ? itemIndex - group.startIndex + 1 : undefined;
var ariaSetSize = group ? group.count : undefined;
var focusZoneDirection = (_a = focusZoneProps === null || focusZoneProps === void 0 ? void 0 : focusZoneProps.direction) !== null && _a !== void 0 ? _a : FocusZone_1.FocusZoneDirection.horizontal;
this._classNames = tslib_1.__assign(tslib_1.__assign({}, this._classNames), getClassNames(styles, {
theme: theme,
isSelected: isSelected,
canSelect: !isContentUnselectable,
anySelected: isSelectionModal,
checkboxCellClassName: checkboxCellClassName,
droppingClassName: droppingClassName,
className: className,
compact: compact,
enableUpdateAnimations: enableUpdateAnimations,
cellStyleProps: cellStyleProps,
disabled: disabled,
}));
var rowClassNames = {
isMultiline: this._classNames.isMultiline,
isRowHeader: this._classNames.isRowHeader,
cell: this._classNames.cell,
cellAnimation: this._classNames.cellAnimation,
cellPadded: this._classNames.cellPadded,
cellUnpadded: this._classNames.cellUnpadded,
fields: this._classNames.fields,
};
// Only re-assign rowClassNames when classNames have changed.
// Otherwise, they will cause DetailsRowFields to unnecessarily
// re-render, see https://github.com/microsoft/fluentui/pull/8799.
// Refactor DetailsRowFields to generate own styles to remove need for this.
if (!(0, Utilities_1.shallowCompare)(this._rowClassNames || {}, rowClassNames)) {
this._rowClassNames = rowClassNames;
}
var RowFields = rowFieldsAs ? (0, Utilities_1.composeComponentAs)(rowFieldsAs, DetailsRowFields_1.DetailsRowFields) : DetailsRowFields_1.DetailsRowFields;
var rowFields = (React.createElement(RowFields, { rowClassNames: this._rowClassNames, rowHeaderId: "".concat(id, "-header"), cellsByColumn: cellsByColumn, columns: columns, item: item, itemIndex: itemIndex, isSelected: isSelected, columnStartIndex: (showCheckbox ? 1 : 0) + (groupNestingDepth ? 1 : 0), onRenderItemColumn: onRenderItemColumn, onRenderField: onRenderField, getCellValueKey: getCellValueKey, enableUpdateAnimations: enableUpdateAnimations, cellStyleProps: cellStyleProps }));
var defaultRole = 'row';
var role = this.props.role ? this.props.role : defaultRole;
this._ariaRowDescriptionId = (0, Utilities_3.getId)('DetailsRow-description');
// When the user does not specify any column is a row-header in the columns props,
// The aria-labelledby of the checkbox does not specify {id}-header.
var hasRowHeader = columns.some(function (column) {
return !!column.isRowHeader;
});
var ariaLabelledby = "".concat(id, "-checkbox") + (hasRowHeader ? " ".concat(id, "-header") : '');
// additional props for rows within a GroupedList
// these are needed for treegrid row semantics, but not grid row semantics
var groupedListRowProps = isGridRow
? {}
: {
'aria-level': (groupNestingDepth && groupNestingDepth + 1) || undefined,
'aria-posinset': ariaPositionInSet,
'aria-setsize': ariaSetSize,
};
return (React.createElement(FocusZone_1.FocusZone, tslib_1.__assign({ "data-is-focusable": true }, (0, Utilities_1.getNativeProps)(this.props, Utilities_1.divProperties), (typeof isDraggable === 'boolean'
? {
'data-is-draggable': isDraggable, // This data attribute is used by some host applications.
draggable: isDraggable,
}
: {}), focusZoneProps, groupedListRowProps, { direction: focusZoneDirection,
// eslint-disable-next-line @typescript-eslint/no-deprecated
elementRef: this._root, componentRef: this._focusZone, role: role, "aria-label": ariaLabel, "aria-disabled": disabled || undefined, "aria-describedby": ariaRowDescription ? this._ariaRowDescriptionId : ariaDescribedBy, className: this._classNames.root, "data-selection-index": itemIndex, "data-selection-touch-invoke": true, "data-selection-disabled": (_b = this.props['data-selection-disabled']) !== null && _b !== void 0 ? _b : (disabled || undefined), "data-item-index": itemIndex, "aria-rowindex": ariaPositionInSet === undefined ? itemIndex + flatIndexOffset : undefined, "data-automationid": "DetailsRow", "aria-selected": ariaSelected, allowFocusRoot: true }),
ariaRowDescription ? (React.createElement("span", { key: "description", role: "presentation", hidden: true, id: this._ariaRowDescriptionId }, ariaRowDescription)) : null,
showCheckbox && (React.createElement("div", { role: "gridcell", "data-selection-toggle": true, className: this._classNames.checkCell }, onRenderCheck({
id: id ? "".concat(id, "-checkbox") : undefined,
selected: isSelected,
selectionMode: selectionMode,
anySelected: isSelectionModal,
'aria-label': checkButtonAriaLabel,
'aria-labelledby': id ? ariaLabelledby : undefined,
canSelect: canSelect,
compact: compact,
className: this._classNames.check,
theme: theme,
isVisible: checkboxVisibility === DetailsList_types_1.CheckboxVisibility.always,
onRenderDetailsCheckbox: onRenderDetailsCheckbox,
useFastIcons: useFastIcons,
}))),
React.createElement(GroupSpacer_1.GroupSpacer, { indentWidth: indentWidth, role: "gridcell", count: groupNestingDepth === 0 ? -1 : groupNestingDepth }),
item && rowFields,
columnMeasureInfo && (React.createElement("span", { role: "presentation", className: (0, Utilities_1.css)(this._classNames.cellMeasurer, this._classNames.cell), ref: this._cellMeasurer },
React.createElement(RowFields, { rowClassNames: this._rowClassNames, rowHeaderId: "".concat(id, "-header"), columns: [columnMeasureInfo.column], item: item, itemIndex: itemIndex, columnStartIndex: (showCheckbox ? 1 : 0) + (groupNestingDepth ? 1 : 0) + columns.length, onRenderItemColumn: onRenderItemColumn, getCellValueKey: getCellValueKey })))));
};
/**
* measure cell at index. and call the call back with the measured cell width when finish measure
*
* @param index - The cell index
* @param onMeasureDone - The call back function when finish measure
*/
DetailsRowBase.prototype.measureCell = function (index, onMeasureDone) {
var _a = this.props.columns, columns = _a === void 0 ? NO_COLUMNS : _a;
var column = tslib_1.__assign({}, columns[index]);
column.minWidth = 0;
column.maxWidth = 999999;
delete column.calculatedWidth;
this.setState({
columnMeasureInfo: {
index: index,
column: column,
onMeasureDone: onMeasureDone,
},
});
};
DetailsRowBase.prototype.focus = function (forceIntoFirstElement) {
var _a;
if (forceIntoFirstElement === void 0) { forceIntoFirstElement = false; }
return !!((_a = this._focusZone.current) === null || _a === void 0 ? void 0 : _a.focus(forceIntoFirstElement));
};
DetailsRowBase.prototype._onRenderCheck = function (props) {
return React.createElement(DetailsRowCheck_1.DetailsRowCheck, tslib_1.__assign({}, props));
};
DetailsRowBase.prototype._getRowDragDropOptions = function () {
var _a = this.props, item = _a.item, itemIndex = _a.itemIndex, dragDropEvents = _a.dragDropEvents, eventsToRegister = _a.eventsToRegister;
var options = {
eventMap: eventsToRegister,
selectionIndex: itemIndex,
context: { data: item, index: itemIndex },
canDrag: dragDropEvents.canDrag,
canDrop: dragDropEvents.canDrop,
onDragStart: dragDropEvents.onDragStart,
updateDropState: this._updateDroppingState,
onDrop: dragDropEvents.onDrop,
onDragEnd: dragDropEvents.onDragEnd,
onDragOver: dragDropEvents.onDragOver,
};
return options;
};
return DetailsRowBase;
}(React.Component));
exports.DetailsRowBase = DetailsRowBase;
function getSelectionState(props) {
var _a;
var itemIndex = props.itemIndex, selection = props.selection;
return {
isSelected: !!(selection === null || selection === void 0 ? void 0 : selection.isIndexSelected(itemIndex)),
isSelectionModal: !!((_a = selection === null || selection === void 0 ? void 0 : selection.isModal) === null || _a === void 0 ? void 0 : _a.call(selection)),
};
}
});
//# sourceMappingURL=DetailsRow.base.js.map