Merge branch '21128-toolbar-context-menu'
[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 React from 'react';
6 import { WrappedFieldProps } from 'redux-form';
7 import { ArvadosTheme } from 'common/custom-theme';
8 import { StyleRulesCallback, WithStyles, withStyles, FormControl, InputLabel, Select, 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 interface NativeSelectFieldProps {
39     disabled?: boolean;
40 }
41
42 export const NativeSelectField = withStyles(styles)((props: WrappedFieldProps & NativeSelectFieldProps & WithStyles<CssRules> & { items: any[] }) => (
43     <FormControl className={props.classes.formControl}>
44         <Select
45             className={props.classes.selectWrapper}
46             native
47             value={props.input.value}
48             onChange={props.input.onChange}
49             disabled={props.meta.submitting || props.disabled}
50             name={props.input.name}
51             inputProps={{
52                 id: `id-${props.input.name}`,
53                 className: props.classes.select,
54             }}>
55             {props.items.map(item => (
56                 <option
57                     key={item.key}
58                     value={item.key}
59                     className={props.classes.option}>
60                     {item.value}
61                 </option>
62             ))}
63         </Select>
64     </FormControl>
65 ));
66
67 interface SelectFieldProps {
68     children: React.ReactNode;
69     label: string;
70 }
71
72 type SelectFieldCssRules = 'formControl';
73
74 const selectFieldStyles: StyleRulesCallback<SelectFieldCssRules> = (theme: ArvadosTheme) => ({
75     formControl: {
76         marginBottom: theme.spacing.unit * 3,
77     },
78 });
79 export const SelectField = withStyles(selectFieldStyles)((props: WrappedFieldProps & SelectFieldProps & WithStyles<SelectFieldCssRules>) => (
80     <FormControl
81         error={props.meta.invalid}
82         className={props.classes.formControl}>
83         <InputLabel>{props.label}</InputLabel>
84         <Select {...props.input}>{props.children}</Select>
85         <FormHelperText>{props.meta.error}</FormHelperText>
86     </FormControl>
87 ));