CommentInput.tsx

 1import React, { useState, useEffect } from 'react';
 2
 3import Tab from '@material-ui/core/Tab';
 4import Tabs from '@material-ui/core/Tabs';
 5import TextField from '@material-ui/core/TextField';
 6import { makeStyles } from '@material-ui/core/styles';
 7
 8import Content from 'src/components/Content';
 9
10const useStyles = makeStyles((theme) => ({
11  container: {
12    margin: theme.spacing(2, 0),
13    padding: theme.spacing(0, 2, 2, 2),
14  },
15  textarea: {},
16  tabContent: {
17    margin: theme.spacing(2, 0),
18  },
19  preview: {
20    borderBottom: `solid 3px ${theme.palette.grey['200']}`,
21    minHeight: '5rem',
22  },
23  actions: {
24    display: 'flex',
25    justifyContent: 'flex-end',
26  },
27}));
28
29type TabPanelProps = {
30  children: React.ReactNode;
31  value: number;
32  index: number;
33} & React.HTMLProps<HTMLDivElement>;
34function TabPanel({ children, value, index, ...props }: TabPanelProps) {
35  return (
36    <div
37      role="tabpanel"
38      hidden={value !== index}
39      id={`editor-tabpanel-${index}`}
40      aria-labelledby={`editor-tab-${index}`}
41      {...props}
42    >
43      {value === index && children}
44    </div>
45  );
46}
47
48const a11yProps = (index: number) => ({
49  id: `editor-tab-${index}`,
50  'aria-controls': `editor-tabpanel-${index}`,
51});
52
53type Props = {
54  loading: boolean;
55  onChange: (comment: string) => void;
56};
57
58function CommentInput({ loading, onChange }: Props) {
59  const [input, setInput] = useState<string>('');
60  const [tab, setTab] = useState(0);
61  const classes = useStyles();
62
63  useEffect(() => {
64    onChange(input);
65  }, [input, onChange]);
66
67  return (
68    <div>
69      <Tabs value={tab} onChange={(_, t) => setTab(t)}>
70        <Tab label="Write" {...a11yProps(0)} />
71        <Tab label="Preview" {...a11yProps(1)} />
72      </Tabs>
73      <div className={classes.tabContent}>
74        <TabPanel value={tab} index={0}>
75          <TextField
76            fullWidth
77            label="Comment"
78            placeholder="Leave a comment"
79            className={classes.textarea}
80            multiline
81            value={input}
82            variant="filled"
83            rows="4" // TODO: rowsMin support
84            onChange={(e: any) => setInput(e.target.value)}
85            disabled={loading}
86          />
87        </TabPanel>
88        <TabPanel value={tab} index={1} className={classes.preview}>
89          <Content markdown={input} />
90        </TabPanel>
91      </div>
92    </div>
93  );
94}
95
96export default CommentInput;