@campxdev/react-blueprint 1.7.12 → 1.7.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/App.tsx +6 -2
- package/src/components/Assets/Icons/IconComponents/ExportIcon.tsx +23 -29
- package/src/components/DataDisplay/AccordionGroup/AccordionGroup.tsx +1 -0
- package/src/components/DataDisplay/Card/Card.tsx +1 -1
- package/src/components/Input/FileUpload/FileUpload.tsx +28 -17
- package/src/components/Layout/PageHeader/PageHeader.tsx +30 -2
- package/src/components/Layout/PageHeader/components/ManageFilters/ManageFilters.tsx +172 -0
- package/src/components/Navigation/DropDownMenu/DropDownMenu.tsx +4 -3
- package/src/components/Navigation/TabsContainer/TabsContainer.tsx +18 -3
- package/src/components/Navigation/export.ts +0 -1
- package/src/stories/Navigation/FileUpload.stories.tsx +43 -0
- package/src/components/Navigation/ManageFilters/ManageFilters.tsx +0 -130
package/package.json
CHANGED
package/src/App.tsx
CHANGED
|
@@ -27,9 +27,13 @@ function App() {
|
|
|
27
27
|
}}
|
|
28
28
|
>
|
|
29
29
|
<FormControlWrapper control={control}>
|
|
30
|
-
<FileUpload
|
|
30
|
+
<FileUpload
|
|
31
|
+
label={'Files'}
|
|
32
|
+
name="daaku"
|
|
33
|
+
files={watch().daaku}
|
|
34
|
+
required
|
|
35
|
+
/>
|
|
31
36
|
</FormControlWrapper>
|
|
32
|
-
<Button onClick={handleSubmit(onSubmit)}>Submit</Button>
|
|
33
37
|
</div>
|
|
34
38
|
);
|
|
35
39
|
}
|
|
@@ -15,36 +15,30 @@ export const ExportIcon = ({
|
|
|
15
15
|
return (
|
|
16
16
|
<>
|
|
17
17
|
<svg
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
...sx,
|
|
24
|
-
}}
|
|
18
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
19
|
+
width="25"
|
|
20
|
+
height="24"
|
|
21
|
+
viewBox="0 0 25 24"
|
|
22
|
+
fill="none"
|
|
25
23
|
>
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
strokeWidth="0.5"
|
|
45
|
-
/>
|
|
46
|
-
</g>
|
|
47
|
-
</g>
|
|
24
|
+
<path
|
|
25
|
+
d="M15.5105 22.2501H8.99047C4.08047 22.2501 1.98047 20.1501 1.98047 15.2401V15.1101C1.98047 10.6701 3.73047 8.53009 7.65047 8.15809C7.84833 8.1444 8.04387 8.20739 8.19655 8.334C8.34922 8.4606 8.44731 8.64111 8.47047 8.83809C8.47997 8.93664 8.46988 9.03609 8.4408 9.13073C8.41172 9.22536 8.36422 9.31332 8.30102 9.38953C8.23782 9.46573 8.16018 9.5287 8.07256 9.57479C7.98494 9.62088 7.88907 9.64919 7.79047 9.65809C4.65047 9.94809 3.48047 11.4281 3.48047 15.1181V15.2481C3.48047 19.3181 4.92047 20.7581 8.99047 20.7581H15.5105C19.5805 20.7581 21.0205 19.3181 21.0205 15.2481V15.1181C21.0205 11.4081 19.8305 9.92809 16.6305 9.65809C16.5311 9.65155 16.4341 9.62524 16.345 9.58071C16.256 9.53617 16.1767 9.4743 16.1119 9.39873C16.047 9.32315 15.9979 9.2354 15.9675 9.1406C15.937 9.04581 15.9258 8.94589 15.9344 8.84669C15.9431 8.7475 15.9714 8.65103 16.0179 8.56295C16.0643 8.47486 16.1278 8.39693 16.2048 8.33373C16.2817 8.27052 16.3705 8.22332 16.4659 8.19487C16.5613 8.16643 16.6615 8.15733 16.7605 8.16809C20.7405 8.50809 22.5205 10.6581 22.5205 15.1281V15.2581C22.5205 20.1501 20.4205 22.2501 15.5105 22.2501Z"
|
|
26
|
+
fill="#121212"
|
|
27
|
+
stroke="#121212"
|
|
28
|
+
stroke-width="0.4"
|
|
29
|
+
/>
|
|
30
|
+
<path
|
|
31
|
+
d="M12.25 15.7501C12.0515 15.7488 11.8615 15.6694 11.7211 15.529C11.5807 15.3886 11.5013 15.1986 11.5 15.0001V3.62012C11.5013 3.42161 11.5807 3.2316 11.7211 3.09124C11.8615 2.95087 12.0515 2.87143 12.25 2.87012C12.4485 2.87143 12.6385 2.95087 12.7789 3.09124C12.9193 3.2316 12.9987 3.42161 13 3.62012V15.0001C12.9987 15.1986 12.9193 15.3886 12.7789 15.529C12.6385 15.6694 12.4485 15.7488 12.25 15.7501Z"
|
|
32
|
+
fill="#121212"
|
|
33
|
+
stroke="#121212"
|
|
34
|
+
stroke-width="0.4"
|
|
35
|
+
/>
|
|
36
|
+
<path
|
|
37
|
+
d="M15.6012 6.60012C15.5026 6.60047 15.405 6.5812 15.314 6.54343C15.223 6.50566 15.1405 6.45014 15.0712 6.38012L12.2532 3.56012L9.43317 6.38012C9.29099 6.5126 9.10295 6.58472 8.90864 6.58129C8.71434 6.57787 8.52896 6.49915 8.39155 6.36174C8.25413 6.22433 8.17542 6.03894 8.17199 5.84464C8.16856 5.65034 8.24069 5.46229 8.37317 5.32012L11.7212 1.97112C11.8623 1.83164 12.0527 1.75342 12.2512 1.75342C12.4496 1.75342 12.64 1.83164 12.7812 1.97112L16.1312 5.32112C16.2706 5.46226 16.3489 5.65269 16.3489 5.85112C16.3489 6.04955 16.2706 6.23998 16.1312 6.38112C16.0624 6.45175 15.9799 6.50759 15.8887 6.54525C15.7976 6.5829 15.6998 6.60157 15.6012 6.60012Z"
|
|
38
|
+
fill="#121212"
|
|
39
|
+
stroke="#121212"
|
|
40
|
+
stroke-width="0.4"
|
|
41
|
+
/>
|
|
48
42
|
</svg>
|
|
49
43
|
</>
|
|
50
44
|
);
|
|
@@ -5,8 +5,10 @@ import {
|
|
|
5
5
|
styled,
|
|
6
6
|
SxProps,
|
|
7
7
|
useTheme,
|
|
8
|
+
useMediaQuery,
|
|
8
9
|
} from '@mui/material';
|
|
9
10
|
import { IconButtons, Icons, PreviewFiles, Typography } from '../../export';
|
|
11
|
+
import { alpha } from '@mui/system';
|
|
10
12
|
|
|
11
13
|
export type FileUploadProps = {
|
|
12
14
|
label: string;
|
|
@@ -24,6 +26,7 @@ export type FileUploadProps = {
|
|
|
24
26
|
sx?: SxProps;
|
|
25
27
|
showImage?: boolean;
|
|
26
28
|
previewSx?: SxProps;
|
|
29
|
+
required?: boolean;
|
|
27
30
|
};
|
|
28
31
|
|
|
29
32
|
export const FileUpload = ({
|
|
@@ -42,8 +45,10 @@ export const FileUpload = ({
|
|
|
42
45
|
showImage,
|
|
43
46
|
previewSx,
|
|
44
47
|
sx,
|
|
48
|
+
required,
|
|
45
49
|
}: FileUploadProps) => {
|
|
46
50
|
const theme = useTheme();
|
|
51
|
+
const isSmallScreen = useMediaQuery(theme.breakpoints.down(768));
|
|
47
52
|
|
|
48
53
|
if (!onChange) {
|
|
49
54
|
return <Typography>onChange Missing</Typography>;
|
|
@@ -81,7 +86,14 @@ export const FileUpload = ({
|
|
|
81
86
|
|
|
82
87
|
return (
|
|
83
88
|
<Stack sx={sx}>
|
|
84
|
-
<Typography variant="label1">
|
|
89
|
+
<Typography variant="label1">
|
|
90
|
+
{label}{' '}
|
|
91
|
+
{required && (
|
|
92
|
+
<span style={{ color: `${theme.palette.tertiary.main}` }}>
|
|
93
|
+
{' *'}
|
|
94
|
+
</span>
|
|
95
|
+
)}
|
|
96
|
+
</Typography>{' '}
|
|
85
97
|
<input
|
|
86
98
|
accept={accept}
|
|
87
99
|
style={{ display: 'none' }}
|
|
@@ -92,19 +104,11 @@ export const FileUpload = ({
|
|
|
92
104
|
disabled={disabled}
|
|
93
105
|
onChange={handleFileChange}
|
|
94
106
|
/>
|
|
95
|
-
|
|
96
107
|
<FormLabel htmlFor={name}>
|
|
97
108
|
<StyledFileSelectorContainer>
|
|
98
109
|
<Stack display={'flex'} alignItems={'center'}>
|
|
99
110
|
<Icons.ExportIcon size={20} />
|
|
100
|
-
<Typography
|
|
101
|
-
color={
|
|
102
|
-
disabled
|
|
103
|
-
? theme.palette.secondary.dark
|
|
104
|
-
: theme.palette.primary.main
|
|
105
|
-
}
|
|
106
|
-
variant="label2"
|
|
107
|
-
>
|
|
111
|
+
<Typography color={theme.palette.text.tertiary} variant="label2">
|
|
108
112
|
{inputText ?? 'Upload Files'}
|
|
109
113
|
</Typography>
|
|
110
114
|
</Stack>
|
|
@@ -123,11 +127,13 @@ export const FileUpload = ({
|
|
|
123
127
|
</Typography>
|
|
124
128
|
)}
|
|
125
129
|
</FormLabel>
|
|
126
|
-
|
|
127
130
|
<Box display="flex" gap="12px" flexWrap="wrap">
|
|
128
131
|
{showImage ? (
|
|
129
132
|
files.map((file, index) => (
|
|
130
|
-
<StyledSelectedFileContainer
|
|
133
|
+
<StyledSelectedFileContainer
|
|
134
|
+
key={index}
|
|
135
|
+
isSmallScreen={isSmallScreen}
|
|
136
|
+
>
|
|
131
137
|
<Box
|
|
132
138
|
sx={{
|
|
133
139
|
height: '120px',
|
|
@@ -183,13 +189,15 @@ export const FileUpload = ({
|
|
|
183
189
|
);
|
|
184
190
|
};
|
|
185
191
|
|
|
186
|
-
const StyledSelectedFileContainer = styled(Box
|
|
192
|
+
const StyledSelectedFileContainer = styled(Box, {
|
|
193
|
+
shouldForwardProp: (prop) => prop !== 'isSmallScreen',
|
|
194
|
+
})<{ isSmallScreen: boolean }>(({ theme, isSmallScreen }) => ({
|
|
187
195
|
borderRadius: '10px',
|
|
188
196
|
position: 'relative',
|
|
189
|
-
flex: '1 1 auto',
|
|
190
197
|
textAlign: 'center',
|
|
191
198
|
marginTop: '5px',
|
|
192
|
-
minWidth: '
|
|
199
|
+
minWidth: isSmallScreen ? '100%' : '300px', // Full width on small screens, 300px on larger
|
|
200
|
+
maxWidth: '100%',
|
|
193
201
|
'& > button': {
|
|
194
202
|
position: 'absolute',
|
|
195
203
|
right: '-4%',
|
|
@@ -198,14 +206,17 @@ const StyledSelectedFileContainer = styled(Box)(({ theme }) => ({
|
|
|
198
206
|
}));
|
|
199
207
|
|
|
200
208
|
const StyledFileSelectorContainer = styled(Box)(({ theme }) => ({
|
|
201
|
-
border: '
|
|
209
|
+
border: '2.5px dashed',
|
|
202
210
|
height: '120px',
|
|
203
211
|
display: 'flex',
|
|
204
212
|
width: '100%',
|
|
213
|
+
minWidth: '200px',
|
|
205
214
|
borderRadius: '5px',
|
|
206
|
-
borderColor: theme.palette.primary
|
|
215
|
+
borderColor: theme.palette.border.primary,
|
|
207
216
|
justifyContent: 'center',
|
|
208
217
|
alignItems: 'center',
|
|
218
|
+
padding: '8px',
|
|
219
|
+
textAlign: 'center',
|
|
209
220
|
'&:hover': {
|
|
210
221
|
borderColor: theme.palette.primary.light,
|
|
211
222
|
backgroundColor: theme.palette.secondary.light,
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
Typography,
|
|
19
19
|
} from '../../export';
|
|
20
20
|
import { FiltersAnchor } from './components/Anchors';
|
|
21
|
+
import { ManageFilters } from './components/ManageFilters/ManageFilters';
|
|
21
22
|
import { SearchBar } from './components/SearchBar';
|
|
22
23
|
|
|
23
24
|
interface PageHeaderProps {
|
|
@@ -64,6 +65,8 @@ export const PageHeader = ({
|
|
|
64
65
|
}: PageHeaderProps) => {
|
|
65
66
|
const [expanded, setExpanded] = useState(false);
|
|
66
67
|
|
|
68
|
+
const [hiddenLabels, setHiddenLabels] = useState<string[]>([]);
|
|
69
|
+
|
|
67
70
|
const dispatch = useDispatch();
|
|
68
71
|
|
|
69
72
|
const wrapProps = (element: ReactElement): ReactElement => {
|
|
@@ -100,6 +103,10 @@ export const PageHeader = ({
|
|
|
100
103
|
|
|
101
104
|
const isTableMode = columns && uniqueId;
|
|
102
105
|
|
|
106
|
+
const finalFilterComponents = filterComponents.filter(
|
|
107
|
+
(filter) => !hiddenLabels.includes(filter.props['label']),
|
|
108
|
+
);
|
|
109
|
+
|
|
103
110
|
return (
|
|
104
111
|
<motion.div
|
|
105
112
|
style={{
|
|
@@ -149,10 +156,10 @@ export const PageHeader = ({
|
|
|
149
156
|
)}
|
|
150
157
|
{expanded && (
|
|
151
158
|
<Stack direction="row" width="100%" alignItems="center" gap={2}>
|
|
152
|
-
{
|
|
159
|
+
{finalFilterComponents.map((filter, index) => (
|
|
153
160
|
<Fragment key={index}>
|
|
154
161
|
{wrapProps(filter)}
|
|
155
|
-
{index <
|
|
162
|
+
{index < finalFilterComponents.length - 1 && (
|
|
156
163
|
<Divider
|
|
157
164
|
orientation="vertical"
|
|
158
165
|
style={{
|
|
@@ -163,6 +170,27 @@ export const PageHeader = ({
|
|
|
163
170
|
)}
|
|
164
171
|
</Fragment>
|
|
165
172
|
))}
|
|
173
|
+
<ManageFilters
|
|
174
|
+
filterLabels={filterComponents.map((filter) => {
|
|
175
|
+
return filter.props['label'] || 'Label Not Found';
|
|
176
|
+
})}
|
|
177
|
+
selectedFilterLabels={finalFilterComponents.map(
|
|
178
|
+
(filter) => filter.props['label'] || 'Label Not Found',
|
|
179
|
+
)}
|
|
180
|
+
handleCheckboxChange={function (
|
|
181
|
+
label: string,
|
|
182
|
+
checked: boolean,
|
|
183
|
+
): void {
|
|
184
|
+
if (checked) {
|
|
185
|
+
setHiddenLabels(hiddenLabels.filter((l) => label !== l));
|
|
186
|
+
} else {
|
|
187
|
+
setHiddenLabels([...hiddenLabels, label]);
|
|
188
|
+
}
|
|
189
|
+
}}
|
|
190
|
+
handleReset={() => {
|
|
191
|
+
setHiddenLabels([]);
|
|
192
|
+
}}
|
|
193
|
+
/>
|
|
166
194
|
</Stack>
|
|
167
195
|
)}
|
|
168
196
|
</motion.div>
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MenuListProps,
|
|
3
|
+
MenuProps,
|
|
4
|
+
Stack,
|
|
5
|
+
styled,
|
|
6
|
+
Typography,
|
|
7
|
+
useTheme,
|
|
8
|
+
} from '@mui/material';
|
|
9
|
+
import { useState } from 'react';
|
|
10
|
+
import { Button, Icons, SearchBar, SingleCheckBox } from '../../../../export';
|
|
11
|
+
import { DropdownMenu } from '../../../../Navigation/export';
|
|
12
|
+
|
|
13
|
+
export type ManageFiltersProps = {
|
|
14
|
+
filterLabels: string[];
|
|
15
|
+
selectedFilterLabels: string[];
|
|
16
|
+
handleCheckboxChange: (label: string, checked: boolean) => void;
|
|
17
|
+
handleReset: () => void;
|
|
18
|
+
menuProps?: Omit<MenuProps, 'open'>;
|
|
19
|
+
menuListProps?: MenuListProps;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const FooterContainerContainer = styled(Stack)(({ theme }) => ({
|
|
23
|
+
backgroundColor: theme.palette.surface.defaultBackground,
|
|
24
|
+
borderRadius: '4px',
|
|
25
|
+
height: '40px',
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
export const ManageFiltersMenuFooter = ({
|
|
29
|
+
onClick,
|
|
30
|
+
}: {
|
|
31
|
+
onClick: () => void;
|
|
32
|
+
}) => {
|
|
33
|
+
const theme = useTheme();
|
|
34
|
+
return (
|
|
35
|
+
<FooterContainerContainer direction="row" alignItems="center">
|
|
36
|
+
<Button
|
|
37
|
+
variant="text"
|
|
38
|
+
onClick={onClick}
|
|
39
|
+
sx={{
|
|
40
|
+
fontFamily: 'Heebo',
|
|
41
|
+
minWidth: '0px',
|
|
42
|
+
margin: '0px 16px',
|
|
43
|
+
}}
|
|
44
|
+
disableRipple
|
|
45
|
+
color={theme.palette.text.tertiary}
|
|
46
|
+
>
|
|
47
|
+
Reset
|
|
48
|
+
</Button>
|
|
49
|
+
</FooterContainerContainer>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const ManageFilters = ({
|
|
54
|
+
filterLabels,
|
|
55
|
+
selectedFilterLabels,
|
|
56
|
+
handleCheckboxChange,
|
|
57
|
+
handleReset,
|
|
58
|
+
...props
|
|
59
|
+
}: ManageFiltersProps) => {
|
|
60
|
+
const theme = useTheme();
|
|
61
|
+
const [search, setSearch] = useState<string>('');
|
|
62
|
+
|
|
63
|
+
const filteredOptions = filterLabels.filter((label) =>
|
|
64
|
+
label.toLowerCase().includes(search.toLowerCase()),
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<DropdownMenu
|
|
69
|
+
menuListProps={{
|
|
70
|
+
sx: {
|
|
71
|
+
padding: '0px',
|
|
72
|
+
width: '250px',
|
|
73
|
+
},
|
|
74
|
+
...props.menuListProps,
|
|
75
|
+
}}
|
|
76
|
+
anchor={({ open }: { open: (e: any) => void }) => (
|
|
77
|
+
<Button onClick={open} sx={{ gap: '1px' }} variant="text">
|
|
78
|
+
{<Icons.ConfigureIcon />} Manage Filters
|
|
79
|
+
</Button>
|
|
80
|
+
)}
|
|
81
|
+
menuProps={{
|
|
82
|
+
...props.menuProps,
|
|
83
|
+
anchorOrigin: {
|
|
84
|
+
vertical: 'bottom',
|
|
85
|
+
horizontal: 'left',
|
|
86
|
+
},
|
|
87
|
+
transformOrigin: {
|
|
88
|
+
vertical: 'top',
|
|
89
|
+
horizontal: 'left',
|
|
90
|
+
},
|
|
91
|
+
}}
|
|
92
|
+
menuHeader={
|
|
93
|
+
<SearchBar
|
|
94
|
+
fullWidth
|
|
95
|
+
size="small"
|
|
96
|
+
placeholder="Search"
|
|
97
|
+
onSearch={(value) => {
|
|
98
|
+
setSearch(value);
|
|
99
|
+
}}
|
|
100
|
+
/>
|
|
101
|
+
}
|
|
102
|
+
menuListContainerSx={{
|
|
103
|
+
margin: '12px 12px 0px 12px',
|
|
104
|
+
gap: 0,
|
|
105
|
+
maxHeight: '310px',
|
|
106
|
+
overflowY: 'scroll',
|
|
107
|
+
}}
|
|
108
|
+
menu={filteredOptions.map((item, index) => (
|
|
109
|
+
<SingleCheckBox
|
|
110
|
+
key={index}
|
|
111
|
+
formControlLabelProps={{
|
|
112
|
+
labelPlacement: 'start',
|
|
113
|
+
sx: {
|
|
114
|
+
display: 'flex',
|
|
115
|
+
justifyContent: 'space-between',
|
|
116
|
+
margin: '0px',
|
|
117
|
+
width: '100%',
|
|
118
|
+
'.MuiFormControlLabel-label': {
|
|
119
|
+
width: '100%',
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
}}
|
|
123
|
+
icon={<Icons.VisibilityOffIcon />}
|
|
124
|
+
checkedIcon={<Icons.VisibilityIcon />}
|
|
125
|
+
checked={selectedFilterLabels.includes(item)}
|
|
126
|
+
label={
|
|
127
|
+
<Typography
|
|
128
|
+
color={
|
|
129
|
+
!selectedFilterLabels.includes(item)
|
|
130
|
+
? theme.palette.text.tertiary
|
|
131
|
+
: theme.palette.text.primary
|
|
132
|
+
}
|
|
133
|
+
variant="subtitle3"
|
|
134
|
+
>
|
|
135
|
+
{item}
|
|
136
|
+
</Typography>
|
|
137
|
+
}
|
|
138
|
+
onChange={(e) => {
|
|
139
|
+
handleCheckboxChange(item, e.target.checked);
|
|
140
|
+
}}
|
|
141
|
+
/>
|
|
142
|
+
))}
|
|
143
|
+
menuFooter={<ManageFiltersMenuFooter onClick={handleReset} />}
|
|
144
|
+
/>
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// const FilterAnchorContainer = styled(Box)(({ theme }) => ({
|
|
149
|
+
// height: '40px',
|
|
150
|
+
// width: '40px',
|
|
151
|
+
// backgroundColor: theme.palette.secondary.main,
|
|
152
|
+
// borderRadius: '5px',
|
|
153
|
+
// display: 'flex',
|
|
154
|
+
// alignItems: 'center',
|
|
155
|
+
// justifyContent: 'center',
|
|
156
|
+
// }));
|
|
157
|
+
|
|
158
|
+
/* <DropDownIcon
|
|
159
|
+
icon={{
|
|
160
|
+
icon: (
|
|
161
|
+
<Badge
|
|
162
|
+
overlap="circular"
|
|
163
|
+
variant={values.length > 0 ? 'dot' : 'standard'}
|
|
164
|
+
>
|
|
165
|
+
<FilterAnchorContainer>
|
|
166
|
+
<FilterViewIcon />
|
|
167
|
+
</FilterAnchorContainer>
|
|
168
|
+
</Badge>
|
|
169
|
+
),
|
|
170
|
+
}}
|
|
171
|
+
handleClick={open}
|
|
172
|
+
/>; */
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
StackProps,
|
|
8
8
|
useTheme,
|
|
9
9
|
} from '@mui/material';
|
|
10
|
-
import {
|
|
10
|
+
import { ReactNode, useState } from 'react';
|
|
11
11
|
|
|
12
12
|
export type DropdownMenuProps = {
|
|
13
13
|
anchor: (props: { open: (e: any) => void }) => ReactNode;
|
|
@@ -73,6 +73,7 @@ export const DropdownMenu = ({
|
|
|
73
73
|
}}
|
|
74
74
|
MenuListProps={{
|
|
75
75
|
...menuListProps,
|
|
76
|
+
// sx: { padding: '0px' },
|
|
76
77
|
}}
|
|
77
78
|
{...menuProps}
|
|
78
79
|
>
|
|
@@ -96,12 +97,12 @@ export const DropdownMenu = ({
|
|
|
96
97
|
{useMenuSlot && menuSlot
|
|
97
98
|
? menuSlot({ close: handleClose })
|
|
98
99
|
: menuItems.map((item, index) => (
|
|
99
|
-
<
|
|
100
|
+
<div key={index}>
|
|
100
101
|
{item}
|
|
101
102
|
{index < menuItems.length - 1 && (
|
|
102
103
|
<Divider flexItem sx={{ margin: '0 !important' }} />
|
|
103
104
|
)}
|
|
104
|
-
</
|
|
105
|
+
</div>
|
|
105
106
|
))}
|
|
106
107
|
</Stack>
|
|
107
108
|
{menuFooter}
|
|
@@ -12,6 +12,7 @@ export interface TabsContainerProps {
|
|
|
12
12
|
onTabChange?: (tabKey: string) => void;
|
|
13
13
|
currentTabIndex?: number;
|
|
14
14
|
tabsProps: TabsProps;
|
|
15
|
+
variant?: 'fixed' | 'dynamic';
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
const TabContent = styled(Box)(({ theme }) => ({
|
|
@@ -27,11 +28,19 @@ const TabContent = styled(Box)(({ theme }) => ({
|
|
|
27
28
|
},
|
|
28
29
|
}));
|
|
29
30
|
|
|
31
|
+
const DynamicContent = styled(Box)(({ theme }) => ({
|
|
32
|
+
width: '100%',
|
|
33
|
+
height: 'max-content',
|
|
34
|
+
backgroundColor: theme.palette.surface.paperBackground,
|
|
35
|
+
'&::-webkit-scrollbar': { display: 'none' },
|
|
36
|
+
}));
|
|
37
|
+
|
|
30
38
|
export const TabsContainer = ({
|
|
31
39
|
tabs,
|
|
32
40
|
onTabChange,
|
|
33
41
|
currentTabIndex = 0,
|
|
34
42
|
tabsProps,
|
|
43
|
+
variant = 'fixed',
|
|
35
44
|
}: TabsContainerProps) => {
|
|
36
45
|
const [currentTab, setCurrentTab] = useState(tabs[currentTabIndex]?.key);
|
|
37
46
|
|
|
@@ -67,9 +76,15 @@ export const TabsContainer = ({
|
|
|
67
76
|
/>
|
|
68
77
|
))}
|
|
69
78
|
</Tabs>
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
79
|
+
{variant === 'fixed' ? (
|
|
80
|
+
<TabContent>
|
|
81
|
+
{tabs.find((tab) => tab?.key === currentTab)?.component}
|
|
82
|
+
</TabContent>
|
|
83
|
+
) : (
|
|
84
|
+
<DynamicContent>
|
|
85
|
+
{tabs.find((tab) => tab?.key === currentTab)?.component}
|
|
86
|
+
</DynamicContent>
|
|
87
|
+
)}
|
|
73
88
|
</>
|
|
74
89
|
);
|
|
75
90
|
};
|
|
@@ -7,7 +7,6 @@ export * from './DropDownMenu/DropDownButton';
|
|
|
7
7
|
export * from './DropDownMenu/DropDownIcon';
|
|
8
8
|
export * from './DropDownMenu/DropDownMenu';
|
|
9
9
|
export * from './DropDownMenu/DropdownMenuItem';
|
|
10
|
-
export * from './ManageFilters/ManageFilters';
|
|
11
10
|
export * from './PreviewFiles/PreviewFiles';
|
|
12
11
|
export * from './Sidebar/Sidebar';
|
|
13
12
|
export * from './Stepper/Stepper';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { action } from '@storybook/addon-actions';
|
|
2
|
+
import { StoryFn } from '@storybook/react/*';
|
|
3
|
+
import { FileUpload, FileUploadProps } from '../../components/export';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Navigation/FileUpload',
|
|
7
|
+
component: FileUpload,
|
|
8
|
+
argTypes: {
|
|
9
|
+
onChange: { action: 'onChange' },
|
|
10
|
+
handleRemove: { action: 'handleRemove' },
|
|
11
|
+
onInvalidFile: { action: 'onInvalidFile' },
|
|
12
|
+
label: { control: 'text' },
|
|
13
|
+
accept: { control: 'text' },
|
|
14
|
+
disabled: { control: 'boolean' },
|
|
15
|
+
multiple: { control: 'boolean' },
|
|
16
|
+
hideDeleteButton: { control: 'boolean' },
|
|
17
|
+
showImage: { control: 'boolean' },
|
|
18
|
+
errorText: { control: 'text' },
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const Template: StoryFn<FileUploadProps> = (args: any) => (
|
|
23
|
+
<FileUpload {...args} />
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
export const Default = Template.bind({});
|
|
27
|
+
Default.args = {
|
|
28
|
+
label: 'Upload File',
|
|
29
|
+
files: [],
|
|
30
|
+
onChange: action('onChange'),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const Disabled = Template.bind({});
|
|
34
|
+
Disabled.args = {
|
|
35
|
+
...Default.args,
|
|
36
|
+
disabled: true,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const AcceptOnlyPDF = Template.bind({});
|
|
40
|
+
AcceptOnlyPDF.args = {
|
|
41
|
+
...Default.args,
|
|
42
|
+
accept: '.pdf',
|
|
43
|
+
};
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { MenuListProps, MenuProps, Typography } from '@mui/material';
|
|
2
|
-
import { ReactNode, useState } from 'react';
|
|
3
|
-
import { Button, Icons, SearchBar, SingleCheckBox } from '../../export';
|
|
4
|
-
import { DropdownMenu } from '../export';
|
|
5
|
-
|
|
6
|
-
type Options = {
|
|
7
|
-
label: string;
|
|
8
|
-
value: ReactNode;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export type ManageFiltersProps = {
|
|
12
|
-
options: Options[];
|
|
13
|
-
onChange: (values: ReactNode[]) => void;
|
|
14
|
-
menuProps?: Omit<MenuProps, 'open'>;
|
|
15
|
-
menuListProps?: MenuListProps;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export const ManageFilters = ({
|
|
19
|
-
options,
|
|
20
|
-
onChange,
|
|
21
|
-
...props
|
|
22
|
-
}: ManageFiltersProps) => {
|
|
23
|
-
const [values, setValues] = useState<Options[]>([]);
|
|
24
|
-
const [search, setSearch] = useState<string>('');
|
|
25
|
-
|
|
26
|
-
const filteredOptions = options.filter((option) =>
|
|
27
|
-
option.label.toLowerCase().includes(search.toLowerCase()),
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
const handleCheckboxChange = (
|
|
31
|
-
value: ReactNode,
|
|
32
|
-
label: string,
|
|
33
|
-
checked: boolean,
|
|
34
|
-
) => {
|
|
35
|
-
const updatedValues = checked
|
|
36
|
-
? [...values, { label, value }]
|
|
37
|
-
: values.filter((v) => v.label !== label);
|
|
38
|
-
setValues(updatedValues);
|
|
39
|
-
onChange(updatedValues.map((v) => v.value));
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<DropdownMenu
|
|
44
|
-
menuListProps={{
|
|
45
|
-
sx: {
|
|
46
|
-
padding: '12px',
|
|
47
|
-
width: '250px',
|
|
48
|
-
},
|
|
49
|
-
...props.menuListProps,
|
|
50
|
-
}}
|
|
51
|
-
anchor={({ open }: { open: (e: any) => void }) => (
|
|
52
|
-
<Button onClick={open} sx={{ gap: '1px' }} variant="text">
|
|
53
|
-
{<Icons.ConfigureIcon />} Manage Filters
|
|
54
|
-
</Button>
|
|
55
|
-
)}
|
|
56
|
-
menuProps={{
|
|
57
|
-
...props.menuProps,
|
|
58
|
-
anchorOrigin: {
|
|
59
|
-
vertical: 'bottom',
|
|
60
|
-
horizontal: 'left',
|
|
61
|
-
},
|
|
62
|
-
transformOrigin: {
|
|
63
|
-
vertical: 'top',
|
|
64
|
-
horizontal: 'left',
|
|
65
|
-
},
|
|
66
|
-
}}
|
|
67
|
-
menuHeader={
|
|
68
|
-
<SearchBar
|
|
69
|
-
fullWidth
|
|
70
|
-
size="small"
|
|
71
|
-
placeholder="Search"
|
|
72
|
-
onSearch={(value) => {
|
|
73
|
-
setSearch(value);
|
|
74
|
-
}}
|
|
75
|
-
/>
|
|
76
|
-
}
|
|
77
|
-
menuListContainerSx={{
|
|
78
|
-
margin: '10px 5px 0px 5px',
|
|
79
|
-
gap: 1,
|
|
80
|
-
maxHeight: '350px',
|
|
81
|
-
}}
|
|
82
|
-
menu={filteredOptions.map((item, index) => (
|
|
83
|
-
<SingleCheckBox
|
|
84
|
-
key={index}
|
|
85
|
-
formControlLabelProps={{
|
|
86
|
-
labelPlacement: 'start',
|
|
87
|
-
sx: {
|
|
88
|
-
display: 'flex',
|
|
89
|
-
justifyContent: 'space-between',
|
|
90
|
-
marginLeft: '0px',
|
|
91
|
-
},
|
|
92
|
-
}}
|
|
93
|
-
icon={<Icons.VisibilityIcon />}
|
|
94
|
-
checkedIcon={<Icons.VisibilityOffIcon />}
|
|
95
|
-
checked={values.map((s) => s.label).includes(item.label)}
|
|
96
|
-
label={<Typography variant="subtitle3">{item.label}</Typography>}
|
|
97
|
-
onChange={(e) => {
|
|
98
|
-
handleCheckboxChange(item.value, item.label, e.target.checked);
|
|
99
|
-
}}
|
|
100
|
-
/>
|
|
101
|
-
))}
|
|
102
|
-
/>
|
|
103
|
-
);
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
// const FilterAnchorContainer = styled(Box)(({ theme }) => ({
|
|
107
|
-
// height: '40px',
|
|
108
|
-
// width: '40px',
|
|
109
|
-
// backgroundColor: theme.palette.secondary.main,
|
|
110
|
-
// borderRadius: '5px',
|
|
111
|
-
// display: 'flex',
|
|
112
|
-
// alignItems: 'center',
|
|
113
|
-
// justifyContent: 'center',
|
|
114
|
-
// }));
|
|
115
|
-
|
|
116
|
-
/* <DropDownIcon
|
|
117
|
-
icon={{
|
|
118
|
-
icon: (
|
|
119
|
-
<Badge
|
|
120
|
-
overlap="circular"
|
|
121
|
-
variant={values.length > 0 ? 'dot' : 'standard'}
|
|
122
|
-
>
|
|
123
|
-
<FilterAnchorContainer>
|
|
124
|
-
<FilterViewIcon />
|
|
125
|
-
</FilterAnchorContainer>
|
|
126
|
-
</Badge>
|
|
127
|
-
),
|
|
128
|
-
}}
|
|
129
|
-
handleClick={open}
|
|
130
|
-
/>; */
|