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 '../Content';
  9
 10/**
 11 * Styles
 12 */
 13const useStyles = makeStyles((theme) => ({
 14  container: {
 15    margin: theme.spacing(2, 0),
 16    padding: theme.spacing(0, 2, 2, 2),
 17  },
 18  textarea: {},
 19  tabContent: {
 20    margin: theme.spacing(2, 0),
 21  },
 22  preview: {
 23    borderBottom: `solid 3px ${theme.palette.grey['200']}`,
 24    minHeight: '5rem',
 25  },
 26}));
 27
 28type TabPanelProps = {
 29  children: React.ReactNode;
 30  value: number;
 31  index: number;
 32} & React.HTMLProps<HTMLDivElement>;
 33function TabPanel({ children, value, index, ...props }: TabPanelProps) {
 34  return (
 35    <div
 36      role="tabpanel"
 37      hidden={value !== index}
 38      id={`editor-tabpanel-${index}`}
 39      aria-labelledby={`editor-tab-${index}`}
 40      {...props}
 41    >
 42      {value === index && children}
 43    </div>
 44  );
 45}
 46
 47const a11yProps = (index: number) => ({
 48  id: `editor-tab-${index}`,
 49  'aria-controls': `editor-tabpanel-${index}`,
 50});
 51
 52type Props = {
 53  inputProps?: any;
 54  inputText?: string;
 55  loading: boolean;
 56  onChange: (comment: string) => void;
 57};
 58
 59/**
 60 * Component for issue comment input
 61 *
 62 * @param inputProps Reset input value
 63 * @param loading Disable input when component not ready yet
 64 * @param onChange Callback to return input value changes
 65 */
 66function CommentInput({ inputProps, inputText, loading, onChange }: Props) {
 67  const [input, setInput] = useState<string>(inputText ? inputText : '');
 68  const [tab, setTab] = useState(0);
 69  const classes = useStyles();
 70
 71  useEffect(() => {
 72    if (inputProps) setInput(inputProps.value);
 73  }, [inputProps]);
 74
 75  useEffect(() => {
 76    onChange(input);
 77  }, [input, onChange]);
 78
 79  return (
 80    <div>
 81      <Tabs value={tab} onChange={(_, t) => setTab(t)}>
 82        <Tab label="Write" {...a11yProps(0)} />
 83        <Tab label="Preview" {...a11yProps(1)} />
 84      </Tabs>
 85      <div className={classes.tabContent}>
 86        <TabPanel value={tab} index={0}>
 87          <TextField
 88            fullWidth
 89            label="Comment"
 90            placeholder="Leave a comment"
 91            className={classes.textarea}
 92            multiline
 93            value={input}
 94            variant="filled"
 95            rows="4" // TODO: rowsMin support
 96            onChange={(e: any) => setInput(e.target.value)}
 97            disabled={loading}
 98          />
 99        </TabPanel>
100        <TabPanel value={tab} index={1} className={classes.preview}>
101          <Content markdown={input} />
102        </TabPanel>
103      </div>
104    </div>
105  );
106}
107
108export default CommentInput;