text: import * as tslib_1 from "tslib";
  import * as React from 'react';
  import { BaseComponent, assign, elementContains, getRTLSafeKeyCode, createRef, classNamesFunction } from '../../Utilities';
  import { CheckboxVisibility, ColumnActionsMode, ConstrainMode, DetailsListLayoutMode, ColumnDragEndLocation } from '../DetailsList/DetailsList.types';
  import { DetailsHeader } from '../DetailsList/DetailsHeader';
  import { SelectAllVisibility } from '../DetailsList/DetailsHeader.types';
  import { DetailsRow } from '../DetailsList/DetailsRow';
  import { FocusZone, FocusZoneDirection } from '../../FocusZone';
  import { Selection, SelectionMode, SelectionZone } from '../../utilities/selection/index';
  import { DragDropHelper } from '../../utilities/dragdrop/DragDropHelper';
  import { GroupedList } from '../../GroupedList';
  import { List } from '../../List';
  import { withViewport } from '../../utilities/decorators/withViewport';
  import { GetGroupCount } from '../../utilities/groupedList/GroupedListUtility';
  import { DEFAULT_CELL_STYLE_PROPS } from './DetailsRow.styles';
  var getClassNames = classNamesFunction();
  var MIN_COLUMN_WIDTH = 100; // this is the global min width
  var CHECKBOX_WIDTH = 40;
  var GROUP_EXPAND_WIDTH = 36;
  var DEFAULT_RENDERED_WINDOWS_AHEAD = 2;
  var DEFAULT_RENDERED_WINDOWS_BEHIND = 2;
  var SHIMMER_INITIAL_ITEMS = 10;
  var SHIMMER_ITEMS = new Array(SHIMMER_INITIAL_ITEMS);
  var DetailsListBase = /** @class */ (function (_super) {
      tslib_1.__extends(DetailsListBase, _super);
      function DetailsListBase(props) {
          var _this = _super.call(this, props) || this;
          // References
          _this._root = createRef();
          _this._header = createRef();
          _this._groupedList = createRef();
          _this._list = createRef();
          _this._focusZone = createRef();
          _this._selectionZone = createRef();
          _this._onRenderRow = function (props, defaultRender) {
              return React.createElement(DetailsRow, tslib_1.__assign({}, props));
          };
          _this._onRenderDetailsHeader = function (detailsHeaderProps, defaultRender) {
              return React.createElement(DetailsHeader, tslib_1.__assign({}, detailsHeaderProps));
          };
          _this._onRenderDetailsFooter = function (detailsFooterProps, defaultRender) {
              return null;
          };
          _this._onRenderListCell = function (nestingDepth) {
              return function (item, itemIndex) {
                  return _this._onRenderCell(nestingDepth, item, itemIndex);
              };
          };
          _this._activeRows = {};
          _this._columnOverrides = {};
          _this._onColumnIsSizingChanged = _this._onColumnIsSizingChanged.bind(_this);
          _this._onColumnResized = _this._onColumnResized.bind(_this);
          _this._onColumnAutoResized = _this._onColumnAutoResized.bind(_this);
          _this._onRowDidMount = _this._onRowDidMount.bind(_this);
          _this._onRowWillUnmount = _this._onRowWillUnmount.bind(_this);
          _this._onToggleCollapse = _this._onToggleCollapse.bind(_this);
          _this._onActiveRowChanged = _this._onActiveRowChanged.bind(_this);
          _this._onBlur = _this._onBlur.bind(_this);
          _this._onHeaderKeyDown = _this._onHeaderKeyDown.bind(_this);
          _this._onContentKeyDown = _this._onContentKeyDown.bind(_this);
          _this._onRenderCell = _this._onRenderCell.bind(_this);
          _this._onGroupExpandStateChanged = _this._onGroupExpandStateChanged.bind(_this);
          _this._onColumnDragEnd = _this._onColumnDragEnd.bind(_this);
          _this.state = {
              focusedItemIndex: -1,
              lastWidth: 0,
              adjustedColumns: _this._getAdjustedColumns(props),
              isSizing: false,
              isDropping: false,
              isCollapsed: props.groupProps && props.groupProps.isAllGroupsCollapsed,
              isSomeGroupExpanded: props.groupProps && !props.groupProps.isAllGroupsCollapsed
          };
          _this._selection = props.selection || new Selection({ onSelectionChanged: undefined, getKey: props.getKey });
          if (!_this.props.disableSelectionZone) {
              _this._selection.setItems(props.items, false);
          }
          _this._dragDropHelper = props.dragDropEvents
              ? new DragDropHelper({
                  selection: _this._selection,
                  minimumPixelsForDrag: props.minimumPixelsForDrag
              })
              : null;
          _this._initialFocusedIndex = props.initialFocusedIndex;
          return _this;
      }
      DetailsListBase.prototype.scrollToIndex = function (index, measureItem, scrollToMode) {
          this._list.current && this._list.current.scrollToIndex(index, measureItem, scrollToMode);
          this._groupedList.current && this._groupedList.current.scrollToIndex(index, measureItem, scrollToMode);
      };
      DetailsListBase.prototype.focusIndex = function (index, forceIntoFirstElement, measureItem, scrollToMode) {
          if (forceIntoFirstElement === void 0) { forceIntoFirstElement = false; }
          var item = this.props.items[index];
          if (item) {
              this.scrollToIndex(index, measureItem, scrollToMode);
              var itemKey = this._getItemKey(item, index);
              var row = this._activeRows[itemKey];
              if (row) {
                  this._setFocusToRow(row, forceIntoFirstElement);
              }
          }
      };
      DetailsListBase.prototype.getStartItemIndexInView = function () {
          if (this._list && this._list.current) {
              return this._list.current.getStartItemIndexInView();
          }
          else if (this._groupedList && this._groupedList.current) {
              return this._groupedList.current.getStartItemIndexInView();
          }
          return 0;
      };
      DetailsListBase.prototype.componentWillUnmount = function () {
          if (this._dragDropHelper) {
              this._dragDropHelper.dispose();
          }
      };
      DetailsListBase.prototype.componentDidUpdate = function (prevProps, prevState) {
          if (this._initialFocusedIndex !== undefined) {
              var item = this.props.items[this._initialFocusedIndex];
              if (item) {
                  var itemKey = this._getItemKey(item, this._initialFocusedIndex);
                  var row = this._activeRows[itemKey];
                  if (row) {
                      this._setFocusToRowIfPending(row);
                  }
              }
          }
          if (this.props.items !== prevProps.items &&
              this.props.items.length > 0 &&
              this.state.focusedItemIndex !== -1 &&
              !elementContains(this._root.current, document.activeElement, false)) {
              // Item set has changed and previously-focused item is gone.
              // Set focus to item at index of previously-focused item if it is in range,
              // else set focus to the last item.
              var index = this.state.focusedItemIndex < this.props.items.length ? this.state.focusedItemIndex : this.props.items.length - 1;
              var item = this.props.items[index];
              var itemKey = this._getItemKey(item, this.state.focusedItemIndex);
              var row = this._activeRows[itemKey];
              if (row) {
                  this._setFocusToRow(row);
              }
              else {
                  this._initialFocusedIndex = index;
              }
          }
          if (this.props.onDidUpdate) {
              this.props.onDidUpdate(this);
          }
      };
      DetailsListBase.prototype.componentWillReceiveProps = function (newProps) {
          var _a = this.props, checkboxVisibility = _a.checkboxVisibility, items = _a.items, setKey = _a.setKey, _b = _a.selectionMode, selectionMode = _b === void 0 ? this._selection.mode : _b, columns = _a.columns, viewport = _a.viewport, compact = _a.compact;
          var _c = (this.props.groupProps || {}).isAllGroupsCollapsed, isAllGroupsCollapsed = _c === void 0 ? undefined : _c;
          var shouldResetSelection = newProps.setKey !== setKey || newProps.setKey === undefined;
          var shouldForceUpdates = false;
          if (newProps.layoutMode !== this.props.layoutMode) {
              shouldForceUpdates = true;
          }
          if (shouldResetSelection) {
              this._initialFocusedIndex = newProps.initialFocusedIndex;
              // reset focusedItemIndex when setKey changes
              this.setState({
                  focusedItemIndex: this._initialFocusedIndex !== undefined ? this._initialFocusedIndex : -1
              });
          }
          if (!this.props.disableSelectionZone && newProps.items !== items) {
              this._selection.setItems(newProps.items, shouldResetSelection);
          }
          if (newProps.checkboxVisibility !== checkboxVisibility ||
              newProps.columns !== columns ||
              newProps.viewport.width !== viewport.width ||
              newProps.compact !== compact) {
              shouldForceUpdates = true;
          }
          this._adjustColumns(newProps, true);
          if (newProps.selectionMode !== selectionMode) {
              shouldForceUpdates = true;
          }
          if (isAllGroupsCollapsed === undefined && (newProps.groupProps && newProps.groupProps.isAllGroupsCollapsed !== undefined)) {
              this.setState({
                  isCollapsed: newProps.groupProps.isAllGroupsCollapsed,
                  isSomeGroupExpanded: !newProps.groupProps.isAllGroupsCollapsed
              });
          }
          if (shouldForceUpdates) {
              this._pendingForceUpdate = true;
          }
      };
      DetailsListBase.prototype.componentWillUpdate = function () {
          if (this._pendingForceUpdate) {
              this._forceListUpdates();
          }
      };
      DetailsListBase.prototype.render = function () {
          var _a = this.props, ariaLabelForListHeader = _a.ariaLabelForListHeader, ariaLabelForSelectAllCheckbox = _a.ariaLabelForSelectAllCheckbox, ariaLabelForSelectionColumn = _a.ariaLabelForSelectionColumn, className = _a.className, checkboxVisibility = _a.checkboxVisibility, compact = _a.compact, constrainMode = _a.constrainMode, dragDropEvents = _a.dragDropEvents, groups = _a.groups, groupProps = _a.groupProps, indentWidth = _a.indentWidth, items = _a.items, isHeaderVisible = _a.isHeaderVisible, layoutMode = _a.layoutMode, onItemInvoked = _a.onItemInvoked, onItemContextMenu = _a.onItemContextMenu, onColumnHeaderClick = _a.onColumnHeaderClick, onColumnHeaderContextMenu = _a.onColumnHeaderContextMenu, _b = _a.selectionMode, selectionMode = _b === void 0 ? this._selection.mode : _b, selectionPreservedOnEmptyClick = _a.selectionPreservedOnEmptyClick, selectionZoneProps = _a.selectionZoneProps, ariaLabel = _a.ariaLabel, ariaLabelForGrid = _a.ariaLabelForGrid, rowElementEventMap = _a.rowElementEventMap, _c = _a.shouldApplyApplicationRole, shouldApplyApplicationRole = _c === void 0 ? false : _c, getKey = _a.getKey, listProps = _a.listProps, usePageCache = _a.usePageCache, onShouldVirtualize = _a.onShouldVirtualize, enableShimmer = _a.enableShimmer, viewport = _a.viewport, minimumPixelsForDrag = _a.minimumPixelsForDrag, getGroupHeight = _a.getGroupHeight, styles = _a.styles, theme = _a.theme, _d = _a.cellStyleProps, cellStyleProps = _d === void 0 ? DEFAULT_CELL_STYLE_PROPS : _d;
          var _e = this.state, adjustedColumns = _e.adjustedColumns, isCollapsed = _e.isCollapsed, isSizing = _e.isSizing, isSomeGroupExpanded = _e.isSomeGroupExpanded;
          var _f = this, selection = _f._selection, dragDropHelper = _f._dragDropHelper;
          var groupNestingDepth = this._getGroupNestingDepth();
          var additionalListProps = tslib_1.__assign({ renderedWindowsAhead: isSizing ? 0 : DEFAULT_RENDERED_WINDOWS_AHEAD, renderedWindowsBehind: isSizing ? 0 : DEFAULT_RENDERED_WINDOWS_BEHIND, getKey: getKey }, listProps);
          var selectAllVisibility = SelectAllVisibility.none; // for SelectionMode.none
          if (selectionMode === SelectionMode.single) {
              selectAllVisibility = SelectAllVisibility.hidden;
          }
          if (selectionMode === SelectionMode.multiple) {
              // if isCollapsedGroupSelectVisible is false, disable select all when the list has all collapsed groups
              var isCollapsedGroupSelectVisible = groupProps && groupProps.headerProps && groupProps.headerProps.isCollapsedGroupSelectVisible;
              if (isCollapsedGroupSelectVisible === undefined) {
                  isCollapsedGroupSelectVisible = true;
              }
              var isSelectAllVisible = isCollapsedGroupSelectVisible || !groups || isSomeGroupExpanded;
              selectAllVisibility = isSelectAllVisible ? SelectAllVisibility.visible : SelectAllVisibility.hidden;
          }
          if (checkboxVisibility === CheckboxVisibility.hidden) {
              selectAllVisibility = SelectAllVisibility.none;
          }
          var _g = this.props, _h = _g.onRenderDetailsHeader, onRenderDetailsHeader = _h === void 0 ? this._onRenderDetailsHeader : _h, _j = _g.onRenderDetailsFooter, onRenderDetailsFooter = _j === void 0 ? this._onRenderDetailsFooter : _j;
          var detailsFooterProps = this._getDetailsFooterProps();
          var columnReorderProps = this._getColumnReorderProps();
          var rowCount = (isHeaderVisible ? 1 : 0) + GetGroupCount(groups) + (items ? items.length : 0);
          var classNames = getClassNames(styles, {
              theme: theme,
              compact: compact,
              isFixed: layoutMode === DetailsListLayoutMode.fixedColumns,
              isHorizontalConstrained: constrainMode === ConstrainMode.horizontalConstrained,
              className: className
          });
          var list = groups ? (React.createElement(GroupedList, { componentRef: this._groupedList, groups: groups, groupProps: groupProps ? this._getGroupProps(groupProps) : undefined, items: items, onRenderCell: this._onRenderCell, selection: selection, selectionMode: checkboxVisibility !== CheckboxVisibility.hidden ? selectionMode : SelectionMode.none, dragDropEvents: dragDropEvents, dragDropHelper: dragDropHelper, eventsToRegister: rowElementEventMap, listProps: additionalListProps, onGroupExpandStateChanged: this._onGroupExpandStateChanged, usePageCache: usePageCache, onShouldVirtualize: onShouldVirtualize, getGroupHeight: getGroupHeight })) : (React.createElement(List, tslib_1.__assign({ ref: this._list, role: "presentation", items: enableShimmer && !items.length ? SHIMMER_ITEMS : items, onRenderCell: this._onRenderListCell(0), usePageCache: usePageCache, onShouldVirtualize: onShouldVirtualize }, additionalListProps)));
          return (
          // If shouldApplyApplicationRole is true, role application will be applied to make arrow keys work
          // with JAWS.
          React.createElement("div", tslib_1.__assign({ ref: this._root, className: classNames.root, "data-automationid": "DetailsList", "data-is-scrollable": "false", "aria-label": ariaLabel }, (shouldApplyApplicationRole ? { role: 'application' } : {})),
              React.createElement("div", { role: "grid", "aria-label": ariaLabelForGrid, "aria-rowcount": rowCount, "aria-colcount": (selectAllVisibility !== SelectAllVisibility.none ? 1 : 0) + (adjustedColumns ? adjustedColumns.length : 0), "aria-readonly": "true" },
                  React.createElement("div", { onKeyDown: this._onHeaderKeyDown, role: "presentation", className: classNames.headerWrapper }, isHeaderVisible &&
                      onRenderDetailsHeader({
                          componentRef: this._header,
                          selectionMode: selectionMode,
                          layoutMode: layoutMode,
                          selection: selection,
                          columns: adjustedColumns,
                          onColumnClick: onColumnHeaderClick,
                          onColumnContextMenu: onColumnHeaderContextMenu,
                          onColumnResized: this._onColumnResized,
                          onColumnIsSizingChanged: this._onColumnIsSizingChanged,
                          onColumnAutoResized: this._onColumnAutoResized,
                          groupNestingDepth: groupNestingDepth,
                          isAllCollapsed: isCollapsed,
                          onToggleCollapseAll: this._onToggleCollapse,
                          ariaLabel: ariaLabelForListHeader,
                          ariaLabelForSelectAllCheckbox: ariaLabelForSelectAllCheckbox,
                          ariaLabelForSelectionColumn: ariaLabelForSelectionColumn,
                          selectAllVisibility: selectAllVisibility,
                          collapseAllVisibility: groupProps && groupProps.collapseAllVisibility,
                          viewport: viewport,
                          columnReorderProps: columnReorderProps,
                          minimumPixelsForDrag: minimumPixelsForDrag,
                          cellStyleProps: cellStyleProps,
                          checkboxVisibility: checkboxVisibility,
                          indentWidth: indentWidth
                      }, this._onRenderDetailsHeader)),
                  React.createElement("div", { onKeyDown: this._onContentKeyDown, role: "presentation", className: classNames.contentWrapper },
                      React.createElement(FocusZone, { componentRef: this._focusZone, className: classNames.focusZone, direction: FocusZoneDirection.vertical, isInnerZoneKeystroke: isRightArrow, onActiveElementChanged: this._onActiveRowChanged, onBlur: this._onBlur }, !this.props.disableSelectionZone ? (React.createElement(SelectionZone, tslib_1.__assign({ ref: this._selectionZone, selection: selection, selectionPreservedOnEmptyClick: selectionPreservedOnEmptyClick, selectionMode: selectionMode, onItemInvoked: onItemInvoked, onItemContextMenu: onItemContextMenu, enterModalOnTouch: this.props.enterModalSelectionOnTouch }, selectionZoneProps || {}), list)) : (list))),
                  onRenderDetailsFooter(tslib_1.__assign({}, detailsFooterProps), this._onRenderDetailsFooter))));
      };
      DetailsListBase.prototype.forceUpdate = function () {
          _super.prototype.forceUpdate.call(this);
          this._forceListUpdates();
      };
      DetailsListBase.prototype._onRenderCell = function (nestingDepth, item, index) {
          var _a = this.props, compact = _a.compact, dragDropEvents = _a.dragDropEvents, eventsToRegister = _a.rowElementEventMap, onRenderMissingItem = _a.onRenderMissingItem, onRenderItemColumn = _a.onRenderItemColumn, _b = _a.onRenderRow, onRenderRow = _b === void 0 ? this._onRenderRow : _b, _c = _a.selectionMode, selectionMode = _c === void 0 ? this._selection.mode : _c, viewport = _a.viewport, checkboxVisibility = _a.checkboxVisibility, getRowAriaLabel = _a.getRowAriaLabel, getRowAriaDescribedBy = _a.getRowAriaDescribedBy, checkButtonAriaLabel = _a.checkButtonAriaLabel, checkboxCellClassName = _a.checkboxCellClassName, groupProps = _a.groupProps, useReducedRowRenderer = _a.useReducedRowRenderer, indentWidth = _a.indentWidth, _d = _a.cellStyleProps, cellStyleProps = _d === void 0 ? DEFAULT_CELL_STYLE_PROPS : _d;
          var collapseAllVisibility = groupProps && groupProps.collapseAllVisibility;
          var selection = this._selection;
          var dragDropHelper = this._dragDropHelper;
          var columns = this.state.adjustedColumns;
          var rowProps = {
              item: item,
              itemIndex: index,
              compact: compact,
              columns: columns,
              groupNestingDepth: nestingDepth,
              selectionMode: selectionMode,
              selection: selection,
              onDidMount: this._onRowDidMount,
              onWillUnmount: this._onRowWillUnmount,
              onRenderItemColumn: onRenderItemColumn,
              eventsToRegister: eventsToRegister,
              dragDropEvents: dragDropEvents,
              dragDropHelper: dragDropHelper,
              viewport: viewport,
              checkboxVisibility: checkboxVisibility,
              collapseAllVisibility: collapseAllVisibility,
              getRowAriaLabel: getRowAriaLabel,
              getRowAriaDescribedBy: getRowAriaDescribedBy,
              checkButtonAriaLabel: checkButtonAriaLabel,
              checkboxCellClassName: checkboxCellClassName,
              useReducedRowRenderer: useReducedRowRenderer,
              indentWidth: indentWidth,
              cellStyleProps: cellStyleProps
          };
          if (!item) {
              if (onRenderMissingItem) {
                  return onRenderMissingItem(index, rowProps);
              }
              return null;
          }
          return onRenderRow(rowProps, this._onRenderRow);
      };
      DetailsListBase.prototype._onGroupExpandStateChanged = function (isSomeGroupExpanded) {
          this.setState({ isSomeGroupExpanded: isSomeGroupExpanded });
      };
      DetailsListBase.prototype._onColumnIsSizingChanged = function (column, isSizing) {
          this.setState({ isSizing: isSizing });
      };
      DetailsListBase.prototype._onHeaderKeyDown = function (ev) {
          if (ev.which === 40 /* down */) {
              if (this._focusZone.current && this._focusZone.current.focus()) {
                  // select the first item in list after down arrow key event
                  this._selection.setIndexSelected(0, true, false);
                  ev.preventDefault();
                  ev.stopPropagation();
              }
          }
      };
      DetailsListBase.prototype._onContentKeyDown = function (ev) {
          if (ev.which === 38 /* up */ && !ev.altKey) {
              if (this._header.current && this._header.current.focus()) {
                  ev.preventDefault();
                  ev.stopPropagation();
              }
          }
      };
      DetailsListBase.prototype._getGroupNestingDepth = function () {
          var groups = this.props.groups;
          var level = 0;
          var groupsInLevel = groups;
          while (groupsInLevel && groupsInLevel.length > 0) {
              level++;
              groupsInLevel = groupsInLevel[0].children;
          }
          return level;
      };
      DetailsListBase.prototype._onRowDidMount = function (row) {
          var _a = row.props, item = _a.item, itemIndex = _a.itemIndex;
          var itemKey = this._getItemKey(item, itemIndex);
          this._activeRows[itemKey] = row; // this is used for column auto resize
          this._setFocusToRowIfPending(row);
          var onRowDidMount = this.props.onRowDidMount;
          if (onRowDidMount) {
              onRowDidMount(item, itemIndex);
          }
      };
      DetailsListBase.prototype._setFocusToRowIfPending = function (row) {
          var itemIndex = row.props.itemIndex;
          if (this._initialFocusedIndex !== undefined && itemIndex === this._initialFocusedIndex) {
              this._setFocusToRow(row);
              delete this._initialFocusedIndex;
          }
      };
      DetailsListBase.prototype._setFocusToRow = function (row, forceIntoFirstElement) {
          if (forceIntoFirstElement === void 0) { forceIntoFirstElement = false; }
          if (this._selectionZone.current) {
              this._selectionZone.current.ignoreNextFocus();
          }
          this._async.setTimeout(function () {
              row.focus(forceIntoFirstElement);
          }, 0);
      };
      DetailsListBase.prototype._onRowWillUnmount = function (row) {
          var onRowWillUnmount = this.props.onRowWillUnmount;
          var _a = row.props, item = _a.item, itemIndex = _a.itemIndex;
          var itemKey = this._getItemKey(item, itemIndex);
          delete this._activeRows[itemKey];
          if (onRowWillUnmount) {
              onRowWillUnmount(item, itemIndex);
          }
      };
      DetailsListBase.prototype._onToggleCollapse = function (collapsed) {
          this.setState({
              isCollapsed: collapsed
          });
          if (this._groupedList.current) {
              this._groupedList.current.toggleCollapseAll(collapsed);
          }
      };
      DetailsListBase.prototype._onColumnDragEnd = function (props, event) {
          var columnReorderOptions = this.props.columnReorderOptions;
          var finalDropLocation = ColumnDragEndLocation.outside;
          if (columnReorderOptions && columnReorderOptions.onDragEnd) {
              if (props.dropLocation && props.dropLocation !== ColumnDragEndLocation.header) {
                  finalDropLocation = props.dropLocation;
              }
              else if (this._root.current) {
                  var clientRect = this._root.current.getBoundingClientRect();
                  if (event.clientX > clientRect.left &&
                      event.clientX < clientRect.right &&
                      event.clientY > clientRect.top &&
                      event.clientY < clientRect.bottom) {
                      finalDropLocation = ColumnDragEndLocation.surface;
                  }
              }
              columnReorderOptions.onDragEnd(finalDropLocation);
          }
      };
      DetailsListBase.prototype._forceListUpdates = function () {
          this._pendingForceUpdate = false;
          if (this._groupedList.current) {
              this._groupedList.current.forceUpdate();
          }
          if (this._list.current) {
              this._list.current.forceUpdate();
          }
      };
      DetailsListBase.prototype._notifyColumnsResized = function () {
          this.state.adjustedColumns.forEach(function (column) {
              if (column.onColumnResize) {
                  column.onColumnResize(column.currentWidth);
              }
          });
      };
      DetailsListBase.prototype._adjustColumns = function (newProps, forceUpdate, resizingColumnIndex) {
          var adjustedColumns = this._getAdjustedColumns(newProps, forceUpdate, resizingColumnIndex);
          var viewportWidth = this.props.viewport.width;
          if (adjustedColumns) {
              this.setState({
                  adjustedColumns: adjustedColumns,
                  lastWidth: viewportWidth
              }, this._notifyColumnsResized);
          }
      };
      /** Returns adjusted columns, given the viewport size and layout mode. */
      DetailsListBase.prototype._getAdjustedColumns = function (newProps, forceUpdate, resizingColumnIndex) {
          var _this = this;
          var newItems = newProps.items, layoutMode = newProps.layoutMode, selectionMode = newProps.selectionMode;
          var newColumns = newProps.columns;
          var viewportWidth = newProps.viewport.width;
          var columns = this.props ? this.props.columns : [];
          var lastWidth = this.state ? this.state.lastWidth : -1;
          var lastSelectionMode = this.state ? this.state.lastSelectionMode : undefined;
          if (viewportWidth !== undefined) {
              if (!forceUpdate && lastWidth === viewportWidth && lastSelectionMode === selectionMode && (!columns || newColumns === columns)) {
                  return [];
              }
          }
          else {
              viewportWidth = this.props.viewport.width;
          }
          newColumns = newColumns || buildColumns(newItems, true);
          var adjustedColumns;
          if (layoutMode === DetailsListLayoutMode.fixedColumns) {
              adjustedColumns = this._getFixedColumns(newColumns);
              // Preserve adjusted column calculated widths.
              adjustedColumns.forEach(function (column) {
                  _this._rememberCalculatedWidth(column, column.calculatedWidth);
              });
          }
          else {
              if (resizingColumnIndex !== undefined) {
                  adjustedColumns = this._getJustifiedColumnsAfterResize(newColumns, viewportWidth, newProps, resizingColumnIndex);
              }
              else {
                  adjustedColumns = this._getJustifiedColumns(newColumns, viewportWidth, newProps, 0);
              }
              adjustedColumns.forEach(function (column) {
                  _this._getColumnOverride(column.key).currentWidth = column.calculatedWidth;
              });
          }
          return adjustedColumns;
      };
      /** Builds a set of columns based on the given columns mixed with the current overrides. */
      DetailsListBase.prototype._getFixedColumns = function (newColumns) {
          var _this = this;
          return newColumns.map(function (column) {
              var newColumn = assign({}, column, _this._columnOverrides[column.key]);
              if (!newColumn.calculatedWidth) {
                  newColumn.calculatedWidth = newColumn.maxWidth || newColumn.minWidth || MIN_COLUMN_WIDTH;
              }
              return newColumn;
          });
      };
      DetailsListBase.prototype._getJustifiedColumnsAfterResize = function (newColumns, viewportWidth, props, resizingColumnIndex) {
          var _this = this;
          var fixedColumns = newColumns.slice(0, resizingColumnIndex);
          fixedColumns.forEach(function (column) { return (column.calculatedWidth = _this._getColumnOverride(column.key).currentWidth); });
          var fixedWidth = fixedColumns.reduce(function (total, column, i) { return total + getPaddedWidth(column, i === 0, props); }, 0);
          var remainingColumns = newColumns.slice(resizingColumnIndex);
          var remainingWidth = viewportWidth - fixedWidth;
          return fixedColumns.concat(this._getJustifiedColumns(remainingColumns, remainingWidth, props, resizingColumnIndex));
      };
      /** Builds a set of columns to fix within the viewport width. */
      DetailsListBase.prototype._getJustifiedColumns = function (newColumns, viewportWidth, props, firstIndex) {
          var _this = this;
          var _a = props.selectionMode, selectionMode = _a === void 0 ? this._selection.mode : _a, checkboxVisibility = props.checkboxVisibility;
          var rowCheckWidth = selectionMode !== SelectionMode.none && checkboxVisibility !== CheckboxVisibility.hidden ? CHECKBOX_WIDTH : 0;
          var groupExpandWidth = this._getGroupNestingDepth() * GROUP_EXPAND_WIDTH;
          var totalWidth = 0; // offset because we have one less inner padding.
          var availableWidth = viewportWidth - (rowCheckWidth + groupExpandWidth);
          var adjustedColumns = newColumns.map(function (column, i) {
              var newColumn = tslib_1.__assign({}, column, { calculatedWidth: column.minWidth || MIN_COLUMN_WIDTH }, _this._columnOverrides[column.key]);
              var isFirst = i + firstIndex === 0;
              totalWidth += getPaddedWidth(newColumn, isFirst, props);
              return newColumn;
          });
          var lastIndex = adjustedColumns.length - 1;
          // Shrink or remove collapsable columns.
          while (lastIndex > 0 && totalWidth > availableWidth) {
              var column = adjustedColumns[lastIndex];
              var minWidth = column.minWidth || MIN_COLUMN_WIDTH;
              var overflowWidth = totalWidth - availableWidth;
              if (column.calculatedWidth - minWidth >= overflowWidth || !column.isCollapsable) {
                  column.calculatedWidth = Math.max(column.calculatedWidth - overflowWidth, minWidth);
                  totalWidth = availableWidth;
              }
              else {
                  totalWidth -= getPaddedWidth(column, false, props);
                  adjustedColumns.splice(lastIndex, 1);
              }
              lastIndex--;
          }
          // Then expand columns starting at the beginning, until we've filled the width.
          for (var i = 0; i < adjustedColumns.length && totalWidth < availableWidth; i++) {
              var column = adjustedColumns[i];
              var isLast = i === adjustedColumns.length - 1;
              var overrides = this._columnOverrides[column.key];
              if (overrides && overrides.calculatedWidth && !isLast) {
                  continue;
              }
              var spaceLeft = availableWidth - totalWidth;
              var increment = void 0;
              if (isLast) {
                  increment = spaceLeft;
              }
              else {
                  var maxWidth = column.maxWidth;
                  var minWidth = column.minWidth || maxWidth || MIN_COLUMN_WIDTH;
                  increment = maxWidth ? Math.min(spaceLeft, maxWidth - minWidth) : spaceLeft;
              }
              column.calculatedWidth = column.calculatedWidth + increment;
              totalWidth += increment;
          }
          return adjustedColumns;
      };
      DetailsListBase.prototype._onColumnResized = function (resizingColumn, newWidth, resizingColumnIndex) {
          var newCalculatedWidth = Math.max(resizingColumn.minWidth || MIN_COLUMN_WIDTH, newWidth);
          if (this.props.onColumnResize) {
              this.props.onColumnResize(resizingColumn, newCalculatedWidth, resizingColumnIndex);
          }
          this._rememberCalculatedWidth(resizingColumn, newCalculatedWidth);
          this._adjustColumns(this.props, true, resizingColumnIndex);
          this._forceListUpdates();
      };
      DetailsListBase.prototype._rememberCalculatedWidth = function (column, newCalculatedWidth) {
          var overrides = this._getColumnOverride(column.key);
          overrides.calculatedWidth = newCalculatedWidth;
          overrides.currentWidth = newCalculatedWidth;
      };
      DetailsListBase.prototype._getColumnOverride = function (key) {
          return (this._columnOverrides[key] = this._columnOverrides[key] || {});
      };
      /**
       * Callback function when double clicked on the details header column resizer
       * which will measure the column cells of all the active rows and resize the
       * column to the max cell width.
       *
       * @private
       * @param {IColumn} column (double clicked column definition)
       * @param {number} columnIndex (double clicked column index)
       * @todo min width 100 should be changed to const value and should be consistent with the
       * value used on _onSizerMove method in DetailsHeader
       */
      DetailsListBase.prototype._onColumnAutoResized = function (column, columnIndex) {
          var _this = this;
          var max = 0;
          var count = 0;
          var totalCount = Object.keys(this._activeRows).length;
          for (var key in this._activeRows) {
              if (this._activeRows.hasOwnProperty(key)) {
                  var currentRow = this._activeRows[key];
                  currentRow.measureCell(columnIndex, function (width) {
                      max = Math.max(max, width);
                      count++;
                      if (count === totalCount) {
                          _this._onColumnResized(column, max, columnIndex);
                      }
                  });
              }
          }
      };
      /**
       * Call back function when an element in FocusZone becomes active. It will translate it into item
       * and call onActiveItemChanged callback if specified.
       *
       * @private
       * @param {el} row element that became active in Focus Zone
       * @param {ev} focus event from Focus Zone
       */
      DetailsListBase.prototype._onActiveRowChanged = function (el, ev) {
          var _a = this.props, items = _a.items, onActiveItemChanged = _a.onActiveItemChanged;
          if (!el) {
              return;
          }
          // Check and assign index only if the event was raised from any DetailsRow element
          if (el.getAttribute('data-item-index')) {
              var index = Number(el.getAttribute('data-item-index'));
              if (index >= 0) {
                  if (onActiveItemChanged) {
                      onActiveItemChanged(items[index], index, ev);
                  }
                  this.setState({
                      focusedItemIndex: index
                  });
              }
          }
      };
      DetailsListBase.prototype._onBlur = function (event) {
          this.setState({
              focusedItemIndex: -1
          });
      };
      DetailsListBase.prototype._getItemKey = function (item, itemIndex) {
          var getKey = this.props.getKey;
          var itemKey = undefined;
          if (item) {
              itemKey = item.key;
          }
          if (getKey) {
              itemKey = getKey(item, itemIndex);
          }
          if (!itemKey) {
              itemKey = itemIndex;
          }
          return itemKey;
      };
      DetailsListBase.prototype._getDetailsFooterProps = function () {
          var columns = this.state.adjustedColumns;
          var _a = this.props, viewport = _a.viewport, checkboxVisibility = _a.checkboxVisibility, indentWidth = _a.indentWidth, _b = _a.cellStyleProps, cellStyleProps = _b === void 0 ? DEFAULT_CELL_STYLE_PROPS : _b, _c = _a.selectionMode, selectionMode = _c === void 0 ? this._selection.mode : _c;
          return {
              columns: columns,
              groupNestingDepth: this._getGroupNestingDepth(),
              selection: this._selection,
              selectionMode: selectionMode,
              viewport: viewport,
              checkboxVisibility: checkboxVisibility,
              indentWidth: indentWidth,
              cellStyleProps: cellStyleProps
          };
      };
      DetailsListBase.prototype._getColumnReorderProps = function () {
          var columnReorderOptions = this.props.columnReorderOptions;
          if (columnReorderOptions) {
              return tslib_1.__assign({}, columnReorderOptions, { onColumnDragEnd: this._onColumnDragEnd });
          }
      };
      DetailsListBase.prototype._getGroupProps = function (detailsGroupProps) {
          var _this = this;
          var onRenderDetailsGroupFooter = detailsGroupProps.onRenderFooter, onRenderDetailsGroupHeader = detailsGroupProps.onRenderHeader;
          var columns = this.state.adjustedColumns;
          var _a = this.props, _b = _a.selectionMode, selectionMode = _b === void 0 ? this._selection.mode : _b, viewport = _a.viewport, _c = _a.cellStyleProps, cellStyleProps = _c === void 0 ? DEFAULT_CELL_STYLE_PROPS : _c, checkboxVisibility = _a.checkboxVisibility, indentWidth = _a.indentWidth;
          var groupNestingDepth = this._getGroupNestingDepth();
          var onRenderFooter = onRenderDetailsGroupFooter
              ? function (props, defaultRender) {
                  return onRenderDetailsGroupFooter(tslib_1.__assign({}, props, { columns: columns, groupNestingDepth: groupNestingDepth, indentWidth: indentWidth, selection: _this._selection, selectionMode: selectionMode, viewport: viewport, checkboxVisibility: checkboxVisibility,
                      cellStyleProps: cellStyleProps }), defaultRender);
              }
              : undefined;
          var onRenderHeader = onRenderDetailsGroupHeader
              ? function (props, defaultRender) {
                  return onRenderDetailsGroupHeader(tslib_1.__assign({}, props, { columns: columns, groupNestingDepth: groupNestingDepth, indentWidth: indentWidth, selection: _this._selection, selectionMode: selectionMode, viewport: viewport, checkboxVisibility: checkboxVisibility,
                      cellStyleProps: cellStyleProps }), defaultRender);
              }
              : undefined;
          var groupProps = detailsGroupProps;
          return tslib_1.__assign({}, groupProps, { onRenderFooter: onRenderFooter,
              onRenderHeader: onRenderHeader });
      };
      DetailsListBase.defaultProps = {
          layoutMode: DetailsListLayoutMode.justified,
          selectionMode: SelectionMode.multiple,
          constrainMode: ConstrainMode.horizontalConstrained,
          checkboxVisibility: CheckboxVisibility.onHover,
          isHeaderVisible: true,
          enableShimmer: false
      };
      DetailsListBase = tslib_1.__decorate([
          withViewport
      ], DetailsListBase);
      return DetailsListBase;
  }(BaseComponent));
  export { DetailsListBase };
  export function buildColumns(items, canResizeColumns, onColumnClick, sortedColumnKey, isSortedDescending, groupedColumnKey, isMultiline) {
      var columns = [];
      if (items && items.length) {
          var firstItem = items[0];
          for (var propName in firstItem) {
              if (firstItem.hasOwnProperty(propName)) {
                  columns.push({
                      key: propName,
                      name: propName,
                      fieldName: propName,
                      minWidth: MIN_COLUMN_WIDTH,
                      maxWidth: 300,
                      isCollapsable: !!columns.length,
                      isMultiline: isMultiline === undefined ? false : isMultiline,
                      isSorted: sortedColumnKey === propName,
                      isSortedDescending: !!isSortedDescending,
                      isRowHeader: false,
                      columnActionsMode: ColumnActionsMode.clickable,
                      isResizable: canResizeColumns,
                      onColumnClick: onColumnClick,
                      isGrouped: groupedColumnKey === propName
                  });
              }
          }
      }
      return columns;
  }
  function isRightArrow(event) {
      return event.which === getRTLSafeKeyCode(39 /* right */);
  }
  function getPaddedWidth(column, isFirst, props) {
      var _a = props.cellStyleProps, cellStyleProps = _a === void 0 ? DEFAULT_CELL_STYLE_PROPS : _a;
      return (column.calculatedWidth +
          cellStyleProps.cellLeftPadding +
          cellStyleProps.cellRightPadding +
          (column.isPadded ? cellStyleProps.cellExtraRightPadding : 0));
  }
  //# sourceMappingURL=DetailsList.base.js.map