react-cm-ui
Version:
React UI for Healthy Church
197 lines (182 loc) • 5.14 kB
JSX
import ClassNames from 'classnames';
import PropTypes from 'prop-types';
import React, { useEffect } from 'react';
import {
BEM_DATA_GRID,
UI_CLASS_NAME,
} from '../../global/constants';
import { SORTABLE_PROP_TYPES } from './dataGridConstants';
import DataGridTable from './dataGridTable';
import makeStyles from '../../styles/makeStyles';
const propTypes = {
bleed: PropTypes.bool,
classes: PropTypes.shape({
bleed: PropTypes.string,
root: PropTypes.string,
}),
className: PropTypes.string,
columns: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
data: PropTypes.arrayOf(
PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.shape({})),
PropTypes.shape({}),
]),
).isRequired,
/**
* Used for DOM testing. https://testing-library.com/docs/queries/bytestid/
*/
dataTestId: PropTypes.string,
fontSize: PropTypes.string,
id: PropTypes.string.isRequired,
minWidth: PropTypes.number,
moduleType: PropTypes.oneOf(['drawer', 'page']),
resizableColumnWidthPercentage: PropTypes.number,
rowProps: PropTypes.func,
size: PropTypes.oneOf([
'small',
'medium',
]),
sortable: PropTypes.arrayOf(SORTABLE_PROP_TYPES),
small: PropTypes.bool,
stickyColumnWidth: PropTypes.number,
stickyColumns: PropTypes.number,
stretch: PropTypes.oneOfType([
PropTypes.oneOf(['very']),
PropTypes.bool,
]),
style: PropTypes.shape({}),
};
const defaultProps = {
bleed: true,
classes: null,
className: undefined,
dataTestId: `${UI_CLASS_NAME}-${BEM_DATA_GRID}`,
fontSize: undefined,
minWidth: 800,
moduleType: null,
resizableColumnWidthPercentage: undefined,
rowProps: () => ({
className: null,
id: null,
onClick: null,
selected: null,
style: null,
}),
size: 'small',
small: false,
sortable: null,
stickyColumns: 0,
stickyColumnWidth: 30,
stretch: false,
style: {},
};
const useStyles = makeStyles((theme) => ({
bleed: {
margin: [[0, -theme.gutters.page.sm]],
[theme.breakpoints.up(496)]: {
margin: [[0, -theme.gutters.page[496]]],
},
},
drawer: {},
root: {
'&$drawer': {
marginTop: -33,
'&$bleed': {
margin: [[0, -22]],
[theme.breakpoints.up(496)]: {
margin: [[0, -22]],
},
},
'& .table-header-cell': {
paddingTop: [[11, '!important']],
},
},
'& .ui.table .table-cell:last-child': {
paddingRight: [[11, '!important']],
},
'& .ui.table .table-header-cell:last-child': {
paddingRight: [[11, '!important']],
position: 'relative',
},
[`& .${BEM_DATA_GRID}--table_body-drop_shadow`]: {
boxShadow: [[0, 4, 5, 0, 'rgba(0, 0, 0, .5)']],
},
},
stickyColumns: {
position: 'relative',
},
}));
function DataGrid(props) {
const {
bleed,
className,
columns,
data,
dataTestId,
fontSize,
id,
minWidth: minWidthProp,
moduleType,
rowProps,
size: sizeProp,
small: smallProp,
sortable,
stickyColumns,
stickyColumnWidth,
resizableColumnWidthPercentage,
stretch,
style,
} = props;
let minWidth;
useEffect(() => {
// eslint-disable-next-line react-hooks/exhaustive-deps
minWidth = minWidthProp;
}, []);
const classes = useStyles(props);
let classNameModuleModifier;
if (moduleType) {
classNameModuleModifier = `${BEM_DATA_GRID}-${moduleType}`;
}
const size = smallProp ? 'small' : sizeProp;
const isStickyColumns = stickyColumns > 0;
const rootClasses = ClassNames(
'ui',
BEM_DATA_GRID,
classes.root,
classNameModuleModifier,
className,
{
[classes.drawer]: moduleType === 'drawer',
[classes.bleed]: bleed,
[classes.stickyColumns]: isStickyColumns,
},
);
return (
<div
className={rootClasses}
data-testid={dataTestId}
style={style}
>
<DataGridTable
bleed={bleed}
className={className}
columns={columns}
data={data}
fontSize={fontSize}
id={id}
minWidth={minWidth}
moduleType={moduleType}
rowProps={rowProps}
size={size}
sortable={sortable}
stickyColumnWidth={stickyColumnWidth}
stickyColumns={stickyColumns}
resizableColumnWidthPercentage={resizableColumnWidthPercentage}
stretch={stretch}
/>
</div>
);
}
DataGrid.propTypes = propTypes;
DataGrid.defaultProps = defaultProps;
export default DataGrid;