function selectionProjectionHandler()

in js/vnext/projection/selection.js [50:145]


function selectionProjectionHandler(state, {
  enabled,
  resolver,
  a11y: {
    selectAllLabel = 'Select All',
    deselectAllLabel = 'Deselect All',
    selectOneLabel = null,
    deselectOneLabel = null,
  } = {},
}) {
  if (!enabled) {
    return state;
  }

  const {
    selected,
    single,
    colClasses,
    headClasses,
    bodyClasses,
    footClasses,
    selectable,
  } = resolver.updateItems(state.items);

  const selectedIndex = _.reduce(selected, (memo, key) => {
    memo[key] = true;
    return memo;
  }, {});
  const primaryKey = state.primaryKey;
  let selectedAll = false;
  let partSelected = false;

  /**
   * Callback to decide whether a row is selectable.
   * @callback SelectableCallback
   * @param {Object} item
   *    The data item of the row.
   * @return {boolean}
   */
  if (!single) {
    const selectableCount = _.filter(state.items.slice(), selectable).length;
    const selectedCount = _.filter(selected, key => selectable(this.itemWithKey(key))).length;

    selectedAll = selectableCount !== 0 && selectedCount === selectableCount;
    partSelected = selectedCount > 0 && selectedCount < selectableCount;
  }

  const columns = [extendDataColumnAttr({
    group: _.chain(state.columns).first().result('group', 'other').value(),
    name: 'selection',
    html: selectionHeadTemplate({
      single,
      checked: selectedAll,
      partSelected,
      checkAllLabel: selectedAll ? deselectAllLabel : selectAllLabel,
    }),
    template: selectionBodyTemplate,
    property: item => {
      return {
        single,
        selectable: selectable(item),
        checked: selectedIndex[item[primaryKey]],
        ariaLabel: selectedIndex[item[primaryKey]] ? deselectOneLabel : selectOneLabel,
        labelbyId: selectOneLabel ? undefined : item[primaryKey],
      };
    },
    sortable: false,
    isResizable: false,
    colClasses,
    headClasses,
    bodyClasses,
    footClasses,
  })].concat(state.columns);

  const bodyRows = _.map(state.bodyRows, row => {
    if (row && row.type === 'data' && row.item && selectable(row.item)) {
      let selectedClassArray = selectedIndex[row.item[primaryKey]] ? ['row-selected'] : [];

      return _.defaults({
        attributes: {
          id: row.item[primaryKey],
        },
        classes: _.union(selectedClassArray, row.classes),
      }, _.isObject(row) ? row : {});
    }

    return row;
  });

  const events = _.defaults({
    'change input.select-all': changeSelectAll,
    'change input.select-row': changeSelectRow,
  }, state.events);

  return _.defaults({ columns, events, bodyRows }, state);
}