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