@wix/design-system
Version:
@wix/design-system
170 lines • 8.98 kB
JavaScript
import React from 'react';
import defaultTo from 'lodash/defaultTo';
import classNames from 'classnames';
import { ScrollSync } from 'react-scroll-sync';
import { classes } from './Table.st.css.js';
import DataTable from './DataTable';
import * as dataTableRowStyle from './DataTable/components/DataTableRow.st.css.js';
import Checkbox from '../Checkbox';
import { TableContext } from './TableContext';
import { BulkSelection } from './BulkSelection';
import { ColumnResize } from './ColumnResize';
import * as dataTableRowVirtualStyle from './DataTable/components/DataTableRowVirtual.st.css.js';
import { TableBulkSelectionCheckbox, TableContent, TableEmptyState, TableSubToolbar, TableTitleBar, TableToolbarContainer, } from './components';
import { RowNumberCell } from './components/RowNumberCell';
import { FloatingScrollBarContextProvider } from './FloatingScrollBar/FloatingScrollBarContext';
const hasUnselectablesSymbol = Symbol('hasUnselectables');
export function createColumns({ tableProps, bulkSelectionContext }) {
const { dragAndDrop, isDragAndDropDisabled } = tableProps;
const includeDragHandleColumn = dragAndDrop != null &&
dragAndDrop.createDragHandleColumn != null &&
!isDragAndDropDisabled;
const createCheckboxColumn = ({ toggleSelectionById, isSelected, selectionDisabled, }) => {
const isRowSelectionDisabled = rowData => selectionDisabled === true ||
(typeof selectionDisabled === 'function' && selectionDisabled(rowData));
return {
key: 'bulk-selection-cell',
title: tableProps.hideBulkSelectionCheckbox ? ('') : (React.createElement(TableBulkSelectionCheckbox, { dataHook: "table-select", ref: tableProps.bulkSelectionCheckboxRef })),
dataHook: 'bulk-selection-cell',
onCellClick: (column, row, rowNum, event) => {
if (row.unselectable) {
return;
}
event.stopPropagation();
if (isRowSelectionDisabled(row)) {
return;
}
const id = defaultTo(row.id, rowNum);
toggleSelectionById(id, 'Checkbox');
},
render: (row, rowNum) => {
const id = defaultTo(row.id, rowNum);
const tooltipContent = row.checkboxTooltipContent;
const checked = !row.unselectable && isSelected(id);
const disabled = row.unselectable || isRowSelectionDisabled(row);
if (tableProps.showRowNumbers) {
return (React.createElement(RowNumberCell, { rowNum: rowNum, checked: checked, disabled: disabled, tooltipContent: tooltipContent, dataHook: "row-select" }));
}
return row.unselectable ? null : (React.createElement(Checkbox, { disabled: isRowSelectionDisabled(row), dataHook: "row-select", checked: isSelected(id), tooltipProps: { disabled: !tooltipContent }, tooltipContent: tooltipContent }));
},
width: '12px',
style: (_, row) => (row.unselectable ? undefined : { cursor: 'pointer' }),
};
};
const checkboxColumn = tableProps.showSelection
? createCheckboxColumn(bulkSelectionContext)
: null;
const columns = [
...(includeDragHandleColumn
? [dragAndDrop.createDragHandleColumn(tableProps)]
: []),
...(checkboxColumn ? [checkboxColumn] : []),
...tableProps.columns,
];
// Apply different column width when checkbox column is the last sticky column
// (looks weird otherwise when stickied with default 12px width).
if (checkboxColumn &&
!tableProps.showRowNumbers &&
columns.indexOf(checkboxColumn) + 1 === tableProps.stickyColumns) {
checkboxColumn.width = '34px';
}
return columns;
}
export function getDataTableProps(tableProps) {
const { showSelection, onSelectionChanged, onSelectionStarted, dataHook, ...props } = tableProps;
return {
...props,
rowClass: classNames(tableProps.rowClass, classes.tableRow),
};
}
/**
* Table is a composite component that allows adding SelectionColumn, Toolbar (on top of the TitleBar).
* It is a context provider, and thus the Table.Consumer, Table.TitleBar and Table.Content can be rendered separately.
*/
export class Table extends React.Component {
constructor() {
super(...arguments);
this.state = {
leftShadowVisible: false,
rightShadowVisible: false,
};
this.tableRef = React.createRef();
this.scrollElementRef = React.createRef();
this._handleUpdateScrollShadows = (leftShadowVisible, rightShadowVisible) => {
if (leftShadowVisible !== this.state.leftShadowVisible) {
this.setState({ leftShadowVisible });
}
if (rightShadowVisible !== this.state.rightShadowVisible) {
this.setState({ rightShadowVisible });
}
};
}
shouldComponentUpdate() {
// Table is not really a PureComponent
return true;
}
setSelectedIds(selectedIds) {
this.bulkSelection.setSelectedIds(selectedIds);
}
renderChildren() {
const { children, withWrapper, dataHook } = this.props;
return withWrapper ? React.createElement("div", { "data-hook": dataHook }, children) : children;
}
render() {
const { data, selectedIds, showSelection, deselectRowsByDefault, infiniteScroll, totalSelectableCount, onSelectionChanged, onSelectionStarted, hasMore, horizontalScroll, resizable, resizeProps, selectionDisabled, dragAndDrop, onDragEnd, scrollElement, } = this.props;
this.scrollElementRef.current =
typeof HTMLElement !== 'undefined' && scrollElement instanceof HTMLElement
? scrollElement
: scrollElement?.current;
let hasUnselectables = null;
let allIds = data.map((rowData, rowIndex) => rowData.unselectable ||
(typeof selectionDisabled === 'function' && selectionDisabled(rowData))
? (hasUnselectables = hasUnselectablesSymbol)
: defaultTo(rowData.id, rowIndex));
if (hasUnselectables === hasUnselectablesSymbol) {
allIds = allIds.filter(rowId => rowId !== hasUnselectablesSymbol);
}
const { leftShadowVisible, rightShadowVisible } = this.state;
const isTableResizable = resizable === true && horizontalScroll === true;
const contextValue = {
...this.props,
leftShadowVisible,
rightShadowVisible,
onUpdateScrollShadows: this._handleUpdateScrollShadows,
tableRef: this.tableRef,
};
let table = this.renderChildren();
table = horizontalScroll ? (React.createElement(FloatingScrollBarContextProvider, { scrollableContentRef: this.tableRef, viewportRef: this.props.viewportRef, scrollElementRef: this.scrollElementRef }, table)) : (table);
table = (React.createElement(TableContext.Provider, { value: contextValue },
React.createElement(ColumnResize, { columns: this.props.columns, onColumnResize: resizeProps?.onColumnResize, onColumnResizeStart: resizeProps?.onColumnResizeStart, onColumnResizeEnd: resizeProps?.onColumnResizeEnd, isTableResizable: isTableResizable, minColumnWidth: resizeProps?.minColumnWidth, maxColumnWidth: resizeProps?.maxColumnWidth }, showSelection ? (React.createElement(BulkSelection, { ref: _ref => {
this.bulkSelection = _ref;
}, selectedIds: selectedIds, deselectRowsByDefault: deselectRowsByDefault, selectionDisabled: selectionDisabled, hasMoreInBulkSelection: infiniteScroll && Boolean(totalSelectableCount) && hasMore, totalCount: totalSelectableCount, allIds: allIds, onSelectionChanged: onSelectionChanged, onSelectionStarted: onSelectionStarted }, table)) : (table))));
table = horizontalScroll ? (React.createElement(ScrollSync, { proportional: false, horizontal: true, vertical: false }, table)) : (table);
return table;
}
}
Table.ToolbarContainer = TableToolbarContainer;
Table.Titlebar = TableTitleBar;
Table.Content = TableContent;
Table.SubToolbar = TableSubToolbar;
Table.EmptyState = TableEmptyState;
Table.BulkSelectionCheckbox = TableBulkSelectionCheckbox;
Table.displayName = 'Table';
Table.dataTableRowVirtualStyle = dataTableRowVirtualStyle;
Table.dataTableRowStyle = dataTableRowStyle;
Table.defaultProps = {
...DataTable.defaultProps,
showSelection: false,
showRowNumbers: false,
hideBulkSelectionCheckbox: false,
children: [React.createElement(Table.Content, { key: "content" })],
withWrapper: true,
showLastRowDivider: false,
horizontalScroll: false,
stickyColumns: 0,
isRowDisabled: () => false,
deselectRowsByDefault: false,
resizable: false,
};
// export default Table;
//# sourceMappingURL=Table.js.map