Skip to content

Commit 79989ff

Browse files
committed
chore: create catalog filter section component
Signed-off-by: Amit Amrutiya <amitamrutiya2210@gmail.com>
1 parent 623fd12 commit 79989ff

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
2+
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
3+
import { useCallback, useState } from 'react';
4+
import {
5+
Box,
6+
Checkbox,
7+
Collapse,
8+
InputAdornment,
9+
List,
10+
OutlinedInput,
11+
Stack,
12+
Typography
13+
} from '../../base';
14+
import { SearchIcon } from '../../icons';
15+
import { InfoTooltip } from '../CustomTooltip';
16+
import { FilterOption, FilterValues, StyleProps } from './CatalogFilterSidebar';
17+
import { FilterTitleButton, InputAdornmentEnd } from './style';
18+
19+
interface FilterSectionProps {
20+
filterKey: string;
21+
sectionDisplayName?: string;
22+
options: FilterOption[];
23+
filters: FilterValues;
24+
openSections: Record<string, boolean>;
25+
onCheckboxChange: (filterKey: string, value: string, checked: boolean) => void;
26+
onSectionToggle: (filterKey: string) => void;
27+
styleProps: StyleProps;
28+
}
29+
30+
/**
31+
* @component FilterSection
32+
* @description A functional component that renders a filter section.
33+
* @param {string} filterKey - The key of the filter section.
34+
* @param {string} sectionDisplayName - The title of the filter section.
35+
* @param {Array} options - The available options for the filter section.
36+
* @param {Object} filters - The selected filters.
37+
* @param {Object} openSections - The open/closed state of the filter sections.
38+
* @param {Function} onCheckboxChange - A function to handle checkbox change event.
39+
* @param {Function} onSectionToggle - A function to handle section toggle event.
40+
* @param {Object} styleProps - The style properties for the component.
41+
*/
42+
const FilterSection: React.FC<FilterSectionProps> = ({
43+
filterKey,
44+
sectionDisplayName,
45+
options,
46+
filters,
47+
openSections,
48+
onCheckboxChange,
49+
onSectionToggle,
50+
styleProps
51+
}) => {
52+
const [searchQuery, setSearchQuery] = useState<string>('');
53+
54+
const handleTextFieldChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
55+
setSearchQuery(e.target.value);
56+
}, []);
57+
58+
const showSearch = options.length > 10;
59+
const searchedOptions = searchQuery
60+
? options.filter((option) => option.label.toLowerCase().includes(searchQuery.toLowerCase()))
61+
: options;
62+
63+
return (
64+
<>
65+
<FilterTitleButton
66+
onClick={() => onSectionToggle(filterKey)}
67+
style={{ backgroundColor: styleProps.sectionTitleBackgroundColor }}
68+
>
69+
<Typography variant="h6" fontWeight="bold">
70+
{(sectionDisplayName || filterKey).toUpperCase()}
71+
</Typography>
72+
{openSections[filterKey] ? <ExpandLessIcon /> : <ExpandMoreIcon />}
73+
</FilterTitleButton>
74+
<Collapse in={openSections[filterKey]} timeout="auto" unmountOnExit>
75+
<List
76+
component="div"
77+
sx={{
78+
overflowY: 'auto',
79+
maxHeight: '25rem',
80+
backgroundColor: styleProps.backgroundColor
81+
}}
82+
>
83+
{showSearch && (
84+
<Box px={'0.5rem'}>
85+
<OutlinedInput
86+
type="search"
87+
fullWidth
88+
placeholder="Search "
89+
value={searchQuery}
90+
onChange={handleTextFieldChange}
91+
startAdornment={
92+
<InputAdornment position="start">
93+
<SearchIcon />
94+
</InputAdornment>
95+
}
96+
endAdornment={
97+
<InputAdornmentEnd position="end">
98+
Total: {searchedOptions.length}
99+
</InputAdornmentEnd>
100+
}
101+
/>
102+
</Box>
103+
)}
104+
{searchedOptions.map((option, index) => (
105+
<Stack
106+
key={`${option.value}-${index}`}
107+
direction="row"
108+
alignItems="center"
109+
px={'0.5rem'}
110+
justifyContent="space-between"
111+
>
112+
<Stack direction="row" alignItems="center" gap="0.35rem">
113+
<Checkbox
114+
id={`checkbox-${option.label}`}
115+
checked={
116+
Array.isArray(filters[filterKey])
117+
? (filters[filterKey] as string[]).includes(option.value)
118+
: filters[filterKey] === option.value
119+
}
120+
onChange={(e) => onCheckboxChange(filterKey, option.value, e.target.checked)}
121+
value={option.value}
122+
/>
123+
124+
{option.Icon && <option.Icon width="20px" height="20px" />}
125+
126+
<Typography>{option.label}</Typography>
127+
</Stack>
128+
<Stack direction="row" alignItems="center" gap="0.35rem">
129+
{option.totalCount !== undefined && `(${option.totalCount || 0})`}
130+
{option.description && (
131+
<InfoTooltip variant="standard" helpText={option.description} />
132+
)}
133+
</Stack>
134+
</Stack>
135+
))}
136+
</List>
137+
</Collapse>
138+
</>
139+
);
140+
};
141+
142+
export default FilterSection;

0 commit comments

Comments
 (0)