Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0c627a4

Browse files
refactor(site): refactor filter search field (#13545)
1 parenta11f8b0 commit0c627a4

File tree

3 files changed

+112
-47
lines changed

3 files changed

+112
-47
lines changed

‎site/src/components/Filter/filter.tsx‎

Lines changed: 9 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
import{useTheme}from"@emotion/react";
22
importCheckOutlinedfrom"@mui/icons-material/CheckOutlined";
3-
importCloseOutlinedfrom"@mui/icons-material/CloseOutlined";
43
importKeyboardArrowDownfrom"@mui/icons-material/KeyboardArrowDown";
54
importOpenInNewOutlinedfrom"@mui/icons-material/OpenInNewOutlined";
6-
importSearchOutlinedfrom"@mui/icons-material/SearchOutlined";
75
importButton,{typeButtonProps}from"@mui/material/Button";
86
importDividerfrom"@mui/material/Divider";
9-
importIconButtonfrom"@mui/material/IconButton";
10-
importInputAdornmentfrom"@mui/material/InputAdornment";
117
importMenu,{typeMenuProps}from"@mui/material/Menu";
128
importMenuItemfrom"@mui/material/MenuItem";
139
importMenuListfrom"@mui/material/MenuList";
1410
importSkeleton,{typeSkeletonProps}from"@mui/material/Skeleton";
15-
importTextFieldfrom"@mui/material/TextField";
16-
importTooltipfrom"@mui/material/Tooltip";
1711
import{
1812
typeFC,
1913
typeReactNode,
@@ -35,6 +29,7 @@ import {
3529
SearchInput,
3630
searchStyles,
3731
}from"components/Search/Search";
32+
import{SearchField}from"components/SearchField/SearchField";
3833
import{useDebouncedFunction}from"hooks/debounce";
3934
importtype{useFilterMenu}from"./menu";
4035
importtype{BaseOption}from"./options";
@@ -199,7 +194,6 @@ export const Filter: FC<FilterProps> = ({
199194
},[filter.query]);
200195

201196
constshouldDisplayError=hasError(error)&&isApiValidationError(error);
202-
consthasFilterQuery=filter.query!=="";
203197

204198
return(
205199
<div
@@ -226,25 +220,23 @@ export const Filter: FC<FilterProps> = ({
226220
learnMoreLabel2={learnMoreLabel2}
227221
learnMoreLink2={learnMoreLink2}
228222
/>
229-
<TextField
223+
<SearchField
230224
fullWidth
231225
error={shouldDisplayError}
232226
helperText={
233227
shouldDisplayError
234228
?getValidationErrorMessage(error)
235229
:undefined
236230
}
237-
size="small"
231+
placeholder="Search..."
232+
value={queryCopy}
233+
onChange={(query)=>{
234+
setQueryCopy(query);
235+
filter.debounceUpdate(query);
236+
}}
238237
InputProps={{
239-
"aria-label":"Filter",
240-
name:"query",
241-
placeholder:"Search...",
242-
value:queryCopy,
243238
ref:textboxInputRef,
244-
onChange:(e)=>{
245-
setQueryCopy(e.target.value);
246-
filter.debounceUpdate(e.target.value);
247-
},
239+
"aria-label":"Filter",
248240
onBlur:()=>{
249241
if(queryCopy!==filter.query){
250242
setQueryCopy(filter.query);
@@ -258,40 +250,10 @@ export const Filter: FC<FilterProps> = ({
258250
"&:hover":{
259251
zIndex:2,
260252
},
261-
"& input::placeholder":{
262-
color:theme.palette.text.secondary,
263-
},
264-
"& .MuiInputAdornment-root":{
265-
marginLeft:0,
266-
},
267253
"&.Mui-error":{
268254
zIndex:3,
269255
},
270256
},
271-
startAdornment:(
272-
<InputAdornmentposition="start">
273-
<SearchOutlined
274-
css={{
275-
fontSize:14,
276-
color:theme.palette.text.secondary,
277-
}}
278-
/>
279-
</InputAdornment>
280-
),
281-
endAdornment:hasFilterQuery&&(
282-
<InputAdornmentposition="end">
283-
<Tooltiptitle="Clear filter">
284-
<IconButton
285-
size="small"
286-
onClick={()=>{
287-
filter.update("");
288-
}}
289-
>
290-
<CloseOutlinedcss={{fontSize:14}}/>
291-
</IconButton>
292-
</Tooltip>
293-
</InputAdornment>
294-
),
295257
}}
296258
/>
297259
</div>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
importtype{Meta,StoryObj}from"@storybook/react";
2+
import{userEvent,within}from"@storybook/test";
3+
import{useState}from"react";
4+
import{SearchField}from"./SearchField";
5+
6+
constmeta:Meta<typeofSearchField>={
7+
title:"components/SearchField",
8+
component:SearchField,
9+
args:{
10+
placeholder:"Search...",
11+
},
12+
render:functionStatefulWrapper(args){
13+
const[value,setValue]=useState(args.value);
14+
return<SearchField{...args}value={value}onChange={setValue}/>;
15+
},
16+
};
17+
18+
exportdefaultmeta;
19+
typeStory=StoryObj<typeofSearchField>;
20+
21+
exportconstEmpty:Story={};
22+
23+
exportconstDefaultValue:Story={
24+
args:{
25+
value:"owner:me",
26+
},
27+
};
28+
29+
exportconstTypeValue:Story={
30+
play:async({ canvasElement})=>{
31+
constcanvas=within(canvasElement);
32+
constinput=canvas.getByRole("textbox");
33+
awaituserEvent.type(input,"owner:me");
34+
},
35+
};
36+
37+
exportconstClearValue:Story={
38+
args:{
39+
value:"owner:me",
40+
},
41+
play:async({ canvasElement})=>{
42+
constcanvas=within(canvasElement);
43+
awaituserEvent.click(canvas.getByRole("button",{name:"Clear field"}));
44+
},
45+
};
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import{useTheme}from"@emotion/react";
2+
importCloseIconfrom"@mui/icons-material/CloseOutlined";
3+
importSearchIconfrom"@mui/icons-material/SearchOutlined";
4+
importIconButtonfrom"@mui/material/IconButton";
5+
importInputAdornmentfrom"@mui/material/InputAdornment";
6+
importTextField,{typeTextFieldProps}from"@mui/material/TextField";
7+
importTooltipfrom"@mui/material/Tooltip";
8+
importvisuallyHiddenfrom"@mui/utils/visuallyHidden";
9+
importtype{FC}from"react";
10+
11+
exporttypeSearchFieldProps=Omit<TextFieldProps,"onChange">&{
12+
onChange:(query:string)=>void;
13+
};
14+
15+
exportconstSearchField:FC<SearchFieldProps>=({
16+
value="",
17+
onChange,
18+
InputProps,
19+
...textFieldProps
20+
})=>{
21+
consttheme=useTheme();
22+
return(
23+
<TextField
24+
size="small"
25+
value={value}
26+
onChange={(e)=>onChange(e.target.value)}
27+
InputProps={{
28+
startAdornment:(
29+
<InputAdornmentposition="start">
30+
<SearchIcon
31+
css={{
32+
fontSize:14,
33+
color:theme.palette.text.secondary,
34+
}}
35+
/>
36+
</InputAdornment>
37+
),
38+
endAdornment:value!==""&&(
39+
<InputAdornmentposition="end">
40+
<Tooltiptitle="Clear field">
41+
<IconButton
42+
size="small"
43+
onClick={()=>{
44+
onChange("");
45+
}}
46+
>
47+
<CloseIconcss={{fontSize:14}}/>
48+
<spancss={{ ...visuallyHidden}}>Clear field</span>
49+
</IconButton>
50+
</Tooltip>
51+
</InputAdornment>
52+
),
53+
...InputProps,
54+
}}
55+
{...textFieldProps}
56+
/>
57+
);
58+
};

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp