diff options
author | Kristóf Marussy <kristof@marussy.com> | 2022-08-18 02:08:21 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2022-08-18 02:08:21 +0200 |
commit | 675f7271642bdddbc008d22678e277c72032bdcd (patch) | |
tree | 765e1d2ccf44a1f3ec90590797c3465c1f5b1042 /subprojects/frontend/src/editor/SearchToolbar.tsx | |
parent | fix(frontend): search panel fixes (diff) | |
download | refinery-675f7271642bdddbc008d22678e277c72032bdcd.tar.gz refinery-675f7271642bdddbc008d22678e277c72032bdcd.tar.zst refinery-675f7271642bdddbc008d22678e277c72032bdcd.zip |
feat(frontend): responsive editor styling
Diffstat (limited to 'subprojects/frontend/src/editor/SearchToolbar.tsx')
-rw-r--r-- | subprojects/frontend/src/editor/SearchToolbar.tsx | 108 |
1 files changed, 82 insertions, 26 deletions
diff --git a/subprojects/frontend/src/editor/SearchToolbar.tsx b/subprojects/frontend/src/editor/SearchToolbar.tsx index dd7859c5..a5925328 100644 --- a/subprojects/frontend/src/editor/SearchToolbar.tsx +++ b/subprojects/frontend/src/editor/SearchToolbar.tsx | |||
@@ -2,7 +2,6 @@ import CloseIcon from '@mui/icons-material/Close'; | |||
2 | import FindReplaceIcon from '@mui/icons-material/FindReplace'; | 2 | import FindReplaceIcon from '@mui/icons-material/FindReplace'; |
3 | import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; | 3 | import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; |
4 | import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; | 4 | import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp'; |
5 | import SearchIcon from '@mui/icons-material/Search'; | ||
6 | import Button from '@mui/material/Button'; | 5 | import Button from '@mui/material/Button'; |
7 | import Checkbox from '@mui/material/Checkbox'; | 6 | import Checkbox from '@mui/material/Checkbox'; |
8 | import FormControlLabel from '@mui/material/FormControlLabel'; | 7 | import FormControlLabel from '@mui/material/FormControlLabel'; |
@@ -10,20 +9,31 @@ import FormHelperText from '@mui/material/FormHelperText'; | |||
10 | import IconButton from '@mui/material/IconButton'; | 9 | import IconButton from '@mui/material/IconButton'; |
11 | import Stack from '@mui/material/Stack'; | 10 | import Stack from '@mui/material/Stack'; |
12 | import TextField from '@mui/material/TextField'; | 11 | import TextField from '@mui/material/TextField'; |
12 | import ToggleButton from '@mui/material/ToggleButton'; | ||
13 | import Toolbar from '@mui/material/Toolbar'; | 13 | import Toolbar from '@mui/material/Toolbar'; |
14 | import useMediaQuery from '@mui/material/useMediaQuery'; | ||
14 | import { observer } from 'mobx-react-lite'; | 15 | import { observer } from 'mobx-react-lite'; |
15 | import React, { useCallback } from 'react'; | 16 | import React, { useCallback, useState } from 'react'; |
16 | 17 | ||
17 | import type SearchPanelStore from './SearchPanelStore'; | 18 | import type SearchPanelStore from './SearchPanelStore'; |
18 | 19 | ||
20 | const SPLIT_MEDIA_QUERY = '@media (max-width: 1200px)'; | ||
21 | const ABBREVIATE_MEDIA_QUERY = '@media (max-width: 720px)'; | ||
22 | |||
19 | function SearchToolbar({ store }: { store: SearchPanelStore }): JSX.Element { | 23 | function SearchToolbar({ store }: { store: SearchPanelStore }): JSX.Element { |
20 | const { | 24 | const { |
21 | id: panelId, | 25 | id: panelId, |
22 | query: { search, valid, caseSensitive, literal, regexp, replace }, | 26 | query: { search, valid, caseSensitive, literal, regexp, replace }, |
23 | invalidRegexp, | 27 | invalidRegexp, |
24 | } = store; | 28 | } = store; |
29 | const split = useMediaQuery(SPLIT_MEDIA_QUERY); | ||
30 | const abbreviate = useMediaQuery(ABBREVIATE_MEDIA_QUERY); | ||
31 | const [showRepalceState, setShowReplaceState] = useState(false); | ||
32 | |||
33 | const showReplace = !split || showRepalceState || replace !== ''; | ||
25 | 34 | ||
26 | const searchHelperId = `${panelId}-search-helper`; | 35 | const searchHelperId = `${panelId}-search-helper`; |
36 | const replaceId = `${panelId}-replace`; | ||
27 | 37 | ||
28 | const searchFieldRef = useCallback( | 38 | const searchFieldRef = useCallback( |
29 | (element: HTMLInputElement | null) => | 39 | (element: HTMLInputElement | null) => |
@@ -32,13 +42,20 @@ function SearchToolbar({ store }: { store: SearchPanelStore }): JSX.Element { | |||
32 | ); | 42 | ); |
33 | 43 | ||
34 | return ( | 44 | return ( |
35 | <Toolbar variant="dense" sx={{ py: 0.5, alignItems: 'flex-start' }}> | 45 | <Toolbar |
46 | variant="dense" | ||
47 | sx={{ py: 0.5, alignItems: 'center', minHeight: 'auto' }} | ||
48 | > | ||
36 | <Stack | 49 | <Stack |
37 | direction="row" | 50 | direction={split ? 'column' : 'row'} |
38 | flexWrap="wrap" | 51 | sx={{ |
39 | alignItems="center" | 52 | alignItems: 'center', |
40 | rowGap={0.5} | 53 | flexGrow: 1, |
41 | flexGrow={1} | 54 | [SPLIT_MEDIA_QUERY]: { |
55 | alignItems: 'start', | ||
56 | gap: 0.5, | ||
57 | }, | ||
58 | }} | ||
42 | > | 59 | > |
43 | <Stack direction="row" flexWrap="wrap" alignItems="center" rowGap={0.5}> | 60 | <Stack direction="row" flexWrap="wrap" alignItems="center" rowGap={0.5}> |
44 | <TextField | 61 | <TextField |
@@ -65,7 +82,7 @@ function SearchToolbar({ store }: { store: SearchPanelStore }): JSX.Element { | |||
65 | }} | 82 | }} |
66 | variant="standard" | 83 | variant="standard" |
67 | size="small" | 84 | size="small" |
68 | sx={{ my: 0.25, mr: 1 }} | 85 | sx={{ mt: '4px', mr: 1 }} |
69 | inputRef={searchFieldRef} | 86 | inputRef={searchFieldRef} |
70 | /> | 87 | /> |
71 | {invalidRegexp && ( | 88 | {invalidRegexp && ( |
@@ -92,6 +109,7 @@ function SearchToolbar({ store }: { store: SearchPanelStore }): JSX.Element { | |||
92 | aria-label="Previous" | 109 | aria-label="Previous" |
93 | disabled={!valid} | 110 | disabled={!valid} |
94 | onClick={() => store.findPrevious()} | 111 | onClick={() => store.findPrevious()} |
112 | color="inherit" | ||
95 | > | 113 | > |
96 | <KeyboardArrowUpIcon fontSize="small" /> | 114 | <KeyboardArrowUpIcon fontSize="small" /> |
97 | </IconButton> | 115 | </IconButton> |
@@ -99,19 +117,17 @@ function SearchToolbar({ store }: { store: SearchPanelStore }): JSX.Element { | |||
99 | aria-label="Next" | 117 | aria-label="Next" |
100 | disabled={!valid} | 118 | disabled={!valid} |
101 | onClick={() => store.findNext()} | 119 | onClick={() => store.findNext()} |
120 | color="inherit" | ||
102 | > | 121 | > |
103 | <KeyboardArrowDownIcon fontSize="small" /> | 122 | <KeyboardArrowDownIcon fontSize="small" /> |
104 | </IconButton> | 123 | </IconButton> |
105 | <Button | ||
106 | disabled={!valid} | ||
107 | onClick={() => store.selectMatches()} | ||
108 | color="inherit" | ||
109 | startIcon={<SearchIcon fontSize="inherit" />} | ||
110 | > | ||
111 | Find all | ||
112 | </Button> | ||
113 | </Stack> | 124 | </Stack> |
114 | <Stack direction="row" flexWrap="wrap" rowGap={0.5}> | 125 | <Stack |
126 | direction="row" | ||
127 | flexWrap="wrap" | ||
128 | alignItems="center" | ||
129 | rowGap={0.5} | ||
130 | > | ||
115 | <FormControlLabel | 131 | <FormControlLabel |
116 | control={ | 132 | control={ |
117 | <Checkbox | 133 | <Checkbox |
@@ -122,7 +138,8 @@ function SearchToolbar({ store }: { store: SearchPanelStore }): JSX.Element { | |||
122 | size="small" | 138 | size="small" |
123 | /> | 139 | /> |
124 | } | 140 | } |
125 | label="Match case" | 141 | aria-label="Match case" |
142 | label={abbreviate ? 'Case' : 'Match case'} | ||
126 | /> | 143 | /> |
127 | <FormControlLabel | 144 | <FormControlLabel |
128 | control={ | 145 | control={ |
@@ -134,7 +151,8 @@ function SearchToolbar({ store }: { store: SearchPanelStore }): JSX.Element { | |||
134 | size="small" | 151 | size="small" |
135 | /> | 152 | /> |
136 | } | 153 | } |
137 | label="Literal" | 154 | aria-label="Literal" |
155 | label={abbreviate ? 'Lit' : 'Literal'} | ||
138 | /> | 156 | /> |
139 | <FormControlLabel | 157 | <FormControlLabel |
140 | control={ | 158 | control={ |
@@ -148,9 +166,36 @@ function SearchToolbar({ store }: { store: SearchPanelStore }): JSX.Element { | |||
148 | } | 166 | } |
149 | label="Regexp" | 167 | label="Regexp" |
150 | /> | 168 | /> |
169 | {split && ( | ||
170 | <ToggleButton | ||
171 | value="show-replace" | ||
172 | selected={showReplace} | ||
173 | onClick={() => { | ||
174 | if (showReplace) { | ||
175 | store.updateQuery({ replace: '' }); | ||
176 | setShowReplaceState(false); | ||
177 | } else { | ||
178 | setShowReplaceState(true); | ||
179 | } | ||
180 | }} | ||
181 | aria-label="Show replace options" | ||
182 | aria-controls={replaceId} | ||
183 | size="small" | ||
184 | sx={{ borderRadius: '100%' }} | ||
185 | > | ||
186 | <FindReplaceIcon fontSize="small" /> | ||
187 | </ToggleButton> | ||
188 | )} | ||
151 | </Stack> | 189 | </Stack> |
152 | </Stack> | 190 | </Stack> |
153 | <Stack direction="row" flexWrap="wrap" alignItems="center" rowGap={0.5}> | 191 | <Stack |
192 | id={replaceId} | ||
193 | direction="row" | ||
194 | flexWrap="wrap" | ||
195 | alignItems="center" | ||
196 | rowGap={0.5} | ||
197 | display={showReplace ? 'flex' : 'none'} | ||
198 | > | ||
154 | <TextField | 199 | <TextField |
155 | placeholder="Replace with" | 200 | placeholder="Replace with" |
156 | aria-label="Replace with" | 201 | aria-label="Replace with" |
@@ -166,9 +211,14 @@ function SearchToolbar({ store }: { store: SearchPanelStore }): JSX.Element { | |||
166 | }} | 211 | }} |
167 | variant="standard" | 212 | variant="standard" |
168 | size="small" | 213 | size="small" |
169 | sx={{ mr: 1 }} | 214 | sx={{ mt: '4px', mr: 1 }} |
170 | /> | 215 | /> |
171 | <Stack direction="row" flexWrap="wrap" rowGap={0.5}> | 216 | <Stack |
217 | direction="row" | ||
218 | flexWrap="wrap" | ||
219 | alignItems="center" | ||
220 | rowGap={0.5} | ||
221 | > | ||
172 | <Button | 222 | <Button |
173 | disabled={!valid} | 223 | disabled={!valid} |
174 | onClick={() => store.replaceNext()} | 224 | onClick={() => store.replaceNext()} |
@@ -188,9 +238,15 @@ function SearchToolbar({ store }: { store: SearchPanelStore }): JSX.Element { | |||
188 | </Stack> | 238 | </Stack> |
189 | </Stack> | 239 | </Stack> |
190 | </Stack> | 240 | </Stack> |
191 | <IconButton onClick={() => store.close()} sx={{ mt: '2px', ml: 1 }}> | 241 | <Stack direction="row" alignSelf="stretch" alignItems="start" mt="1px"> |
192 | <CloseIcon fontSize="small" /> | 242 | <IconButton |
193 | </IconButton> | 243 | aria-label="Close find/replace" |
244 | onClick={() => store.close()} | ||
245 | color="inherit" | ||
246 | > | ||
247 | <CloseIcon fontSize="small" /> | ||
248 | </IconButton> | ||
249 | </Stack> | ||
194 | </Toolbar> | 250 | </Toolbar> |
195 | ); | 251 | ); |
196 | } | 252 | } |