office-ui-fabric-react
Version:
Reusable React components for building experiences for Office 365.
250 lines (248 loc) • 13.5 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var React = require('react');
var BaseComponent_1 = require('../../common/BaseComponent');
var DetailsList_Props_1 = require('./DetailsList.Props');
var FocusZone_1 = require('../../FocusZone');
var Check_1 = require('../Check/Check');
var GroupSpacer_1 = require('../GroupedList/GroupSpacer');
var css_1 = require('../../utilities/css');
var interfaces_1 = require('../../utilities/selection/interfaces');
var rtl_1 = require('../../utilities/rtl');
require('./DetailsHeader.scss');
var MOUSEDOWN_PRIMARY_BUTTON = 0; // for mouse down event we are using ev.button property, 0 means left button
var MOUSEMOVE_PRIMARY_BUTTON = 1; // for mouse move event we are using ev.buttons property, 1 means left button
var INNER_PADDING = 16;
(function (SelectAllVisibility) {
SelectAllVisibility[SelectAllVisibility["none"] = 0] = "none";
SelectAllVisibility[SelectAllVisibility["hidden"] = 1] = "hidden";
SelectAllVisibility[SelectAllVisibility["visible"] = 2] = "visible";
})(exports.SelectAllVisibility || (exports.SelectAllVisibility = {}));
var SelectAllVisibility = exports.SelectAllVisibility;
var DetailsHeader = (function (_super) {
__extends(DetailsHeader, _super);
function DetailsHeader(props) {
_super.call(this, props);
this.state = {
columnResizeDetails: null,
groupNestingDepth: this.props.groupNestingDepth,
isAllCollapsed: this.props.isAllCollapsed
};
this._onToggleCollapseAll = this._onToggleCollapseAll.bind(this);
this._onSelectAllClicked = this._onSelectAllClicked.bind(this);
}
DetailsHeader.prototype.componentDidMount = function () {
var selection = this.props.selection;
this._events.on(selection, interfaces_1.SELECTION_CHANGE, this._onSelectionChanged);
this._events.on(this.refs.root, 'mousedown', this._onSizerDown);
};
DetailsHeader.prototype.componentWillReceiveProps = function (newProps) {
var groupNestingDepth = this.state.groupNestingDepth;
if (newProps.groupNestingDepth !== groupNestingDepth) {
this.setState({ groupNestingDepth: newProps.groupNestingDepth });
}
};
DetailsHeader.prototype.render = function () {
var _this = this;
var _a = this.props, columns = _a.columns, ariaLabel = _a.ariaLabel, ariaLabelForSelectAllCheckbox = _a.ariaLabelForSelectAllCheckbox, selectAllVisibility = _a.selectAllVisibility;
var _b = this.state, isAllSelected = _b.isAllSelected, columnResizeDetails = _b.columnResizeDetails, isSizing = _b.isSizing, groupNestingDepth = _b.groupNestingDepth, isAllCollapsed = _b.isAllCollapsed;
return (React.createElement("div", {role: 'row', "aria-label": ariaLabel, className: css_1.css('ms-DetailsHeader', {
'is-allSelected': isAllSelected,
'is-selectAllHidden': selectAllVisibility === SelectAllVisibility.hidden,
'is-resizingColumn': !!columnResizeDetails && isSizing
}), onMouseMove: this._onMove.bind(this), onMouseUp: this._onUp.bind(this), ref: 'root', "data-automationid": 'DetailsHeader'},
React.createElement(FocusZone_1.FocusZone, {ref: 'focusZone', direction: FocusZone_1.FocusZoneDirection.horizontal},
React.createElement("div", {className: 'ms-DetailsHeader-cellWrapper', role: 'columnheader'}, (selectAllVisibility === SelectAllVisibility.visible) ? (React.createElement("button", {className: 'ms-DetailsHeader-cell is-check', onClick: this._onSelectAllClicked, "aria-label": ariaLabelForSelectAllCheckbox, "aria-pressed": isAllSelected},
React.createElement(Check_1.Check, {isChecked: isAllSelected})
)) : null),
groupNestingDepth > 0 ? (React.createElement("button", {className: 'ms-DetailsHeader-cell', onClick: this._onToggleCollapseAll},
React.createElement("i", {className: css_1.css('ms-DetailsHeader-collapseButton ms-Icon ms-Icon--ChevronDown', {
'is-collapsed': isAllCollapsed
})})
)) : (null),
GroupSpacer_1.GroupSpacer({ count: groupNestingDepth - 1 }),
columns.map(function (column, columnIndex) { return (React.createElement("div", {key: column.key, className: 'ms-DetailsHeader-cellSizeWrapper'},
React.createElement("div", {className: 'ms-DetailsHeader-cellWrapper', role: 'columnheader'},
React.createElement("button", {key: column.fieldName, disabled: column.columnActionsMode === DetailsList_Props_1.ColumnActionsMode.disabled, className: css_1.css('ms-DetailsHeader-cell', column.headerClassName, {
'is-actionable': column.columnActionsMode !== DetailsList_Props_1.ColumnActionsMode.disabled,
'is-empty': !column.name,
'is-icon-visible': column.isSorted || column.isGrouped || column.isFiltered
}), style: { width: column.calculatedWidth + INNER_PADDING }, onClick: _this._onColumnClick.bind(_this, column), onContextMenu: _this._onColumnContextMenu.bind(_this, column), "aria-haspopup": column.columnActionsMode === DetailsList_Props_1.ColumnActionsMode.hasDropdown, "aria-label": column.ariaLabel || column.name, "aria-sort": column.isSorted ? (column.isSortedDescending ? 'descending' : 'ascending') : 'none', "data-automationid": 'ColumnsHeaderColumn', "data-item-key": column.key},
column.isFiltered && (React.createElement("i", {className: 'ms-Icon ms-Icon--filter'})),
column.isSorted && (React.createElement("i", {className: css_1.css('ms-Icon', {
'ms-Icon--SortUp': !column.isSortedDescending,
'ms-Icon--SortDown': column.isSortedDescending
})})),
column.isGrouped && (React.createElement("i", {className: 'ms-Icon ms-Icon--GroupedDescending'})),
column.iconClassName && (React.createElement("i", {className: 'ms-Icon ' + column.iconClassName})),
column.name,
column.columnActionsMode === DetailsList_Props_1.ColumnActionsMode.hasDropdown && (React.createElement("i", {className: 'ms-DetailsHeader-filterChevron ms-Icon ms-Icon--ChevronDown'})))
),
(column.isResizable) ? (React.createElement("div", {"data-sizer-index": columnIndex, className: css_1.css('ms-DetailsHeader-cell is-sizer', {
'is-resizing': columnResizeDetails && columnResizeDetails.columnIndex === columnIndex && isSizing
}), onDoubleClick: _this._onSizerDoubleClick.bind(_this, columnIndex)})) : (null))); }))
));
};
/** Set focus to the active thing in the focus area. */
DetailsHeader.prototype.focus = function () {
return this.refs.focusZone.focus();
};
/**
* double click on the column sizer will auto ajust column width
* to fit the longest content among current rendered rows.
*
* @private
* @param {number} columnIndex (index of the column user double clicked)
* @param {React.MouseEvent} ev (mouse double click event)
*/
DetailsHeader.prototype._onSizerDoubleClick = function (columnIndex, ev) {
var _a = this.props, onColumnAutoResized = _a.onColumnAutoResized, columns = _a.columns;
if (onColumnAutoResized) {
onColumnAutoResized(columns[columnIndex], columnIndex);
}
};
/**
* Called when the select all toggle is clicked.
*/
DetailsHeader.prototype._onSelectAllClicked = function () {
var selection = this.props.selection;
selection.toggleAllSelected();
};
/**
* mouse move event handler in the header
* it will set isSizing state to true when user clicked on the sizer and move the mouse.
*
* @private
* @param {React.MouseEvent} ev (mouse move event)
*/
DetailsHeader.prototype._onMove = function (ev) {
var _a = ev.buttons, buttons = _a === void 0 ? MOUSEMOVE_PRIMARY_BUTTON : _a;
var _b = this.props, onColumnIsSizingChanged = _b.onColumnIsSizingChanged, columns = _b.columns;
var _c = this.state, columnResizeDetails = _c.columnResizeDetails, isSizing = _c.isSizing;
if (columnResizeDetails) {
if (buttons !== MOUSEMOVE_PRIMARY_BUTTON) {
// cancel mouse down event and return early when the primary button is not pressed
this._onUp(ev);
return;
}
if (!isSizing && ev.clientX !== columnResizeDetails.originX) {
isSizing = true;
this._events.on(window, 'mousemove', this._onSizerMove, true);
this._events.on(window, 'mouseup', this._onSizerUp, true);
this.setState({ isSizing: isSizing });
if (onColumnIsSizingChanged) {
onColumnIsSizingChanged(columns[columnResizeDetails.columnIndex], true);
}
}
}
};
/**
* mouse up event handler in the header
* clear the resize related state.
* This is to ensure we can catch double click event
*
* @private
* @param {React.MouseEvent} ev (mouse up event)
*/
DetailsHeader.prototype._onUp = function (ev) {
this.setState({
columnResizeDetails: null,
isSizing: false
});
};
DetailsHeader.prototype._onSizerDown = function (ev) {
var columnIndexAttr = ev.target.getAttribute('data-sizer-index');
var columnIndex = Number(columnIndexAttr);
var columns = this.props.columns;
if (columnIndexAttr === null || ev.button !== MOUSEDOWN_PRIMARY_BUTTON) {
// Ignore anything except the primary button.
return;
}
this.setState({
columnResizeDetails: {
columnIndex: columnIndex,
columnMinWidth: columns[columnIndex].calculatedWidth,
originX: ev.clientX
}
});
ev.preventDefault();
ev.stopPropagation();
};
DetailsHeader.prototype._onSelectionChanged = function () {
var isAllSelected = this.props.selection.isAllSelected();
if (this.state.isAllSelected !== isAllSelected) {
this.setState({
isAllSelected: isAllSelected
});
}
};
DetailsHeader.prototype._onSizerMove = function (ev) {
var _a = ev.buttons, buttons = _a === void 0 ? MOUSEMOVE_PRIMARY_BUTTON : _a;
var columnResizeDetails = this.state.columnResizeDetails;
if (columnResizeDetails) {
if (buttons !== MOUSEMOVE_PRIMARY_BUTTON) {
// cancel mouse down event and return early when the primary button is not pressed
this._onSizerUp();
return;
}
var _b = this.props, onColumnResized = _b.onColumnResized, columns = _b.columns;
if (onColumnResized) {
var movement = ev.clientX - columnResizeDetails.originX;
if (rtl_1.getRTL()) {
movement = -movement;
}
onColumnResized(columns[columnResizeDetails.columnIndex], columnResizeDetails.columnMinWidth + movement);
}
}
};
DetailsHeader.prototype._onSizerUp = function () {
var _a = this.props, columns = _a.columns, onColumnIsSizingChanged = _a.onColumnIsSizingChanged;
var columnResizeDetails = this.state.columnResizeDetails;
this._events.off(window);
this.setState({
columnResizeDetails: null,
isSizing: false
});
if (onColumnIsSizingChanged) {
onColumnIsSizingChanged(columns[columnResizeDetails.columnIndex], false);
}
};
DetailsHeader.prototype._onColumnClick = function (column, ev) {
var onColumnClick = this.props.onColumnClick;
if (column.onColumnClick) {
column.onColumnClick(ev, column);
}
if (onColumnClick) {
onColumnClick(ev, column);
}
};
DetailsHeader.prototype._onColumnContextMenu = function (column, ev) {
var onColumnContextMenu = this.props.onColumnContextMenu;
if (column.onContextMenu) {
column.onColumnContextMenu(column, ev);
}
if (onColumnContextMenu) {
onColumnContextMenu(column, ev);
}
};
DetailsHeader.prototype._onToggleCollapseAll = function () {
var onToggleCollapseAll = this.props.onToggleCollapseAll;
var newCollapsed = !this.state.isAllCollapsed;
this.setState({
isAllCollapsed: newCollapsed
});
if (onToggleCollapseAll) {
onToggleCollapseAll(newCollapsed);
}
};
DetailsHeader.defaultProps = {
isSelectAllVisible: SelectAllVisibility.visible
};
return DetailsHeader;
}(BaseComponent_1.BaseComponent));
exports.DetailsHeader = DetailsHeader;
//# sourceMappingURL=DetailsHeader.js.map