Skip to content

Commit 1e8455e

Browse files
authored
refactor(query): Refactor QueryInputBox into a dedicated component from SearchTabPanel. (#196)
1 parent 19fd738 commit 1e8455e

File tree

4 files changed

+158
-128
lines changed

4 files changed

+158
-128
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
.query-input-box-with-progress {
2+
/* JoyUI has a rounding issue when calculating the Textarea width, causing it to overflow its
3+
container. */
4+
margin-right: 1px;
5+
}
6+
7+
.query-input-box {
8+
flex-direction: row !important;
9+
border-radius: 0 !important;
10+
}
11+
12+
.query-option-button {
13+
width: 1.5rem !important;
14+
min-width: 0 !important;
15+
height: 1.5rem !important;
16+
min-height: 0 !important;
17+
18+
font-family: Inter, sans-serif !important;
19+
}
20+
21+
.query-input-box-textarea {
22+
width: 0;
23+
}
24+
25+
.query-input-box-end-decorator {
26+
display: block !important;
27+
margin-block-start: 0 !important;
28+
}
29+
30+
.query-input-box-linear-progress {
31+
/* stylelint-disable-next-line custom-property-pattern */
32+
--LinearProgress-radius: 0 !important;
33+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import React, {
2+
useContext,
3+
useState,
4+
} from "react";
5+
6+
import {
7+
LinearProgress,
8+
Stack,
9+
Textarea,
10+
} from "@mui/joy";
11+
12+
import {StateContext} from "../../../../../contexts/StateContextProvider";
13+
import {
14+
QUERY_PROGRESS_VALUE_MAX,
15+
QueryArgs,
16+
} from "../../../../../typings/query";
17+
import {UI_ELEMENT} from "../../../../../typings/states";
18+
import {isDisabled} from "../../../../../utils/states";
19+
import ToggleIconButton from "./ToggleIconButton";
20+
21+
import "./QueryInputBox.css";
22+
23+
24+
/**
25+
* Provides a text input and optional toggles for submitting search queries.
26+
*
27+
* @return
28+
*/
29+
const QueryInputBox = () => {
30+
const {queryProgress, startQuery, uiState} = useContext(StateContext);
31+
32+
const [queryString, setQueryString] = useState<string>("");
33+
const [isCaseSensitive, setIsCaseSensitive] = useState<boolean>(false);
34+
const [isRegex, setIsRegex] = useState<boolean>(false);
35+
36+
const handleQuerySubmit = (newArgs: Partial<QueryArgs>) => {
37+
startQuery({
38+
isCaseSensitive: isCaseSensitive,
39+
isRegex: isRegex,
40+
queryString: queryString,
41+
...newArgs,
42+
});
43+
};
44+
45+
const handleQueryInputChange = (ev: React.ChangeEvent<HTMLTextAreaElement>) => {
46+
setQueryString(ev.target.value);
47+
handleQuerySubmit({queryString: ev.target.value});
48+
};
49+
50+
const handleCaseSensitivityButtonClick = () => {
51+
handleQuerySubmit({isCaseSensitive: !isCaseSensitive});
52+
setIsCaseSensitive(!isCaseSensitive);
53+
};
54+
55+
const handleRegexButtonClick = () => {
56+
handleQuerySubmit({isRegex: !isRegex});
57+
setIsRegex(!isRegex);
58+
};
59+
60+
const isQueryInputBoxDisabled = isDisabled(uiState, UI_ELEMENT.QUERY_INPUT_BOX);
61+
62+
return (
63+
<div className={"query-input-box-with-progress"}>
64+
<Textarea
65+
className={"query-input-box"}
66+
maxRows={7}
67+
placeholder={"Search"}
68+
size={"sm"}
69+
endDecorator={
70+
<Stack
71+
direction={"row"}
72+
spacing={0.25}
73+
>
74+
<ToggleIconButton
75+
className={"query-option-button"}
76+
disabled={isQueryInputBoxDisabled}
77+
isChecked={isCaseSensitive}
78+
size={"sm"}
79+
tooltipTitle={"Match case"}
80+
variant={"plain"}
81+
onClick={handleCaseSensitivityButtonClick}
82+
>
83+
Aa
84+
</ToggleIconButton>
85+
86+
<ToggleIconButton
87+
className={"query-option-button"}
88+
disabled={isQueryInputBoxDisabled}
89+
isChecked={isRegex}
90+
size={"sm"}
91+
tooltipTitle={"Use regular expression"}
92+
variant={"plain"}
93+
onClick={handleRegexButtonClick}
94+
>
95+
.*
96+
</ToggleIconButton>
97+
</Stack>
98+
}
99+
slotProps={{
100+
textarea: {
101+
className: "query-input-box-textarea",
102+
disabled: isQueryInputBoxDisabled,
103+
},
104+
endDecorator: {className: "query-input-box-end-decorator"},
105+
}}
106+
onChange={handleQueryInputChange}/>
107+
<LinearProgress
108+
className={"query-input-box-linear-progress"}
109+
determinate={true}
110+
thickness={4}
111+
value={queryProgress * 100}
112+
color={QUERY_PROGRESS_VALUE_MAX === queryProgress ?
113+
"success" :
114+
"primary"}/>
115+
</div>
116+
);
117+
};
118+
119+
120+
export default QueryInputBox;

src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/index.css

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,6 @@
55
height: 100%;
66
}
77

8-
.query-input-box-with-progress {
9-
/* JoyUI has a rounding issue when calculating the Textarea width, causing it to overflow its
10-
container. */
11-
margin-right: 1px;
12-
}
13-
14-
.query-input-box {
15-
flex-direction: row !important;
16-
border-radius: 0 !important;
17-
}
18-
19-
.query-option-button {
20-
width: 1.5rem !important;
21-
min-width: 0 !important;
22-
height: 1.5rem !important;
23-
min-height: 0 !important;
24-
25-
font-family: Inter, sans-serif !important;
26-
}
27-
28-
.query-input-box-textarea {
29-
width: 0;
30-
}
31-
32-
.query-input-box-end-decorator {
33-
display: block !important;
34-
margin-block-start: 0 !important;
35-
}
36-
37-
.query-input-box-linear-progress {
38-
/* stylelint-disable-next-line custom-property-pattern */
39-
--LinearProgress-radius: 0 !important;
40-
}
41-
428
.query-results {
439
overflow-y: auto;
4410
flex-grow: 1;

src/components/CentralContainer/Sidebar/SidebarTabs/SearchTabPanel/index.tsx

Lines changed: 5 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,25 @@
1-
import React, {
1+
import {
22
useContext,
33
useState,
44
} from "react";
55

66
import {
77
AccordionGroup,
88
Box,
9-
LinearProgress,
10-
Stack,
11-
Textarea,
129
} from "@mui/joy";
1310

1411
import UnfoldLessIcon from "@mui/icons-material/UnfoldLess";
1512
import UnfoldMoreIcon from "@mui/icons-material/UnfoldMore";
1613

1714
import {StateContext} from "../../../../../contexts/StateContextProvider";
18-
import {
19-
QUERY_PROGRESS_VALUE_MAX,
20-
QueryArgs,
21-
} from "../../../../../typings/query";
22-
import {UI_ELEMENT} from "../../../../../typings/states";
2315
import {
2416
TAB_DISPLAY_NAMES,
2517
TAB_NAME,
2618
} from "../../../../../typings/tab";
27-
import {isDisabled} from "../../../../../utils/states";
2819
import CustomTabPanel from "../CustomTabPanel";
2920
import PanelTitleButton from "../PanelTitleButton";
21+
import QueryInputBox from "./QueryInputBox";
3022
import ResultsGroup from "./ResultsGroup";
31-
import ToggleIconButton from "./ToggleIconButton";
3223

3324
import "./index.css";
3425

@@ -39,42 +30,14 @@ import "./index.css";
3930
* @return
4031
*/
4132
const SearchTabPanel = () => {
42-
const {queryProgress, queryResults, startQuery, uiState} = useContext(StateContext);
33+
const {queryResults} = useContext(StateContext);
34+
4335
const [isAllExpanded, setIsAllExpanded] = useState<boolean>(true);
44-
const [queryString, setQueryString] = useState<string>("");
45-
const [isCaseSensitive, setIsCaseSensitive] = useState<boolean>(false);
46-
const [isRegex, setIsRegex] = useState<boolean>(false);
4736

4837
const handleCollapseAllButtonClick = () => {
4938
setIsAllExpanded((v) => !v);
5039
};
5140

52-
const handleQuerySubmit = (newArgs: Partial<QueryArgs>) => {
53-
startQuery({
54-
isCaseSensitive: isCaseSensitive,
55-
isRegex: isRegex,
56-
queryString: queryString,
57-
...newArgs,
58-
});
59-
};
60-
61-
const handleQueryInputChange = (ev: React.ChangeEvent<HTMLTextAreaElement>) => {
62-
setQueryString(ev.target.value);
63-
handleQuerySubmit({queryString: ev.target.value});
64-
};
65-
66-
const handleCaseSensitivityButtonClick = () => {
67-
handleQuerySubmit({isCaseSensitive: !isCaseSensitive});
68-
setIsCaseSensitive(!isCaseSensitive);
69-
};
70-
71-
const handleRegexButtonClick = () => {
72-
handleQuerySubmit({isRegex: !isRegex});
73-
setIsRegex(!isRegex);
74-
};
75-
76-
const isQueryInputBoxDisabled = isDisabled(uiState, UI_ELEMENT.QUERY_INPUT_BOX);
77-
7841
return (
7942
<CustomTabPanel
8043
tabName={TAB_NAME.SEARCH}
@@ -93,59 +56,7 @@ const SearchTabPanel = () => {
9356
}
9457
>
9558
<Box className={"search-tab-container"}>
96-
<div className={"query-input-box-with-progress"}>
97-
<Textarea
98-
className={"query-input-box"}
99-
maxRows={7}
100-
placeholder={"Search"}
101-
size={"sm"}
102-
endDecorator={
103-
<Stack
104-
direction={"row"}
105-
spacing={0.25}
106-
>
107-
<ToggleIconButton
108-
className={"query-option-button"}
109-
disabled={isQueryInputBoxDisabled}
110-
isChecked={isCaseSensitive}
111-
size={"sm"}
112-
tooltipTitle={"Match case"}
113-
variant={"plain"}
114-
onClick={handleCaseSensitivityButtonClick}
115-
>
116-
Aa
117-
</ToggleIconButton>
118-
119-
<ToggleIconButton
120-
className={"query-option-button"}
121-
disabled={isQueryInputBoxDisabled}
122-
isChecked={isRegex}
123-
size={"sm"}
124-
tooltipTitle={"Use regular expression"}
125-
variant={"plain"}
126-
onClick={handleRegexButtonClick}
127-
>
128-
.*
129-
</ToggleIconButton>
130-
</Stack>
131-
}
132-
slotProps={{
133-
textarea: {
134-
className: "query-input-box-textarea",
135-
disabled: isQueryInputBoxDisabled,
136-
},
137-
endDecorator: {className: "query-input-box-end-decorator"},
138-
}}
139-
onChange={handleQueryInputChange}/>
140-
<LinearProgress
141-
className={"query-input-box-linear-progress"}
142-
determinate={true}
143-
thickness={4}
144-
value={queryProgress * 100}
145-
color={QUERY_PROGRESS_VALUE_MAX === queryProgress ?
146-
"success" :
147-
"primary"}/>
148-
</div>
59+
<QueryInputBox/>
14960
<AccordionGroup
15061
className={"query-results"}
15162
disableDivider={true}

0 commit comments

Comments
 (0)