1
+ import { Drawer , useMediaQuery } from '@mui/material' ;
1
2
import { SelectChangeEvent } from '@mui/material/Select' ;
2
3
import React from 'react' ;
3
4
import { Button } from '../base/Button' ;
@@ -37,11 +38,23 @@ function UniversalFilter({
37
38
} : UniversalFilterProps ) : JSX . Element {
38
39
const [ anchorEl , setAnchorEl ] = React . useState < null | HTMLElement > ( null ) ;
39
40
const [ open , setOpen ] = React . useState ( false ) ;
41
+
40
42
const theme = useTheme ( ) ;
43
+ const muiTheme = useTheme ( ) ;
44
+ const isMobile = useMediaQuery ( muiTheme . breakpoints . down ( 'sm' ) ) ;
45
+
46
+ const handleClick = ( event : React . MouseEvent < HTMLElement > ) => {
47
+ setAnchorEl ( event . currentTarget ) ;
48
+ setOpen ( ( prevOpen ) => ! prevOpen ) ;
49
+ } ;
50
+
51
+ const handleClose = ( ) => {
52
+ setAnchorEl ( null ) ;
53
+ setOpen ( false ) ;
54
+ } ;
41
55
42
56
const handleFilterChange = ( event : React . ChangeEvent < { value : string } > , columnName : string ) => {
43
57
const value = event . target . value ;
44
-
45
58
setSelectedFilters ( ( prevFilters ) => ( {
46
59
...prevFilters ,
47
60
[ columnName ] : value
@@ -53,98 +66,91 @@ function UniversalFilter({
53
66
handleApplyFilter ( ) ;
54
67
} ;
55
68
56
- const handleClick = ( event : React . MouseEvent < HTMLElement > ) => {
57
- setAnchorEl ( event . currentTarget ) ;
58
- setOpen ( ( previousOpen ) => ! previousOpen ) ;
59
- } ;
60
-
61
- const canBeOpen = open && Boolean ( anchorEl ) ;
62
- const idx = canBeOpen ? 'transition-popper' : undefined ;
69
+ const renderFilterContent = ( ) => (
70
+ < div style = { { padding : '1rem' , width : isMobile ? '90vw' : 'auto' } } >
71
+ < h3 > Filters: </ h3 >
72
+ { Object . keys ( filters ) . map ( ( filterColumn ) => {
73
+ const options = filters [ filterColumn ] . options ;
74
+ return (
75
+ < div key = { filterColumn } role = "presentation" >
76
+ < InputLabel id = { filters [ filterColumn ] . name } > { filters [ filterColumn ] . name } </ InputLabel >
77
+ < Select
78
+ defaultValue = "All"
79
+ key = { filterColumn }
80
+ value = { selectedFilters [ filterColumn ] }
81
+ variant = { variant }
82
+ onChange = { ( e : SelectChangeEvent < unknown > ) =>
83
+ handleFilterChange ( e as React . ChangeEvent < { value : string } > , filterColumn )
84
+ }
85
+ style = { {
86
+ width : '20rem' ,
87
+ marginBottom : '1rem'
88
+ } }
89
+ inputProps = { { 'aria-label' : 'Without label' } }
90
+ displayEmpty
91
+ >
92
+ { showAllOption && < MenuItem value = "All" > All</ MenuItem > }
93
+ { options . map ( ( option ) => (
94
+ < MenuItem key = { option . value } value = { option . value } >
95
+ { option . label }
96
+ </ MenuItem >
97
+ ) ) }
98
+ </ Select >
99
+ </ div >
100
+ ) ;
101
+ } ) }
63
102
64
- const handleClose = ( ) => {
65
- setAnchorEl ( null ) ;
66
- setOpen ( false ) ;
67
- } ;
103
+ < div style = { { display : 'flex' , justifyContent : 'center' } } >
104
+ < Button variant = "contained" onClick = { handleApplyOnClick } >
105
+ Apply
106
+ </ Button >
107
+ </ div >
108
+ </ div >
109
+ ) ;
68
110
69
111
return (
70
- < React . Fragment >
112
+ < >
71
113
< div id = { id } >
72
114
< TooltipIcon
73
115
title = "Filter"
74
116
onClick = { handleClick }
75
117
icon = { < FilterIcon fill = { theme . palette . icon . default } /> }
76
118
arrow
77
119
/>
78
- < PopperListener
79
- id = { idx }
80
- open = { open }
81
- anchorEl = { anchorEl }
82
- placement = "bottom-end"
83
- // transition
84
- >
85
- < div >
86
- < ClickAwayListener
87
- onClickAway = { handleClose }
88
- mouseEvent = "onMouseDown"
89
- touchEvent = "onTouchStart"
90
- >
91
- < div >
92
- < Paper
93
- sx = { {
94
- padding : '1rem' ,
95
- paddingTop : '1.8rem' ,
96
- boxShadow : '0px 4px 8px rgba(0, 0, 0, 0.1)' ,
97
- backgroundColor : theme . palette . background . surfaces
98
- } }
99
- >
100
- { Object . keys ( filters ) . map ( ( filterColumn ) => {
101
- const options = filters [ filterColumn ] . options ;
102
- return (
103
- < div key = { filterColumn } role = "presentation" >
104
- < InputLabel id = { filters [ filterColumn ] . name } >
105
- { filters [ filterColumn ] . name }
106
- </ InputLabel >
107
- < Select
108
- defaultValue = "All"
109
- key = { filterColumn }
110
- value = { selectedFilters [ filterColumn ] }
111
- variant = { variant }
112
- onChange = { ( e : SelectChangeEvent < unknown > ) =>
113
- handleFilterChange (
114
- e as React . ChangeEvent < { value : string } > ,
115
- filterColumn
116
- )
117
- }
118
- style = { {
119
- width : '15rem' ,
120
- marginBottom : '1rem'
121
- } }
122
- inputProps = { { 'aria-label' : 'Without label' } }
123
- displayEmpty
124
- >
125
- { showAllOption && < MenuItem value = "All" > All</ MenuItem > }
126
- { options . map ( ( option ) => (
127
- < MenuItem key = { option . value } value = { option . value } >
128
- { option . label }
129
- </ MenuItem >
130
- ) ) }
131
- </ Select >
132
- </ div >
133
- ) ;
134
- } ) }
135
-
136
- < div style = { { display : 'flex' , justifyContent : 'flex-end' } } >
137
- < Button variant = "contained" onClick = { handleApplyOnClick } >
138
- Apply
139
- </ Button >
140
- </ div >
141
- </ Paper >
142
- </ div >
120
+ { ! isMobile ? (
121
+ < PopperListener
122
+ id = { open && anchorEl ? 'transition-popper' : undefined }
123
+ open = { open }
124
+ anchorEl = { anchorEl }
125
+ placement = "bottom-end"
126
+ >
127
+ < ClickAwayListener onClickAway = { handleClose } >
128
+ < Paper
129
+ sx = { {
130
+ padding : '1rem' ,
131
+ paddingTop : '1.8rem' ,
132
+ boxShadow : '0px 4px 8px rgba(0, 0, 0, 0.1)' ,
133
+ backgroundColor : theme . palette . background . surfaces
134
+ } }
135
+ >
136
+ { renderFilterContent ( ) }
137
+ </ Paper >
143
138
</ ClickAwayListener >
144
- </ div >
145
- </ PopperListener >
139
+ </ PopperListener >
140
+ ) : (
141
+ < Drawer
142
+ anchor = "bottom"
143
+ open = { open }
144
+ onClose = { handleClose }
145
+ PaperProps = { {
146
+ style : { borderTopLeftRadius : '1rem' , borderTopRightRadius : '1rem' }
147
+ } }
148
+ >
149
+ { renderFilterContent ( ) }
150
+ </ Drawer >
151
+ ) }
146
152
</ div >
147
- </ React . Fragment >
153
+ </ >
148
154
) ;
149
155
}
150
156
export default UniversalFilter ;
0 commit comments