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