Skip to content

Commit

Permalink
feat(react-grid): Material UI detail row (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
SergeyAlexeev committed Jun 5, 2017
1 parent 81353bc commit c161c66
Show file tree
Hide file tree
Showing 19 changed files with 294 additions and 40 deletions.
Expand Up @@ -17,4 +17,4 @@ export const expandedDetailRows = (sourceRows, expandedRows, getRowId, rowHeight
return rows;
};

export const tableColumnsWithDetail = columns => [{ type: 'detail', width: 25 }, ...columns];
export const tableColumnsWithDetail = (columns, detailToggleCellWidth) => [{ type: 'detail', width: detailToggleCellWidth }, ...columns];
Expand Up @@ -56,10 +56,10 @@ describe('DetailRow computeds', () => {
];

test('should work', () => {
const columns = tableColumnsWithDetail(tableColumns);
const columns = tableColumnsWithDetail(tableColumns, 50);

expect(columns).toHaveLength(3);
expect(columns[0]).toMatchObject({ type: 'detail', width: 25 });
expect(columns[0]).toMatchObject({ type: 'detail', width: 50 });
expect(columns[1]).toBe(tableColumns[0]);
expect(columns[2]).toBe(tableColumns[1]);
});
Expand Down
29 changes: 29 additions & 0 deletions packages/dx-react-demos/src/material-ui/detail-row.jsx
@@ -0,0 +1,29 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Route } from 'react-router-dom';

import { SimpleDetailRowDemo } from './detail-row/simple-detail-row';
import { DetailRowControlledDemo } from './detail-row/detail-row-controlled';

const AllDemos = () => (
<div>
<h2>Detail Row Demos</h2>
<h3>Simple Uncontrolled Detail Row</h3>
<SimpleDetailRowDemo />
<h3>Expanded State Controlled Mode</h3>
<DetailRowControlledDemo />
</div>
);

export const DetailRowDemos = ({ match }) => (
<div>
<Route exact path={`${match.url}/`} component={AllDemos} />
<Route path={`${match.url}/simple-detail-row`} component={SimpleDetailRowDemo} />
<Route path={`${match.url}/detail-row-controlled`} component={DetailRowControlledDemo} />
</div>
);
DetailRowDemos.propTypes = {
match: PropTypes.shape({
url: PropTypes.string,
}).isRequired,
};
@@ -0,0 +1,54 @@
import React from 'react';
import {
RowDetailState,
} from '@devexpress/dx-react-grid';
import {
Grid,
TableView,
TableHeaderRow,
TableRowDetail,
} from '@devexpress/dx-react-grid-material-ui';

import {
generateRows,
} from '../../demoData';

export class DetailRowControlledDemo extends React.PureComponent {
constructor(props) {
super(props);

this.state = {
columns: [
{ name: 'name', title: 'Name' },
{ name: 'sex', title: 'Sex' },
{ name: 'city', title: 'City' },
{ name: 'car', title: 'Car' },
],
rows: generateRows({ length: 7 }),
expandedRows: [2, 5],
};

this.changeExpandedDetails = expandedRows => this.setState({ expandedRows });
this.rowTemplate = ({ row }) => <div>Details for {row.name} from {row.city}</div>;
}
render() {
const { rows, columns, expandedRows } = this.state;

return (
<Grid
rows={rows}
columns={columns}
>
<RowDetailState
expandedRows={expandedRows}
onExpandedRowsChange={this.changeExpandedDetails}
/>
<TableView />
<TableHeaderRow />
<TableRowDetail
template={this.rowTemplate}
/>
</Grid>
);
}
}
@@ -0,0 +1,16 @@
import React from 'react';
import { mount } from 'enzyme';
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
import { DetailRowControlledDemo } from './detail-row-controlled';

describe('MUI: detail row controlled demo', () => {
test('should work', () => {
mount(
<MuiThemeProvider theme={createMuiTheme()}>
<DetailRowControlledDemo />
</MuiThemeProvider>,
);

expect(true).toBeTruthy();
});
});
@@ -0,0 +1,52 @@
import React from 'react';
import {
RowDetailState,
} from '@devexpress/dx-react-grid';
import {
Grid,
TableView,
TableHeaderRow,
TableRowDetail,
} from '@devexpress/dx-react-grid-material-ui';

import {
generateRows,
} from '../../demoData';

export class SimpleDetailRowDemo extends React.PureComponent {
constructor(props) {
super(props);

this.state = {
columns: [
{ name: 'name', title: 'Name' },
{ name: 'sex', title: 'Sex' },
{ name: 'city', title: 'City' },
{ name: 'car', title: 'Car' },
],
rows: generateRows({ length: 7 }),
};

this.changeExpandedDetails = expandedRows => this.setState({ expandedRows });
this.rowTemplate = ({ row }) => <div>Details for {row.name} from {row.city}</div>;
}
render() {
const { rows, columns } = this.state;

return (
<Grid
rows={rows}
columns={columns}
>
<RowDetailState
defaultExpandedRows={[2, 5]}
/>
<TableView />
<TableHeaderRow />
<TableRowDetail
template={this.rowTemplate}
/>
</Grid>
);
}
}
@@ -0,0 +1,16 @@
import React from 'react';
import { mount } from 'enzyme';
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
import { SimpleDetailRowDemo } from './simple-detail-row';

describe('MUI: simple detail row demo', () => {
test('should work', () => {
mount(
<MuiThemeProvider theme={createMuiTheme()}>
<SimpleDetailRowDemo />
</MuiThemeProvider>,
);

expect(true).toBeTruthy();
});
});
3 changes: 3 additions & 0 deletions packages/dx-react-demos/src/material-ui/index.jsx
Expand Up @@ -18,6 +18,7 @@ import { FilteringDemos } from './filtering';
import { PagingDemos } from './paging';
import { GroupingDemos } from './grouping';
import { SelectionDemos } from './selection';
import { DetailRowDemos } from './detail-row';
import { ColumnReorderingDemos } from './column-reordering';

injectTapEventPlugin();
Expand Down Expand Up @@ -45,6 +46,7 @@ const Demos = () => (
<Route path="/material-ui/filtering" component={FilteringDemos} />
<Route path="/material-ui/selection" component={SelectionDemos} />
<Route path="/material-ui/grouping" component={GroupingDemos} />
<Route path="/material-ui/detail-row" component={DetailRowDemos} />
<Route path="/material-ui/column-reordering" component={ColumnReorderingDemos} />
</div>
</MuiThemeProvider>
Expand Down Expand Up @@ -78,6 +80,7 @@ export const MaterialUIDemos = withRouter(({ location }) => {
<li><NavLink to="/material-ui/filtering">Filtering</NavLink></li>
<li><NavLink to="/material-ui/selection">Selection</NavLink></li>
<li><NavLink to="/material-ui/grouping">Grouping</NavLink></li>
<li><NavLink to="/material-ui/detail-row">Detail Row</NavLink></li>
<li>
<NavLink to="/material-ui/column-reordering">Column Reordering</NavLink>
</li>
Expand Down
@@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';

import { TableGroupRow as TableGroupRowBase } from '@devexpress/dx-react-grid';
import { TableGroupRowCell, TableGroupIndentCell } from '../templates/table-group-row-cell';
Expand All @@ -8,14 +7,7 @@ export const TableGroupRow = props => (
<TableGroupRowBase
groupRowCellTemplate={TableGroupRowCell}
groupIndentCellTemplate={TableGroupIndentCell}
groupColumnWidth={20}
{...props}
/>
);

TableGroupRow.defaultProps = {
groupColumnWidth: 20,
};

TableGroupRow.propTypes = {
groupColumnWidth: PropTypes.number,
};
Expand Up @@ -7,6 +7,7 @@ export const TableRowDetail = props => (
<TableRowDetailBase
detailToggleTemplate={TableDetailToggleCell}
detailCellTemplate={TableDetailCell}
detailToggleCellWidth={25}
{...props}
/>
);
@@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';

import { TableSelection as TableSelectionBase } from '@devexpress/dx-react-grid';
import { TableSelectAllCell } from '../templates/table-select-all-cell';
Expand All @@ -9,14 +8,7 @@ export const TableSelection = props => (
<TableSelectionBase
selectCellTemplate={TableSelectCell}
selectAllCellTemplate={TableSelectAllCell}
selectionColumnWidth={30}
{...props}
/>
);

TableSelection.defaultProps = {
selectionColumnWidth: 30,
};

TableSelection.propTypes = {
selectionColumnWidth: PropTypes.number,
};
1 change: 1 addition & 0 deletions packages/dx-react-grid-material-ui/src/index.js
@@ -1,6 +1,7 @@
export { Grid } from './grid';
export { PagingPanel } from './plugins/paging-panel';
export { GroupingPanel } from './plugins/grouping-panel';
export { TableRowDetail } from './plugins/table-row-detail';
export { TableGroupRow } from './plugins/table-group-row';
export { TableSelection } from './plugins/table-selection';
export { TableView } from './plugins/table-view';
Expand Down
@@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';

import { TableGroupRow as TableGroupRowBase } from '@devexpress/dx-react-grid';
import { TableGroupRowCell, TableGroupIndentCell } from '../templates/table-group-row-cell';
Expand All @@ -11,14 +10,7 @@ export const TableGroupRow = props => (
<TableGroupRowBase
groupRowCellTemplate={groupRowCellTemplate}
groupIndentCellTemplate={groupIndentCellTemplate}
groupColumnWidth={24}
{...props}
/>
);

TableGroupRow.defaultProps = {
groupColumnWidth: 24,
};

TableGroupRow.propTypes = {
groupColumnWidth: PropTypes.number,
};
@@ -0,0 +1,16 @@
import React from 'react';
import { TableRowDetail as TableRowDetailBase } from '@devexpress/dx-react-grid';
import { TableDetailToggleCell } from '../templates/table-detail-toggle-cell';
import { TableDetailCell } from '../templates/table-detail-cell';

const detailToggleTemplate = props => <TableDetailToggleCell {...props} />;
const detailCellTemplate = props => <TableDetailCell {...props} />;

export const TableRowDetail = props => (
<TableRowDetailBase
detailToggleTemplate={detailToggleTemplate}
detailCellTemplate={detailCellTemplate}
detailToggleCellWidth={42}
{...props}
/>
);
@@ -1,5 +1,4 @@
import React from 'react';
import PropTypes from 'prop-types';

import { TableSelection as TableSelectionBase } from '@devexpress/dx-react-grid';
import { TableSelectAllCell } from '../templates/table-select-all-cell';
Expand All @@ -12,14 +11,7 @@ export const TableSelection = props => (
<TableSelectionBase
selectCellTemplate={selectCellTemplate}
selectAllCellTemplate={selectAllCellTemplate}
selectionColumnWidth={50}
{...props}
/>
);

TableSelection.defaultProps = {
selectionColumnWidth: 50,
};

TableSelection.propTypes = {
selectionColumnWidth: PropTypes.number,
};
@@ -0,0 +1,33 @@
import React from 'react';
import PropTypes from 'prop-types';
import { TableCell } from 'material-ui';
import { withStyles, createStyleSheet } from 'material-ui/styles';

const styleSheet = createStyleSheet('TableDetailCell', theme => ({
active: {
backgroundColor: theme.palette.background.contentFrame,
},
}));

const TableDetailCellBase = ({ colspan, style, template, classes }) =>
<TableCell
style={style}
colSpan={colspan}
className={classes.active}
>
{template()}
</TableCell>;

TableDetailCellBase.propTypes = {
style: PropTypes.shape(),
colspan: PropTypes.number,
template: PropTypes.func.isRequired,
classes: PropTypes.object.isRequired,
};

TableDetailCellBase.defaultProps = {
style: null,
colspan: 1,
};

export const TableDetailCell = withStyles(styleSheet)(TableDetailCellBase);

0 comments on commit c161c66

Please sign in to comment.