Skip to content

Commit 33b6863

Browse files
authored
[DataGrid] Add single select column type (#1956)
1 parent db033be commit 33b6863

File tree

23 files changed

+684
-512
lines changed

23 files changed

+684
-512
lines changed

docs/pages/api-docs/data-grid/grid-col-def.md

Lines changed: 28 additions & 27 deletions
Large diffs are not rendered by default.

docs/src/pages/components/data-grid/columns/ColumnTypesGrid.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const rows = [
1313
dateCreated: randomCreatedDate(),
1414
lastLogin: randomUpdatedDate(),
1515
isAdmin: true,
16+
country: 'Spain',
1617
},
1718
{
1819
id: 2,
@@ -21,6 +22,7 @@ const rows = [
2122
dateCreated: randomCreatedDate(),
2223
lastLogin: randomUpdatedDate(),
2324
isAdmin: true,
25+
country: 'France',
2426
},
2527
{
2628
id: 3,
@@ -29,6 +31,7 @@ const rows = [
2931
dateCreated: randomCreatedDate(),
3032
lastLogin: randomUpdatedDate(),
3133
isAdmin: false,
34+
country: 'Brazil',
3235
},
3336
];
3437

@@ -42,6 +45,19 @@ export default function ColumnTypesGrid() {
4245
{ field: 'dateCreated', type: 'date', width: 130 },
4346
{ field: 'lastLogin', type: 'dateTime', width: 180 },
4447
{ field: 'isAdmin', type: 'boolean', width: 120 },
48+
{
49+
field: 'country',
50+
type: 'singleSelect',
51+
width: 150,
52+
valueOptions: [
53+
'Bulgaria',
54+
'Netherlands',
55+
'France',
56+
'United Kingdom',
57+
'Spain',
58+
'Brazil',
59+
],
60+
},
4561
]}
4662
rows={rows}
4763
/>

docs/src/pages/components/data-grid/columns/ColumnTypesGrid.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const rows = [
1313
dateCreated: randomCreatedDate(),
1414
lastLogin: randomUpdatedDate(),
1515
isAdmin: true,
16+
country: 'Spain',
1617
},
1718
{
1819
id: 2,
@@ -21,6 +22,7 @@ const rows = [
2122
dateCreated: randomCreatedDate(),
2223
lastLogin: randomUpdatedDate(),
2324
isAdmin: true,
25+
country: 'France',
2426
},
2527
{
2628
id: 3,
@@ -29,6 +31,7 @@ const rows = [
2931
dateCreated: randomCreatedDate(),
3032
lastLogin: randomUpdatedDate(),
3133
isAdmin: false,
34+
country: 'Brazil',
3235
},
3336
];
3437

@@ -42,6 +45,19 @@ export default function ColumnTypesGrid() {
4245
{ field: 'dateCreated', type: 'date', width: 130 },
4346
{ field: 'lastLogin', type: 'dateTime', width: 180 },
4447
{ field: 'isAdmin', type: 'boolean', width: 120 },
48+
{
49+
field: 'country',
50+
type: 'singleSelect',
51+
width: 150,
52+
valueOptions: [
53+
'Bulgaria',
54+
'Netherlands',
55+
'France',
56+
'United Kingdom',
57+
'Spain',
58+
'Brazil',
59+
],
60+
},
4561
]}
4662
rows={rows}
4763
/>

docs/src/pages/components/data-grid/columns/columns.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,10 @@ The following are the native column types:
240240
- `'date'`
241241
- `'dateTime'`
242242
- `'boolean'`
243+
- `'singleSelect'`
243244

244245
To apply a column type, you need to define the type property in your column definition.
246+
If the column is `type: 'singleSelect'` you also need to set the `valueOptions` property in that column definition.
245247

246248
{{"demo": "pages/components/data-grid/columns/ColumnTypesGrid.js", "bg": "inline"}}
247249

docs/src/pages/components/data-grid/demo/FullFeaturedDemo.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ export default function FullFeaturedDemo() {
255255
const { loading, data, setRowLength, loadNewData } = useDemoData({
256256
dataSet: type,
257257
rowLength: size,
258-
maxColumns: 20,
258+
maxColumns: 40,
259259
editable: true,
260260
});
261261

docs/src/pages/components/data-grid/demo/FullFeaturedDemo.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ export default function FullFeaturedDemo() {
271271
const { loading, data, setRowLength, loadNewData } = useDemoData({
272272
dataSet: type,
273273
rowLength: size,
274-
maxColumns: 20,
274+
maxColumns: 40,
275275
editable: true,
276276
});
277277

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import * as React from 'react';
2+
import Select, { SelectProps } from '@material-ui/core/Select';
3+
import MenuItem from '@material-ui/core/MenuItem';
4+
import { GridCellParams } from '../../models/params/gridCellParams';
5+
import { isEscapeKey } from '../../utils/keyboardUtils';
6+
7+
const renderSingleSelectOptions = (option) =>
8+
typeof option === 'string' ? (
9+
<MenuItem key={option} value={option}>
10+
{option}
11+
</MenuItem>
12+
) : (
13+
<MenuItem key={option.value} value={option.value}>
14+
{option.label}
15+
</MenuItem>
16+
);
17+
18+
export function GridEditSingleSelectCell(props: GridCellParams & SelectProps) {
19+
const {
20+
id,
21+
value,
22+
formattedValue,
23+
api,
24+
field,
25+
row,
26+
colDef,
27+
cellMode,
28+
isEditable,
29+
className,
30+
getValue,
31+
hasFocus,
32+
...other
33+
} = props;
34+
35+
const handleChange = (event) => {
36+
const editProps = { value: event.target.value };
37+
38+
if (event.key) {
39+
api.setEditCellProps({ id, field, props: editProps }, event);
40+
} else {
41+
api.commitCellChange({ id, field, props: editProps }, event);
42+
api.setCellMode(id, field, 'view');
43+
}
44+
};
45+
46+
const handleClose = (event, reason) => {
47+
if (reason === 'backdropClick' || isEscapeKey(event.key)) {
48+
api.setCellMode(id, field, 'view');
49+
}
50+
};
51+
52+
return (
53+
<Select
54+
value={value}
55+
onChange={handleChange}
56+
MenuProps={{
57+
onClose: handleClose,
58+
}}
59+
autoFocus
60+
fullWidth
61+
open
62+
{...other}
63+
>
64+
{colDef.valueOptions.map(renderSingleSelectOptions)}
65+
</Select>
66+
);
67+
}
68+
export const renderEditSingleSelectCell = (params) => <GridEditSingleSelectCell {...params} />;

packages/grid/_modules_/grid/components/panel/filterPanel/GridFilterInputValue.tsx

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,25 @@ import TextField, { TextFieldProps } from '@material-ui/core/TextField';
44
import { unstable_useId as useId } from '@material-ui/core/utils';
55
import { GridLoadIcon } from '../../icons/index';
66
import { GridFilterInputValueProps } from './GridFilterInputValueProps';
7+
import { GridColDef } from '../../../models/colDef/gridColDef';
8+
9+
const renderSingleSelectOptions = ({ valueOptions }: GridColDef) =>
10+
['', ...valueOptions!].map((option) =>
11+
typeof option === 'string' ? (
12+
<option key={option} value={option}>
13+
{option}
14+
</option>
15+
) : (
16+
<option key={option.value} value={option.value}>
17+
{option.label}
18+
</option>
19+
),
20+
);
721

822
export const SUBMIT_FILTER_STROKE_TIME = 500;
923

1024
export interface GridTypeFilterInputValueProps extends GridFilterInputValueProps {
11-
type?: 'text' | 'number' | 'date' | 'datetime-local';
25+
type?: 'text' | 'number' | 'date' | 'datetime-local' | 'singleSelect';
1226
}
1327

1428
export function GridFilterInputValue(props: GridTypeFilterInputValueProps & TextFieldProps) {
@@ -17,6 +31,16 @@ export function GridFilterInputValue(props: GridTypeFilterInputValueProps & Text
1731
const [filterValueState, setFilterValueState] = React.useState(item.value || '');
1832
const [applying, setIsApplying] = React.useState(false);
1933
const id = useId();
34+
const singleSelectProps: TextFieldProps =
35+
type === 'singleSelect'
36+
? {
37+
select: true,
38+
SelectProps: {
39+
native: true,
40+
},
41+
children: renderSingleSelectOptions(apiRef.current.getColumn(item.columnField)),
42+
}
43+
: {};
2044

2145
const onFilterChange = React.useCallback(
2246
(event) => {
@@ -57,6 +81,7 @@ export function GridFilterInputValue(props: GridTypeFilterInputValueProps & Text
5781
InputLabelProps={{
5882
shrink: true,
5983
}}
84+
{...singleSelectProps}
6085
{...others}
6186
/>
6287
);

packages/grid/_modules_/grid/models/colDef/gridColDef.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export interface GridColDef {
5959
resizable?: boolean;
6060
/**
6161
* If `true`, the cells of the column are editable.
62-
* @default true
62+
* @default false
6363
*/
6464
editable?: boolean;
6565
/**
@@ -71,6 +71,10 @@ export interface GridColDef {
7171
* @default 'string'
7272
*/
7373
type?: GridColType;
74+
/**
75+
* To be used in combination with `type: 'singleSelect'`. This is an array of the possible cell values and labels.
76+
*/
77+
valueOptions?: Array<string | { value: any; label: string }>;
7478
/**
7579
* Allows to align the column values in cells.
7680
*/

packages/grid/_modules_/grid/models/colDef/gridColType.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,11 @@ export const GRID_DATE_COLUMN_TYPE = 'date';
44
export const GRID_DATETIME_COLUMN_TYPE = 'dateTime';
55
export const GRID_BOOLEAN_COLUMN_TYPE = 'boolean';
66

7-
export type GridNativeColTypes = 'string' | 'number' | 'date' | 'dateTime' | 'boolean';
7+
export type GridNativeColTypes =
8+
| 'string'
9+
| 'number'
10+
| 'date'
11+
| 'dateTime'
12+
| 'boolean'
13+
| 'singleSelect';
814
export type GridColType = GridNativeColTypes | string;

0 commit comments

Comments
 (0)