norma-library 0.4.8 → 0.5.0

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.
Files changed (251) hide show
  1. package/.babelrc.json +1 -1
  2. package/.husky/commit-msg +4 -0
  3. package/.prettierignore +11 -0
  4. package/.prettierrc.json +20 -0
  5. package/CHANGELOG.md +0 -0
  6. package/CONTRIBUTING.md +0 -0
  7. package/README.md +42 -0
  8. package/commitlint.config.js +1 -0
  9. package/dist/Button/index.d.ts +9 -0
  10. package/dist/Button/types.d.ts +18 -0
  11. package/dist/Card/Card.d.ts +3 -0
  12. package/dist/Card/CardHeader.d.ts +3 -0
  13. package/dist/Card/index.d.ts +4 -0
  14. package/dist/Card/styles.d.ts +546 -0
  15. package/dist/Card/types.d.ts +8 -0
  16. package/dist/esm/components/Accordion.d.ts +2 -2
  17. package/dist/esm/components/Accordion.js +8 -8
  18. package/dist/esm/components/Accordion.js.map +1 -1
  19. package/dist/esm/components/Avatar.d.ts +2 -2
  20. package/dist/esm/components/Avatar.js +7 -7
  21. package/dist/esm/components/Avatar.js.map +1 -1
  22. package/dist/esm/components/Badge.d.ts +2 -2
  23. package/dist/esm/components/Badge.js +5 -5
  24. package/dist/esm/components/Badge.js.map +1 -1
  25. package/dist/esm/components/Button.d.ts +2 -2
  26. package/dist/esm/components/Button.js +10 -10
  27. package/dist/esm/components/Button.js.map +1 -1
  28. package/dist/esm/components/Card.d.ts +3 -3
  29. package/dist/esm/components/Card.js +8 -8
  30. package/dist/esm/components/Card.js.map +1 -1
  31. package/dist/esm/components/ChatMessage.d.ts +2 -2
  32. package/dist/esm/components/ChatMessage.js +35 -35
  33. package/dist/esm/components/ChatMessage.js.map +1 -1
  34. package/dist/esm/components/CheckBox.d.ts +2 -2
  35. package/dist/esm/components/CheckBox.js +5 -5
  36. package/dist/esm/components/CheckBox.js.map +1 -1
  37. package/dist/esm/components/DataGrid/base/dropdown.d.ts +4 -0
  38. package/dist/esm/components/DataGrid/base/dropdown.js +126 -0
  39. package/dist/esm/components/DataGrid/base/dropdown.js.map +1 -0
  40. package/dist/esm/components/DataGrid/base/number-filter.d.ts +4 -0
  41. package/dist/esm/components/DataGrid/base/number-filter.js +30 -0
  42. package/dist/esm/components/DataGrid/base/number-filter.js.map +1 -0
  43. package/dist/esm/components/DataGrid/base/sorting.d.ts +5 -0
  44. package/dist/esm/components/DataGrid/base/sorting.js +15 -0
  45. package/dist/esm/components/DataGrid/base/sorting.js.map +1 -0
  46. package/dist/esm/components/DataGrid/icons.d.ts +4 -0
  47. package/dist/esm/components/DataGrid/icons.js +15 -0
  48. package/dist/esm/components/DataGrid/icons.js.map +1 -0
  49. package/dist/esm/components/DataGrid/index.d.ts +5 -0
  50. package/dist/esm/components/DataGrid/index.js +137 -0
  51. package/dist/esm/components/DataGrid/index.js.map +1 -0
  52. package/dist/esm/components/DataGrid/shared.d.ts +20 -0
  53. package/dist/esm/components/DataGrid/shared.js +128 -0
  54. package/dist/esm/components/DataGrid/shared.js.map +1 -0
  55. package/dist/esm/components/DataGrid/styled.d.ts +10 -0
  56. package/dist/esm/components/DataGrid/styled.js +73 -0
  57. package/dist/esm/components/DataGrid/styled.js.map +1 -0
  58. package/dist/esm/components/DatePicker.d.ts +5 -5
  59. package/dist/esm/components/DatePicker.js +37 -37
  60. package/dist/esm/components/DatePicker.js.map +1 -1
  61. package/dist/esm/components/DropDown.d.ts +2 -2
  62. package/dist/esm/components/DropDown.js +6 -6
  63. package/dist/esm/components/DropDown.js.map +1 -1
  64. package/dist/esm/components/IconButton.d.ts +2 -2
  65. package/dist/esm/components/IconButton.js +7 -7
  66. package/dist/esm/components/IconButton.js.map +1 -1
  67. package/dist/esm/components/Icons.d.ts +2 -2
  68. package/dist/esm/components/Icons.js +10 -10
  69. package/dist/esm/components/Icons.js.map +1 -1
  70. package/dist/esm/components/Modal.d.ts +2 -2
  71. package/dist/esm/components/Modal.js +8 -8
  72. package/dist/esm/components/Modal.js.map +1 -1
  73. package/dist/esm/components/Paper.d.ts +2 -2
  74. package/dist/esm/components/Paper.js +5 -5
  75. package/dist/esm/components/Paper.js.map +1 -1
  76. package/dist/esm/components/ProgressBar.d.ts +2 -2
  77. package/dist/esm/components/ProgressBar.js +11 -11
  78. package/dist/esm/components/ProgressBar.js.map +1 -1
  79. package/dist/esm/components/RadioGroup.d.ts +2 -2
  80. package/dist/esm/components/RadioGroup.js +7 -7
  81. package/dist/esm/components/RadioGroup.js.map +1 -1
  82. package/dist/esm/components/RangerSlider.d.ts +2 -2
  83. package/dist/esm/components/RangerSlider.js +31 -31
  84. package/dist/esm/components/RangerSlider.js.map +1 -1
  85. package/dist/esm/components/Select.d.ts +2 -2
  86. package/dist/esm/components/Select.js +14 -14
  87. package/dist/esm/components/Select.js.map +1 -1
  88. package/dist/esm/components/Svgs.d.ts +1 -1
  89. package/dist/esm/components/Svgs.js +1 -1
  90. package/dist/esm/components/Svgs.js.map +1 -1
  91. package/dist/esm/components/Tabs.d.ts +2 -2
  92. package/dist/esm/components/Tabs.js +25 -26
  93. package/dist/esm/components/Tabs.js.map +1 -1
  94. package/dist/esm/components/Tag.d.ts +2 -2
  95. package/dist/esm/components/Tag.js +8 -8
  96. package/dist/esm/components/Tag.js.map +1 -1
  97. package/dist/esm/components/TextField.d.ts +2 -2
  98. package/dist/esm/components/TextField.js +8 -8
  99. package/dist/esm/components/TextField.js.map +1 -1
  100. package/dist/esm/components/TimeLine.d.ts +2 -2
  101. package/dist/esm/components/TimeLine.js +20 -20
  102. package/dist/esm/components/TimeLine.js.map +1 -1
  103. package/dist/esm/components/TimePicker.d.ts +8 -8
  104. package/dist/esm/components/TimePicker.js +43 -43
  105. package/dist/esm/components/TimePicker.js.map +1 -1
  106. package/dist/esm/components/index.d.ts +23 -22
  107. package/dist/esm/components/index.js +23 -22
  108. package/dist/esm/components/index.js.map +1 -1
  109. package/dist/esm/helpers/alignments.js +7 -7
  110. package/dist/esm/helpers/borders.js +11 -11
  111. package/dist/esm/helpers/colors.js +41 -41
  112. package/dist/esm/helpers/index.d.ts +5 -5
  113. package/dist/esm/helpers/index.js +5 -5
  114. package/dist/esm/helpers/sizes.d.ts +1 -1
  115. package/dist/esm/helpers/sizes.js +39 -39
  116. package/dist/esm/helpers/sizes.js.map +1 -1
  117. package/dist/esm/index.d.ts +17 -17
  118. package/dist/esm/index.js +17 -17
  119. package/dist/esm/interfaces/Accordion.d.ts +3 -3
  120. package/dist/esm/interfaces/Avatar.d.ts +6 -6
  121. package/dist/esm/interfaces/Badge.d.ts +7 -7
  122. package/dist/esm/interfaces/Button.d.ts +5 -5
  123. package/dist/esm/interfaces/Card.d.ts +3 -3
  124. package/dist/esm/interfaces/ChatMessage.d.ts +1 -1
  125. package/dist/esm/interfaces/CheckBox.d.ts +10 -10
  126. package/dist/esm/interfaces/DataGrid.d.ts +40 -0
  127. package/dist/esm/interfaces/DataGrid.js +2 -0
  128. package/dist/esm/interfaces/DataGrid.js.map +1 -0
  129. package/dist/esm/interfaces/DatePicker.d.ts +3 -3
  130. package/dist/esm/interfaces/DropDown.d.ts +4 -4
  131. package/dist/esm/interfaces/IconButton.d.ts +5 -5
  132. package/dist/esm/interfaces/Icons.d.ts +3 -3
  133. package/dist/esm/interfaces/Modal.d.ts +3 -3
  134. package/dist/esm/interfaces/Paper.d.ts +4 -4
  135. package/dist/esm/interfaces/ProgressBar.d.ts +5 -5
  136. package/dist/esm/interfaces/RadioGroup.d.ts +4 -4
  137. package/dist/esm/interfaces/RangerSlider.d.ts +8 -8
  138. package/dist/esm/interfaces/Select.d.ts +3 -3
  139. package/dist/esm/interfaces/Tabs.d.ts +3 -3
  140. package/dist/esm/interfaces/Tag.d.ts +5 -5
  141. package/dist/esm/interfaces/TextField.d.ts +12 -12
  142. package/dist/esm/interfaces/TimeLine.d.ts +3 -3
  143. package/dist/esm/interfaces/TimePicker.d.ts +3 -3
  144. package/dist/esm/interfaces/index.d.ts +23 -22
  145. package/dist/esm/interfaces/index.js +23 -22
  146. package/dist/esm/interfaces/index.js.map +1 -1
  147. package/dist/esm/types/index.d.ts +41 -40
  148. package/dist/esm/types/index.js +2 -2
  149. package/dist/esm/types/index.js.map +1 -1
  150. package/dist/index.d.ts +2 -0
  151. package/dist/index.es.js +6992 -0
  152. package/dist/index.es.js.map +1 -0
  153. package/dist/index.umd.js +266 -0
  154. package/dist/index.umd.js.map +1 -0
  155. package/dist/vite.svg +1 -0
  156. package/docs/index.md +118 -0
  157. package/package.json +65 -9
  158. package/src/components/Accordion.tsx +47 -64
  159. package/src/components/Avatar.tsx +22 -29
  160. package/src/components/Badge.tsx +19 -22
  161. package/src/components/Button.tsx +12 -19
  162. package/src/components/Card.tsx +44 -47
  163. package/src/components/ChatMessage.tsx +87 -89
  164. package/src/components/CheckBox.tsx +8 -19
  165. package/src/components/DataGrid/allData.json +2918 -0
  166. package/src/components/DataGrid/base/dropdown.tsx +212 -0
  167. package/src/components/DataGrid/base/number-filter.tsx +43 -0
  168. package/src/components/DataGrid/base/sorting.tsx +29 -0
  169. package/src/components/DataGrid/icons.tsx +53 -0
  170. package/src/components/DataGrid/index.tsx +254 -0
  171. package/src/components/DataGrid/shared.ts +154 -0
  172. package/src/components/DataGrid/styled.ts +96 -0
  173. package/src/components/DataGrid/styles/dropdown.module.css +86 -0
  174. package/src/components/DataGrid/styles/number-filter.module.css +16 -0
  175. package/src/components/DataGrid/styles/styles.module.css +107 -0
  176. package/src/components/DatePicker.tsx +73 -84
  177. package/src/components/DropDown.tsx +31 -38
  178. package/src/components/IconButton.tsx +12 -29
  179. package/src/components/Icons.tsx +82 -87
  180. package/src/components/Modal.tsx +114 -123
  181. package/src/components/Paper.tsx +19 -22
  182. package/src/components/ProgressBar.tsx +54 -63
  183. package/src/components/RadioGroup.tsx +47 -55
  184. package/src/components/RangerSlider.tsx +70 -81
  185. package/src/components/Select.tsx +82 -98
  186. package/src/components/Svgs.tsx +498 -522
  187. package/src/components/Tabs.tsx +111 -140
  188. package/src/components/Tag.tsx +37 -45
  189. package/src/components/TextField.tsx +11 -22
  190. package/src/components/TimeLine.tsx +93 -103
  191. package/src/components/TimePicker.tsx +84 -95
  192. package/src/components/index.ts +23 -22
  193. package/src/helpers/alignments.ts +7 -7
  194. package/src/helpers/borders.ts +11 -11
  195. package/src/helpers/colors.ts +42 -42
  196. package/src/helpers/index.ts +5 -5
  197. package/src/helpers/sizes.ts +39 -46
  198. package/src/index.ts +17 -17
  199. package/src/interfaces/Accordion.ts +12 -12
  200. package/src/interfaces/Avatar.tsx +15 -18
  201. package/src/interfaces/Badge.ts +19 -32
  202. package/src/interfaces/Button.ts +5 -10
  203. package/src/interfaces/Card.ts +11 -11
  204. package/src/interfaces/ChatMessage.ts +12 -12
  205. package/src/interfaces/CheckBox.ts +12 -18
  206. package/src/interfaces/DataGrid.ts +46 -0
  207. package/src/interfaces/DatePicker.ts +13 -13
  208. package/src/interfaces/DropDown.ts +14 -14
  209. package/src/interfaces/IconButton.ts +5 -10
  210. package/src/interfaces/Icons.ts +17 -17
  211. package/src/interfaces/Modal.ts +15 -15
  212. package/src/interfaces/Paper.ts +12 -12
  213. package/src/interfaces/ProgressBar.ts +18 -25
  214. package/src/interfaces/RadioGroup.ts +22 -28
  215. package/src/interfaces/RangerSlider.ts +21 -32
  216. package/src/interfaces/Select.ts +17 -17
  217. package/src/interfaces/Tabs.ts +19 -24
  218. package/src/interfaces/Tag.ts +17 -17
  219. package/src/interfaces/TextField.ts +14 -34
  220. package/src/interfaces/TimeLine.ts +11 -16
  221. package/src/interfaces/TimePicker.ts +13 -13
  222. package/src/interfaces/index.ts +23 -22
  223. package/src/sample-data.json +178 -0
  224. package/src/stories/Accordion.stories.tsx +65 -65
  225. package/src/stories/Avatar.stories.tsx +123 -139
  226. package/src/stories/Badge.stories.tsx +39 -47
  227. package/src/stories/Button.stories.tsx +18 -26
  228. package/src/stories/Card.stories.tsx +40 -55
  229. package/src/stories/ChatMessage.stories.tsx +84 -85
  230. package/src/stories/CheckBox.stories.tsx +17 -23
  231. package/src/stories/DataGrid.stories.tsx +28 -0
  232. package/src/stories/DatePicker.stories.tsx +50 -77
  233. package/src/stories/DropDown.stories.tsx +57 -57
  234. package/src/stories/IconButton.stories.tsx +78 -114
  235. package/src/stories/Modal.stories.tsx +190 -190
  236. package/src/stories/Paper.stories.tsx +53 -53
  237. package/src/stories/ProgressBar.stories.tsx +95 -139
  238. package/src/stories/RadioGroup.stories.tsx +21 -28
  239. package/src/stories/RangerSlider.stories.tsx +58 -68
  240. package/src/stories/Select.stories.tsx +100 -128
  241. package/src/stories/Tabs.stories.tsx +62 -62
  242. package/src/stories/Tag.stories.tsx +56 -74
  243. package/src/stories/TextField.stories.tsx +54 -189
  244. package/src/stories/TimeLine.stories.tsx +35 -43
  245. package/src/stories/TimePicker.stories.tsx +87 -113
  246. package/src/types/index.ts +92 -154
  247. package/tsconfig.json +1 -1
  248. package/buildcache/front-end +0 -1
  249. package/norma-library.tar +0 -0
  250. package/postcss.config.js +0 -6
  251. package/tailwind.config.js +0 -58
@@ -0,0 +1,212 @@
1
+ import React, { useState, useEffect, Fragment } from 'react';
2
+ import NumberFilter from './number-filter';
3
+ import { Button, Typography, FormControl, InputLabel, OutlinedInput, InputAdornment, IconButton } from '@mui/material';
4
+ import Divider from '@mui/material/Divider';
5
+ import MenuList from '@mui/material/MenuList';
6
+ import MenuItem from '@mui/material/MenuItem';
7
+ import ListItemIcon from '@mui/material/ListItemIcon';
8
+ import ListItemText from '@mui/material/ListItemText';
9
+
10
+ import List from '@mui/material/List';
11
+ import ListItem from '@mui/material/ListItem';
12
+ import ListItemButton from '@mui/material/ListItemButton';
13
+ import Checkbox from '@mui/material/Checkbox';
14
+
15
+ import { Search } from '@mui/icons-material';
16
+ import { DropdownFilterProps } from '@/interfaces';
17
+ import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
18
+
19
+ import { DropDownStyled } from '../styled';
20
+
21
+ import { ArrowSmallDownIcon, ArrowSmallUpIcon, FunnelIcon } from '../icons';
22
+
23
+ const DropdownFilter = ({
24
+ onOrder,
25
+ onFilter,
26
+ onSelected,
27
+ onFilterSelected,
28
+ itemsSelected,
29
+ onSelectAll,
30
+ onChecketAll,
31
+ data,
32
+ }: DropdownFilterProps) => {
33
+ const [openFilter, setOpenFilter] = useState<boolean>(false);
34
+ const [selectAll, setSelectAll] = useState(onSelectAll);
35
+ const [selecteds, setItemsSelected] = useState<(string | number)[]>(itemsSelected);
36
+
37
+ const handleFilter = () => {
38
+ setOpenFilter(prevState => !prevState);
39
+ };
40
+
41
+ const handleFilterSelected = () => {
42
+ if (itemsSelected.length > 0) {
43
+ onFilterSelected();
44
+ } else {
45
+ onSelected([]);
46
+ onFilter('');
47
+ onFilterSelected();
48
+ }
49
+ };
50
+
51
+ const handleCheckboxChange = (option: string) => {
52
+ const updatedSelection = selecteds.includes(option)
53
+ ? selecteds.filter(selected => selected !== option)
54
+ : [...selecteds, option];
55
+
56
+ setItemsSelected(updatedSelection);
57
+ onSelected(updatedSelection);
58
+ };
59
+
60
+ const handleSelectAll = () => {
61
+ setSelectAll(selectAll ? false : true);
62
+ onChecketAll(selectAll ? false : true);
63
+
64
+ if (!selectAll) {
65
+ const allItems = data.map((item: any) => item.toString());
66
+ setItemsSelected(allItems);
67
+ onSelected(allItems);
68
+ } else {
69
+ setItemsSelected([]);
70
+ onSelected([]);
71
+ }
72
+ };
73
+
74
+ useEffect(() => {
75
+ setItemsSelected(selectAll ? data.map(String) : []);
76
+ onSelected(selectAll ? data.map(String) : []);
77
+ }, [selectAll]);
78
+
79
+ useEffect(() => {
80
+ setItemsSelected(itemsSelected);
81
+ }, [selecteds]);
82
+
83
+ return (
84
+ <DropDownStyled>
85
+ <Fragment>
86
+ <MenuList>
87
+ <MenuItem
88
+ onClick={() => {
89
+ onOrder('down');
90
+ setOpenFilter(false);
91
+ }}
92
+ >
93
+ <ListItemIcon>
94
+ <ArrowSmallUpIcon width="16" height="16" />
95
+ </ListItemIcon>
96
+ <ListItemText>Classificar de A a Z</ListItemText>
97
+ </MenuItem>
98
+ <MenuItem
99
+ onClick={() => {
100
+ onOrder('up');
101
+ setOpenFilter(false);
102
+ }}
103
+ >
104
+ <ListItemIcon>
105
+ <ArrowSmallDownIcon width="16" height="16" />
106
+ </ListItemIcon>
107
+ <ListItemText>Classificar de Z a A</ListItemText>
108
+ </MenuItem>
109
+ <MenuItem onClick={handleFilter}>
110
+ <ListItemIcon>
111
+ <FunnelIcon width="16" height="16" />
112
+ </ListItemIcon>
113
+ <ListItemText>Filtro por números</ListItemText>
114
+ <Typography variant="body2" color="text.secondary">
115
+ <KeyboardArrowRightIcon fontSize="medium" style={{ position: 'relative', top: '5px' }} />
116
+ </Typography>
117
+ {openFilter && (
118
+ <React.Fragment>
119
+ <NumberFilter onClick={() => console.log('Me clicou')} />
120
+ </React.Fragment>
121
+ )}
122
+ </MenuItem>
123
+ <Divider />
124
+ <FormControl sx={{ m: 1 }} variant="outlined">
125
+ <InputLabel htmlFor="outlined-adornment-search" size="small">
126
+ Buscar
127
+ </InputLabel>
128
+ <OutlinedInput
129
+ id="outlined-adornment-search"
130
+ endAdornment={
131
+ <InputAdornment position="end">
132
+ <IconButton edge="end">
133
+ <Search />
134
+ </IconButton>
135
+ </InputAdornment>
136
+ }
137
+ onChange={event => {
138
+ onFilter(event.target.value);
139
+ }}
140
+ label="Buscar"
141
+ fullWidth
142
+ size="small"
143
+ />
144
+ </FormControl>
145
+ <Divider />
146
+ <List
147
+ sx={{
148
+ bgcolor: '#f2f2f2',
149
+ padding: ' 5px',
150
+ overflow: ' auto',
151
+ width: ' 100%',
152
+ height: ' 120px',
153
+ }}
154
+ >
155
+ <ListItem disablePadding onClick={handleSelectAll}>
156
+ <ListItemButton role={undefined} sx={{ py: 0, minHeight: 32 }}>
157
+ <ListItemIcon>
158
+ <Checkbox
159
+ edge="start"
160
+ tabIndex={-1}
161
+ checked={selectAll}
162
+ disableRipple
163
+ inputProps={{ 'aria-labelledby': 'all' }}
164
+ />
165
+ </ListItemIcon>
166
+ <ListItemText
167
+ id={'all'}
168
+ primary={selectAll ? 'Deselect All' : 'Select All'}
169
+ primaryTypographyProps={{
170
+ fontSize: 14,
171
+ fontWeight: 'medium',
172
+ }}
173
+ />
174
+ </ListItemButton>
175
+ </ListItem>
176
+ {data.map((item: any, key: number) => {
177
+ const labelId = `checkbox-list-label-${item.toString()}`;
178
+ return (
179
+ <ListItem key={key} disablePadding onClick={() => handleCheckboxChange(item.toString())}>
180
+ <ListItemButton role={undefined} sx={{ py: 0, minHeight: 32 }}>
181
+ <ListItemIcon>
182
+ <Checkbox
183
+ edge="start"
184
+ tabIndex={-1}
185
+ disableRipple
186
+ inputProps={{ 'aria-labelledby': labelId }}
187
+ checked={selecteds.includes(item.toString())}
188
+ />
189
+ </ListItemIcon>
190
+ <ListItemText
191
+ id={labelId}
192
+ primary={`${item}`}
193
+ primaryTypographyProps={{
194
+ fontSize: 14,
195
+ fontWeight: 'medium',
196
+ }}
197
+ />
198
+ </ListItemButton>
199
+ </ListItem>
200
+ );
201
+ })}
202
+ </List>
203
+ </MenuList>
204
+ <Button variant="outlined" sx={{ align: 'right' }} onClick={handleFilterSelected}>
205
+ Confirm
206
+ </Button>
207
+ </Fragment>
208
+ </DropDownStyled>
209
+ );
210
+ };
211
+
212
+ export default DropdownFilter;
@@ -0,0 +1,43 @@
1
+ import React from 'react';
2
+
3
+ import List from '@mui/material/List';
4
+ import ListItem from '@mui/material/ListItem';
5
+ import ListItemText from '@mui/material/ListItemText';
6
+ import { NumberFilterProps } from '@/interfaces';
7
+
8
+ const items = [
9
+ 'Equal',
10
+ 'Does not equal',
11
+ 'Greater than',
12
+ 'Greater than or equal to',
13
+ 'Less than',
14
+ 'Less than or equal to',
15
+ 'Between',
16
+ ];
17
+
18
+ const NumberFilter: React.FC<NumberFilterProps> = () => {
19
+ return (
20
+ <List
21
+ sx={{
22
+ bgcolor: '#FFF',
23
+ position: 'absolute',
24
+ minHeight: '190px',
25
+ top: '0',
26
+ left: 'auto',
27
+ right: 'auto',
28
+ minWidth: '240px',
29
+ zIndex: '9',
30
+ padding: '5px 10px',
31
+ boxShadow: '0 0 10px #ccc',
32
+ }}
33
+ >
34
+ {items.map((value, key) => (
35
+ <ListItem key={key} disableGutters>
36
+ <ListItemText primary={`${value}...`} />
37
+ </ListItem>
38
+ ))}
39
+ </List>
40
+ );
41
+ };
42
+
43
+ export default NumberFilter;
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+
3
+ import { SortingProps } from '@/interfaces';
4
+ // import { Icons } from "@/components/Icons";
5
+
6
+ export function ArrowSmallUpIcon(props: any) {
7
+ return (
8
+ <svg fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" {...props}>
9
+ <path
10
+ clipRule="evenodd"
11
+ fillRule="evenodd"
12
+ d="M12 20.25a.75.75 0 01-.75-.75V6.31l-5.47 5.47a.75.75 0 01-1.06-1.06l6.75-6.75a.75.75 0 011.06 0l6.75 6.75a.75.75 0 11-1.06 1.06l-5.47-5.47V19.5a.75.75 0 01-.75.75z"
13
+ />
14
+ </svg>
15
+ );
16
+ }
17
+
18
+ const Sorting: React.FC<SortingProps> = ({ sort, active }) => {
19
+ const sortIcon = <ArrowSmallUpIcon />;
20
+ const opacityValue = active ? 1 : 0.5;
21
+
22
+ return (
23
+ <button type="button" style={{ opacity: opacityValue }} className="arrows">
24
+ {sort && sortIcon}
25
+ </button>
26
+ );
27
+ };
28
+
29
+ export default Sorting;
@@ -0,0 +1,53 @@
1
+ import React from 'react';
2
+
3
+ export function FunnelIcon(props: any) {
4
+ return (
5
+ <svg
6
+ fill="none"
7
+ stroke="currentColor"
8
+ strokeWidth={1.5}
9
+ viewBox="0 0 24 24"
10
+ xmlns="http://www.w3.org/2000/svg"
11
+ aria-hidden="true"
12
+ {...props}
13
+ >
14
+ <path
15
+ strokeLinecap="round"
16
+ strokeLinejoin="round"
17
+ d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 01-.659 1.591l-5.432 5.432a2.25 2.25 0 00-.659 1.591v2.927a2.25 2.25 0 01-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 00-.659-1.591L3.659 7.409A2.25 2.25 0 013 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0112 3z"
18
+ />
19
+ </svg>
20
+ );
21
+ }
22
+
23
+ export function ArrowSmallUpIcon(props: any) {
24
+ return (
25
+ <svg
26
+ fill="none"
27
+ stroke="currentColor"
28
+ strokeWidth={1.5}
29
+ viewBox="0 0 24 24"
30
+ xmlns="http://www.w3.org/2000/svg"
31
+ aria-hidden="true"
32
+ {...props}
33
+ >
34
+ <path strokeLinecap="round" strokeLinejoin="round" d="M12 19.5v-15m0 0l-6.75 6.75M12 4.5l6.75 6.75" />
35
+ </svg>
36
+ );
37
+ }
38
+
39
+ export function ArrowSmallDownIcon(props: any) {
40
+ return (
41
+ <svg
42
+ fill="none"
43
+ stroke="currentColor"
44
+ strokeWidth={1.5}
45
+ viewBox="0 0 24 24"
46
+ xmlns="http://www.w3.org/2000/svg"
47
+ aria-hidden="true"
48
+ {...props}
49
+ >
50
+ <path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m0 0l6.75-6.75M12 19.5l-6.75-6.75" />
51
+ </svg>
52
+ );
53
+ }
@@ -0,0 +1,254 @@
1
+ import React, { useEffect, useMemo, useState, useRef } from 'react';
2
+
3
+ import { Box, Stack, ThemeProvider, useMediaQuery, Paper } from '@mui/material';
4
+
5
+ import Table from '@mui/material/Table';
6
+ import TableBody from '@mui/material/TableBody';
7
+ import TableCell from '@mui/material/TableCell';
8
+ import TableContainer from '@mui/material/TableContainer';
9
+ import TableHead from '@mui/material/TableHead';
10
+ import TableRow from '@mui/material/TableRow';
11
+
12
+ import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp';
13
+ import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
14
+
15
+ import { DataGridBaseProps, DataSourceItem } from '../../interfaces';
16
+
17
+ import { themes } from '../../helpers';
18
+
19
+ import DropdownFilter from './base/dropdown';
20
+ import { Pagination as MuiPagination } from '@mui/material';
21
+
22
+ import { filterDataSource, generateRandomDataSource, groupByDataSource, sortDataSourceByColumn } from './shared';
23
+
24
+ import {
25
+ ButtonStyled,
26
+ DataGridHeaderStyled,
27
+ HeaderCogStyled,
28
+ TableCellStyled,
29
+ TableRowStyled,
30
+ TotalRecordsStyled,
31
+ } from './styled';
32
+
33
+ export function ArrowSmallUpIcon(props: any) {
34
+ return (
35
+ <svg fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" {...props}>
36
+ <path
37
+ clipRule="evenodd"
38
+ fillRule="evenodd"
39
+ d="M12 20.25a.75.75 0 01-.75-.75V6.31l-5.47 5.47a.75.75 0 01-1.06-1.06l6.75-6.75a.75.75 0 011.06 0l6.75 6.75a.75.75 0 11-1.06 1.06l-5.47-5.47V19.5a.75.75 0 01-.75.75z"
40
+ />
41
+ </svg>
42
+ );
43
+ }
44
+
45
+ export function Cog6ToothIcon(props: any) {
46
+ return (
47
+ <svg
48
+ fill="none"
49
+ stroke="currentColor"
50
+ strokeWidth={1.5}
51
+ viewBox="0 0 24 24"
52
+ xmlns="http://www.w3.org/2000/svg"
53
+ aria-hidden="true"
54
+ {...props}
55
+ >
56
+ <path
57
+ strokeLinecap="round"
58
+ strokeLinejoin="round"
59
+ d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281z"
60
+ />
61
+ <path strokeLinecap="round" strokeLinejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
62
+ </svg>
63
+ );
64
+ }
65
+
66
+ const dataSource = generateRandomDataSource(30);
67
+
68
+ export const DataGrid: React.FC<DataGridBaseProps> = ({ data = [] }) => {
69
+ const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
70
+ const theme = useMemo(() => (prefersDarkMode ? themes.light : themes.light), [prefersDarkMode]);
71
+
72
+ const pageSize = 10;
73
+ const columns = data[0].columns;
74
+
75
+ const [selectedItems, setSelectedItems] = useState<(string | number)[]>([]);
76
+
77
+ const [sorting, setSorting] = useState('down');
78
+ const [selectAll, setSelectAll] = useState<boolean>(false);
79
+
80
+ const [currentActiveSorting, setCurrentActiveSorting] = useState<string>('id');
81
+
82
+ const [currentDropDownActive, setCurrentDropDownActive] = useState<string | null>(null);
83
+
84
+ const [originalDataSource, setOriginalDataSource] = useState<DataSourceItem[]>(dataSource);
85
+ const [newDataSource, setDataSource] = useState<DataSourceItem[]>(dataSource);
86
+ const [totalRecords, setTotalRecords] = useState(dataSource.length);
87
+ const [totalPages, setTotalPages] = useState(Math.ceil(dataSource.length / pageSize));
88
+
89
+ const [currentPage, setCurrentPage] = useState(1);
90
+ const startIndex = (currentPage - 1) * pageSize;
91
+ const endIndex = Math.min(startIndex + pageSize, totalRecords);
92
+
93
+ const sortRefs = useRef<(React.RefObject<HTMLTableCellElement> | null)[]>(new Array(columns.length).fill(null));
94
+
95
+ const handleItemSelected = (items: (string | number)[]) => {
96
+ setSelectedItems(items);
97
+ };
98
+
99
+ const handleDropDown = (item: any) => {
100
+ setCurrentDropDownActive(item === currentDropDownActive ? null : item);
101
+ if (item !== currentDropDownActive) {
102
+ setCurrentActiveSorting(item);
103
+ setSorting('down');
104
+ }
105
+ };
106
+
107
+ const handleSorting = (sort: string) => {
108
+ setSorting(sort === 'up' ? 'up' : 'down');
109
+ currentDropDownActive && setCurrentActiveSorting(currentDropDownActive);
110
+ handleDropDown(currentDropDownActive);
111
+ };
112
+
113
+ const handleFilter = (filter: string) => {
114
+ const dataSourceFiltered = filterDataSource(originalDataSource, currentActiveSorting, filter);
115
+ setOriginalDataSource(dataSourceFiltered);
116
+ setCurrentPage(1);
117
+ };
118
+
119
+ const handleFilterSelected = () => {
120
+ if (selectedItems.length > 0) {
121
+ const filteredData = originalDataSource.filter((item: DataSourceItem) => {
122
+ const columnValue = currentActiveSorting ? item[currentActiveSorting] : undefined;
123
+
124
+ if (typeof columnValue === 'string') {
125
+ return selectedItems.includes(columnValue);
126
+ } else if (typeof columnValue === 'number') {
127
+ return selectedItems.includes(columnValue.toString());
128
+ }
129
+ return false;
130
+ });
131
+
132
+ const sortedData = sortDataSourceByColumn(filteredData, currentActiveSorting, sorting);
133
+ setTotalRecords(sortedData.length);
134
+ setTotalPages(Math.ceil(sortedData.length / pageSize));
135
+ setCurrentPage(1);
136
+ setDataSource(sortedData.slice(startIndex, endIndex));
137
+ } else {
138
+ const sortedData = sortDataSourceByColumn(dataSource, currentActiveSorting, sorting);
139
+ setTotalRecords(sortedData.length);
140
+ setTotalPages(Math.ceil(sortedData.length / pageSize));
141
+ setCurrentPage(1);
142
+ setDataSource(sortedData.slice(startIndex, endIndex));
143
+ }
144
+ handleDropDown(currentDropDownActive);
145
+ };
146
+
147
+ const handleChangePage = (page: number) => {
148
+ setCurrentPage(page);
149
+ const startIndex = (page - 1) * pageSize;
150
+ const endIndex = Math.min(startIndex + pageSize, totalRecords);
151
+ setDataSource(originalDataSource.slice(startIndex, endIndex));
152
+ };
153
+
154
+ useEffect(() => {
155
+ if (selectedItems.length <= 0) {
156
+ const sortedData = sortDataSourceByColumn(dataSource, currentActiveSorting, sorting);
157
+ setDataSource(sortedData.slice(startIndex, endIndex));
158
+ setTotalRecords(sortedData.length);
159
+ setTotalPages(Math.ceil(sortedData.length / pageSize));
160
+ setCurrentPage(1);
161
+ }
162
+ }, [selectedItems]);
163
+
164
+ return (
165
+ <ThemeProvider theme={theme}>
166
+ <Box sx={{ width: '100%', minHeight: 480 }}>
167
+ <DataGridHeaderStyled>
168
+ <TotalRecordsStyled>{totalRecords} results found for this search</TotalRecordsStyled>
169
+ <HeaderCogStyled type="button">
170
+ <Cog6ToothIcon width={24} height={24} />
171
+ </HeaderCogStyled>
172
+ </DataGridHeaderStyled>
173
+ <TableContainer component={Paper} sx={{ overflowX: 'inherit' }}>
174
+ <Table sx={{ minWidth: 650, width: '100%' }} aria-label="a dense table">
175
+ <TableHead>
176
+ <TableRow>
177
+ {columns &&
178
+ columns.map((item: any, key: any) => (
179
+ <TableCellStyled
180
+ key={key}
181
+ ref={ref => (sortRefs.current[key] = ref as React.RefObject<HTMLTableCellElement> | null)}
182
+ >
183
+ <Stack direction="row" spacing={2} sx={{ position: 'relative' }}>
184
+ <ButtonStyled
185
+ variant="text"
186
+ size="small"
187
+ color={currentActiveSorting === item.field ? 'primary' : 'inherit'}
188
+ endIcon={
189
+ currentActiveSorting === item.field && sorting === 'up' ? (
190
+ <ArrowDropUpIcon />
191
+ ) : (
192
+ <ArrowDropDownIcon />
193
+ )
194
+ }
195
+ onClick={() => {
196
+ handleDropDown(item.field);
197
+ }}
198
+ >
199
+ {item.headerText}
200
+ </ButtonStyled>
201
+ {currentDropDownActive && currentDropDownActive === item.field && (
202
+ <DropdownFilter
203
+ format={item.format}
204
+ onOrder={handleSorting}
205
+ onFilter={handleFilter}
206
+ onSelected={handleItemSelected}
207
+ itemsSelected={selectedItems}
208
+ onFilterSelected={handleFilterSelected}
209
+ onChecketAll={setSelectAll}
210
+ onSelectAll={selectAll}
211
+ data={groupByDataSource(dataSource, item.field)}
212
+ />
213
+ )}
214
+ </Stack>
215
+ </TableCellStyled>
216
+ ))}
217
+ </TableRow>
218
+ </TableHead>
219
+ <TableBody>
220
+ {newDataSource &&
221
+ newDataSource.map((item: DataSourceItem, key: number) => (
222
+ <TableRowStyled key={key} sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
223
+ {Object.keys(item).map(columnKey => (
224
+ <TableCell component="th" scope="row" key={columnKey}>
225
+ {item[columnKey]}
226
+ </TableCell>
227
+ ))}
228
+ </TableRowStyled>
229
+ ))}
230
+ </TableBody>
231
+ </Table>
232
+ <Stack
233
+ spacing={2}
234
+ sx={{
235
+ display: 'flex',
236
+ justifyContent: 'center',
237
+ alignItems: 'center',
238
+ borderTop: '1px solid #ccc',
239
+ padding: 2,
240
+ }}
241
+ >
242
+ <MuiPagination
243
+ variant="outlined"
244
+ shape="rounded"
245
+ count={totalPages}
246
+ page={currentPage}
247
+ onChange={(_event, page) => handleChangePage(page)}
248
+ />
249
+ </Stack>
250
+ </TableContainer>
251
+ </Box>
252
+ </ThemeProvider>
253
+ );
254
+ };