UNPKG

@wix/design-system

Version:

@wix/design-system

170 lines 8.98 kB
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