/**
* @flow
* @file Item list component
* @author Box
*/
import * as React from 'react';
import classNames from 'classnames';
import { Table, Column } from '@box/react-virtualized/dist/es/Table';
import AutoSizer from '@box/react-virtualized/dist/es/AutoSizer';
import KeyBinder from '../common/KeyBinder';
import nameCellRenderer from '../common/item/nameCellRenderer';
import iconCellRenderer from '../common/item/iconCellRenderer';
// $FlowFixMe TypeScript file
import { ItemOptions, type ItemAction } from '../common/item';
import { isFocusableElement, focus } from '../../utils/dom';
import shareAccessCellRenderer from './shareAccessCellRenderer';
import selectionCellRenderer from './selectionCellRenderer';
import isRowSelectable from './cellRendererHelper';
import { VIEW_SELECTED, FIELD_NAME, FIELD_ID, FIELD_SHARED_LINK, TYPE_FOLDER } from '../../constants';
import type { View, Collection, BoxItem } from '../../common/types/core';
import '@box/react-virtualized/styles.css';
import './ItemList.scss';
type Props = {
canSetShareAccess: boolean,
currentCollection: Collection,
extensionsWhitelist: string[],
focusedRow: number,
hasHitSelectionLimit: boolean,
isSingleSelect: boolean,
isSmall: boolean,
itemActions?: ItemAction[],
onFocusChange: Function,
onItemClick: Function,
onItemSelect: Function,
onShareAccessChange: Function,
rootElement?: HTMLElement,
rootId: string,
selectableType: string,
tableRef: Function,
view: View,
};
const moreOptionsCellRenderer =
props =>
({ rowData }) => (
);
const ItemList = ({
view,
rootId,
isSmall,
rootElement,
focusedRow,
selectableType,
canSetShareAccess,
hasHitSelectionLimit,
isSingleSelect,
extensionsWhitelist,
onItemSelect,
onItemClick,
onShareAccessChange,
onFocusChange,
currentCollection,
tableRef,
itemActions,
}: Props) => {
const iconCell = iconCellRenderer();
const nameCell = nameCellRenderer(rootId, view, onItemClick);
const selectionCell = selectionCellRenderer(
onItemSelect,
selectableType,
extensionsWhitelist,
hasHitSelectionLimit,
isSingleSelect,
);
const shareAccessCell = shareAccessCellRenderer(
onShareAccessChange,
canSetShareAccess,
selectableType,
extensionsWhitelist,
hasHitSelectionLimit,
);
const moreOptionsCell = moreOptionsCellRenderer({
itemActions,
});
const { id, items = [] }: Collection = currentCollection;
const rowCount: number = items.length;
const rowClassName = ({ index }) => {
if (index === -1) {
return '';
}
const { selected, type } = items[index];
const isSelectable = isRowSelectable(selectableType, extensionsWhitelist, hasHitSelectionLimit, items[index]);
return classNames(`bcp-item-row bcp-item-row-${index}`, {
'bcp-item-row-selected': selected && view !== VIEW_SELECTED,
'bcp-item-row-unselectable': type !== TYPE_FOLDER && !isSelectable, // folder row should never dim
});
};
const onRowClick = ({
event,
rowData,
index,
}: {
event: Event & { target: HTMLElement },
index: number,
rowData: BoxItem,
}) => {
// If the click is happening on a clickable element on the item row, ignore row selection
if (
isRowSelectable(selectableType, extensionsWhitelist, hasHitSelectionLimit, rowData) &&
!isFocusableElement(event.target)
) {
onItemSelect(rowData);
} else {
onFocusChange(index);
}
};
return (
focus(rootElement, `.bcp-item-row-${scrollToRow}`)}
>
{({ onSectionRendered, scrollToRow, focusOnRender }) => (
{({ width, height }) => (
items[index]}
ref={tableRef}
rowClassName={rowClassName}
onRowClick={onRowClick}
scrollToIndex={scrollToRow}
onRowsRendered={({ startIndex, stopIndex }) => {
onSectionRendered({
rowStartIndex: startIndex,
rowStopIndex: stopIndex,
});
if (focusOnRender) {
focus(rootElement, `.bcp-item-row-${scrollToRow}`);
}
}}
>
{isSmall ? null : (
)}
{!!itemActions?.length && (
)}
)}
)}
);
};
export default ItemList;