Merge branch '14971-table-column-filters-ux-improvements'
[arvados-workbench2.git] / src / components / select-field / select-field.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from 'react';
6 import { WrappedFieldProps } from 'redux-form';
7 import { ArvadosTheme } from '~/common/custom-theme';
8 import { StyleRulesCallback, WithStyles, withStyles, FormControl, InputLabel, Select, MenuItem, FormHelperText } from '@material-ui/core';
9
10 type CssRules = 'formControl' | 'selectWrapper' | 'select' | 'option';
11
12 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
13     formControl: {
14         width: '100%'
15     },
16     selectWrapper: {
17         backgroundColor: theme.palette.common.white,
18         '&:before': {
19             borderBottomColor: 'rgba(0, 0, 0, 0.42)'
20         },
21         '&:focus': {
22             outline: 'none'
23         }
24     },
25     select: {
26         fontSize: '0.875rem',
27         '&:focus': {
28             backgroundColor: 'rgba(0, 0, 0, 0.0)'
29         }
30     },
31     option: {
32         fontSize: '0.875rem',
33         backgroundColor: theme.palette.common.white,
34         height: '30px'
35     }
36 });
37
38 export const NativeSelectField = withStyles(styles)
39     ((props: WrappedFieldProps & WithStyles<CssRules> & { items: any[] }) =>
40         <FormControl className={props.classes.formControl}>
41             <Select className={props.classes.selectWrapper}
42                 native
43                 value={props.input.value}
44                 onChange={props.input.onChange}
45                 disabled={props.meta.submitting}
46                 name={props.input.name}
47                 inputProps={{
48                     id: `id-${props.input.name}`,
49                     className: props.classes.select
50                 }}>
51                 {props.items.map(item => (
52                     <option key={item.key} value={item.key} className={props.classes.option}>
53                         {item.value}
54                     </option>
55                 ))}
56             </Select>
57         </FormControl>
58     );
59
60 interface SelectFieldProps {
61     children: React.ReactNode;
62     label: string;
63 }
64
65 type SelectFieldCssRules = 'formControl';
66
67 const selectFieldStyles: StyleRulesCallback<SelectFieldCssRules> = (theme: ArvadosTheme) => ({
68     formControl: {
69         marginBottom: theme.spacing.unit * 3
70     },
71 });
72 export const SelectField = withStyles(selectFieldStyles)(
73     (props: WrappedFieldProps & SelectFieldProps &  WithStyles<SelectFieldCssRules>) =>
74         <FormControl error={props.meta.invalid} className={props.classes.formControl}>
75             <InputLabel>
76                 {props.label}
77             </InputLabel>
78             <Select
79                 {...props.input}>
80                 {props.children}
81             </Select>
82             <FormHelperText>{props.meta.error}</FormHelperText>
83         </FormControl>
84 );