wix-style-react
Version:
wix-style-react
184 lines • 9.8 kB
JavaScript
import React from 'react';
import Toggle from '../../../Transition/Toggle';
import { timingMap } from '../../../Transition/constants';
import defaultTo from 'lodash/defaultTo';
import { classes, st } from '../DataTable.st.css';
import classNames from 'classnames';
import { getStickyColumnStyle } from '../DataTable.utils';
import PropTypes from 'prop-types';
const DataTableRow = props => {
const getCellClasses = ({ column, colNum }) => {
const { rowData, stickyColumns, rowDetails, showDetails } = props;
return classNames({
[classes.important]: column.important,
[classes.alignStart]: column.align === 'start',
[classes.alignCenter]: column.align === 'center',
[classes.alignEnd]: column.align === 'end',
[classes.sticky]: colNum < stickyColumns,
[classes.lastSticky]: colNum === stickyColumns - 1,
[classes.stickyActionCell]: column.stickyActionCell,
[classes.hasRowDetails]: rowDetails,
[classes.rowDetailsExtended]: showDetails && rowDetails(rowData),
});
};
const renderCell = ({ column, colNum }) => {
const { rowData, rowNum, maskingClassNames, isDragOverlay, virtualized, stickyColumns, columns, hideHeader, hideHeaderAccessible, isApplyColumnWidthStyle, } = props;
const width = isDragOverlay ||
((virtualized || rowNum === 0) && (hideHeader || hideHeaderAccessible))
? column.width
: undefined;
const widthStyle = isApplyColumnWidthStyle
? column.width
? { width: column.width }
: { flex: 1 }
: {};
const style = typeof column.style === 'function'
? column.style(column, rowData, rowNum)
: column.style;
const stickyColumnStyle = colNum < stickyColumns
? getStickyColumnStyle(columns, column)
: undefined;
const cellClasses = getCellClasses({
column,
colNum,
});
return (React.createElement("td", { key: column.key ?? colNum, "data-mask": !!maskingClassNames, "data-hook": column.dataHook, style: {
...style,
...stickyColumnStyle,
...widthStyle,
}, width: width, className: st(cellClasses, {}, maskingClassNames), onClick: column.onCellClick
? event => column.onCellClick(column, rowData, rowNum, event)
: undefined }, column.render && column.render(rowData, rowNum)));
};
const onClickRow = () => {
const { toggleRowDetails, rowData, rowNum, onRowClick, rowDetails, isRowDisabled, } = props;
onRowClick && !isRowDisabled(rowData) && onRowClick(rowData, rowNum);
rowDetails && rowDetails(rowData, rowNum) && toggleRowDetails(rowData);
};
const renderRow = () => {
const { rowData, rowNum, style, className, isDragOverlay, onRowClick, onMouseEnterRow, onMouseLeaveRow, rowDataHook, dynamicRowClass, isRowHighlight, rowDetails, rowClass, columns, selectedRowsIds, isRowSelected, isRowDisabled, dragAndDrop, isDragAndDropDisabled, showDetails, virtualized, TrElementType = 'tr', rowProps = {}, } = props;
const rowClasses = [rowClass, className];
const key = defaultTo(rowData.id, rowNum);
const optionalRowProps = { ...rowProps };
const isRowHighlighted = isRowHighlight && isRowHighlight(rowData, rowNum);
const handlers = [
{ rowEventHandler: onClickRow, eventHandler: 'onClick' },
{ rowEventHandler: onMouseEnterRow, eventHandler: 'onMouseEnter' },
{ rowEventHandler: onMouseLeaveRow, eventHandler: 'onMouseLeave' },
];
handlers.forEach(({ rowEventHandler, eventHandler }) => {
if (rowEventHandler) {
optionalRowProps[eventHandler] = event => {
if (event.isDefaultPrevented()) {
return;
}
rowEventHandler(rowData, rowNum);
};
}
});
if (onRowClick && !isRowDisabled(rowData)) {
rowClasses.push(classes.clickableDataRow);
}
if (rowDetails) {
rowClasses.push(classes.animatedDataRow);
}
if (rowDataHook) {
if (typeof rowDataHook === 'string') {
optionalRowProps['data-hook'] = rowDataHook;
}
else {
optionalRowProps['data-hook'] = rowDataHook(rowData, rowNum);
}
}
if (typeof TrElementType !== 'string') {
optionalRowProps.rowData = rowData;
}
if (dynamicRowClass) {
rowClasses.push(dynamicRowClass(rowData, rowNum));
}
if (isRowHighlighted) {
rowClasses.push(classes.highlight);
}
if (isRowSelected
? isRowSelected(rowData, rowNum)
: selectedRowsIds && selectedRowsIds.includes(key)) {
rowClasses.push(classes.selected);
}
optionalRowProps.className = classNames(rowClasses);
let tr = (React.createElement(TrElementType, { "data-table-row": "dataTableRow", "data-key": key, "data-index": `index-${rowNum}`, style: style, key: key, "data-highlighted": isRowHighlighted ? true : null, ...optionalRowProps, "data-animated": !!rowDetails ? true : null, "data-clickable": onRowClick && !isRowDisabled(rowData) ? true : null }, columns.map((column, colNum) => renderCell({
column,
colNum,
}))));
if (dragAndDrop) {
const { DraggableTableRow } = dragAndDrop;
tr = (React.createElement(DraggableTableRow, { id: rowData.id, key: tr.key, index: rowNum, isDragOverlay: isDragOverlay, isDragAndDropDisabled: isDragAndDropDisabled, forwardedRef: rowProps.ref }, tr));
}
const rowsToRender = [tr];
if (rowDetails) {
rowsToRender.push(React.createElement("tr", { key: `${key}_details`, className: classes.rowDetails },
React.createElement("td", { "data-hook": `${rowNum}_details`, className: classNames(classes.details, showDetails ? classes.active : ''), colSpan: columns.length },
React.createElement(Toggle, { timeout: timingMap['medium01'], show: showDetails, unmountOnExit: true }, rowDetails(rowData, rowNum)))));
}
return virtualized ? rowsToRender[0] : rowsToRender;
};
return React.createElement(React.Fragment, null, renderRow());
};
DataTableRow.propTypes = {
/** Row properties */
/** Element from the data array */
rowData: PropTypes.any,
/** Row index */
rowNum: PropTypes.number,
/** Styles to be applied to the row */
style: PropTypes.object,
/** Class to be applied to the row */
className: PropTypes.string,
maskingClassNames: PropTypes.any,
isDragOverlay: PropTypes.bool,
toggleRowDetails: PropTypes.func,
showDetails: PropTypes.bool,
rowProps: PropTypes.object,
/* DataTable properties */
/** A callback method to be called on row click. Signature: `onRowClick(rowData, rowNum)` */
onRowClick: PropTypes.func,
/** A callback method to be called on row mouse enter. Signature: `onMouseEnterRow(rowData, rowNum)` */
onMouseEnterRow: PropTypes.func,
/** A callback method to be called on row mouse leave. Signature: `onMouseLeaveRow(rowData, rowNum)` */
onMouseLeaveRow: PropTypes.func,
/** A string data-hook to apply to all table body rows. or a func which calculates the data-hook for each row - Signature: `(rowData, rowNum) => string` */
rowDataHook: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
/** A func that gets row data and returns a class(es) to apply to that specific row */
dynamicRowClass: PropTypes.func,
/** A func that gets row data and returns boolean if row is highlighted or not */
isRowHighlight: PropTypes.func,
/** Function that returns React component that will be rendered in row details section. Example: `rowDetails={(row, rowNum) => <MyRowDetailsComponent {...row} />}` */
rowDetails: PropTypes.func,
/** A class to apply to all table body rows */
rowClass: PropTypes.string,
/** A class to apply to the header table row */
headerRowClass: PropTypes.string,
/** A class to apply to the table header */
headerClass: PropTypes.string,
/** Configuration of the table's columns. See table below */
columns: PropTypes.array,
/** array of selected ids in the table. Note that `isRowSelected` prop provides greater selection logic flexibility and is recommended to use instead. */
selectedRowsIds: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])),
/** A func that gets row data and returns boolean if row is selected or not */
isRowSelected: PropTypes.func,
/** a function which will be called for every row in `data` to specify if it should appear as disabled. Example: `isRowDisabled={(rowData) => !rowData.isEnabled}` */
isRowDisabled: PropTypes.func,
dragAndDrop: PropTypes.object,
isDragAndDropDisabled: PropTypes.bool,
/** ++EXPERIMENTAL++ virtualize the table scrolling for long list items */
virtualized: PropTypes.bool,
stickyColumns: PropTypes.number,
/** Should we remove the header of the table from DOM. */
hideHeader: PropTypes.bool,
/** Should we hide the header of the table with display: none. */
hideHeaderAccessible: PropTypes.bool,
/** A flag specifying weather to apply column width style to table cells */
isApplyColumnWidthStyle: PropTypes.bool,
};
DataTableRow.displayName = 'Table.DataTableRow';
export default DataTableRow;
//# sourceMappingURL=DataTableRow.js.map