@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@campxdev/react-blueprint",
3
- "version": "1.7.12",
3
+ "version": "1.7.13",
4
4
  "main": "./export.ts",
5
5
  "dependencies": {
6
6
  "@emotion/react": "^11.13.3",
package/src/App.tsx CHANGED
@@ -27,9 +27,13 @@ function App() {
27
27
  }}
28
28
  >
29
29
  <FormControlWrapper control={control}>
30
- <FileUpload label={'Files'} name="daaku" files={watch().daaku} />
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
- width={size}
19
- height={size}
20
- viewBox="0 0 30 30"
21
- style={{
22
- fill: color,
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
- <g id="vuesax/outline/export">
27
- <g id="export">
28
- <path
29
- id="Vector"
30
- d="M19.0746 27.8126H10.9246C4.78711 27.8126 2.16211 25.1876 2.16211 19.0501V18.8876C2.16211 13.3376 4.34961 10.6626 9.24961 10.1976C9.49694 10.1805 9.74137 10.2592 9.93221 10.4175C10.123 10.5758 10.2457 10.8014 10.2746 11.0476C10.2865 11.1708 10.2739 11.2951 10.2375 11.4134C10.2012 11.5317 10.1418 11.6416 10.0628 11.7369C9.9838 11.8322 9.88675 11.9109 9.77722 11.9685C9.6677 12.0261 9.54786 12.0615 9.42461 12.0726C5.49961 12.4351 4.03711 14.2851 4.03711 18.8976V19.0601C4.03711 24.1476 5.83711 25.9476 10.9246 25.9476H19.0746C24.1621 25.9476 25.9621 24.1476 25.9621 19.0601V18.8976C25.9621 14.2601 24.4746 12.4101 20.4746 12.0726C20.3504 12.0644 20.2291 12.0316 20.1178 11.9759C20.0065 11.9202 19.9074 11.8429 19.8263 11.7484C19.7453 11.6539 19.684 11.5442 19.6459 11.4258C19.6078 11.3073 19.5937 11.1824 19.6045 11.0584C19.6154 10.9344 19.6508 10.8138 19.7089 10.7037C19.7669 10.5936 19.8463 10.4962 19.9425 10.4172C20.0387 10.3382 20.1496 10.2791 20.2689 10.2436C20.3882 10.208 20.5134 10.1967 20.6371 10.2101C25.6121 10.6351 27.8371 13.3226 27.8371 18.9101V19.0726C27.8371 25.1876 25.2121 27.8126 19.0746 27.8126Z"
31
- stroke={color}
32
- strokeWidth="0.5"
33
- />
34
- <path
35
- id="Vector_2"
36
- d="M15 19.6879C14.7519 19.6863 14.5144 19.587 14.3389 19.4115C14.1634 19.236 14.0641 18.9985 14.0625 18.7504V4.52539C14.0641 4.27726 14.1634 4.03975 14.3389 3.86429C14.5144 3.68883 14.7519 3.58953 15 3.58789C15.2481 3.58953 15.4856 3.68883 15.6611 3.86429C15.8366 4.03975 15.9359 4.27726 15.9375 4.52539V18.7504C15.9359 18.9985 15.8366 19.236 15.6611 19.4115C15.4856 19.587 15.2481 19.6863 15 19.6879Z"
37
- stroke={color}
38
- strokeWidth="0.5"
39
- />
40
- <path
41
- id="Vector_3"
42
- d="M19.189 8.24978C19.0658 8.25022 18.9438 8.22614 18.83 8.17892C18.7163 8.1317 18.6131 8.06231 18.5265 7.97478L15.004 4.44978L11.479 7.97478C11.3012 8.14038 11.0662 8.23054 10.8233 8.22625C10.5804 8.22197 10.3487 8.12358 10.1769 7.95181C10.0052 7.78004 9.90678 7.54831 9.90249 7.30544C9.8982 7.06256 9.98836 6.8275 10.154 6.64978L14.339 2.46353C14.5154 2.28918 14.7534 2.19141 15.0015 2.19141C15.2495 2.19141 15.4875 2.28918 15.664 2.46353L19.8515 6.65103C20.0258 6.82746 20.1236 7.06549 20.1236 7.31353C20.1236 7.56157 20.0258 7.79961 19.8515 7.97603C19.7654 8.06431 19.6623 8.13413 19.5484 8.18119C19.4345 8.22826 19.3122 8.2516 19.189 8.24978Z"
43
- stroke={color}
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
  );
@@ -19,6 +19,7 @@ export const AccordionGroup = ({ data, containerSx }: AccordionGroupProps) => {
19
19
  <Box sx={{ ...containerSx }}>
20
20
  {data?.map((itemProps, index) => (
21
21
  <Accordion
22
+ elevation={0}
22
23
  {...itemProps}
23
24
  expanded={expanded}
24
25
  index={index}
@@ -48,7 +48,7 @@ export interface CardProps {
48
48
  checkBox?: boolean;
49
49
 
50
50
  moreOptions?: boolean;
51
- menu?: Array<ReactNode>;
51
+ menu?: ReactNode[] | ((props: { close: () => void }) => ReactNode[]);
52
52
  icon?: ReactNode;
53
53
  headerSx?: SxProps;
54
54
  statusSx?: SxProps;
@@ -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">{label}</Typography>
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 key={index}>
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)(({ theme }) => ({
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: '400px',
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: '1.5px dotted',
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.main,
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
- {filterComponents.map((filter, index) => (
159
+ {finalFilterComponents.map((filter, index) => (
153
160
  <Fragment key={index}>
154
161
  {wrapProps(filter)}
155
- {index < filterComponents.length - 1 && (
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 { Fragment, ReactNode, useState } from 'react';
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
- <Fragment key={index}>
100
+ <div key={index}>
100
101
  {item}
101
102
  {index < menuItems.length - 1 && (
102
103
  <Divider flexItem sx={{ margin: '0 !important' }} />
103
104
  )}
104
- </Fragment>
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
- <TabContent>
71
- {tabs.find((tab) => tab?.key === currentTab)?.component}
72
- </TabContent>
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
- />; */