venice-ui 1.0.42 → 1.0.44
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/dist/cjs/Theme/Theme.js +14 -1
- package/dist/cjs/components/Chips/Chips.js +20 -0
- package/dist/cjs/components/Chips/Chips.styles.js +21 -0
- package/dist/cjs/components/Chips/index.js +17 -0
- package/dist/cjs/components/Filters/Filters.js +198 -0
- package/dist/cjs/components/Filters/Filters.styles.js +32 -0
- package/dist/cjs/components/Filters/filtersHelper.js +51 -0
- package/dist/cjs/components/Filters/index.js +18 -0
- package/dist/cjs/components/Icons/IconsPath.js +2 -0
- package/dist/cjs/components/Table/Table.js +107 -0
- package/dist/cjs/components/Table/Table.styles.js +69 -0
- package/dist/cjs/components/Table/index.js +17 -0
- package/dist/cjs/components/Table/tableHelper.js +29 -0
- package/dist/cjs/components/Typography/Typography.styles.js +2 -2
- package/dist/cjs/components/common/commonComponents.js +1 -0
- package/dist/cjs/index.js +3 -0
- package/dist/esm/Theme/Theme.js +14 -1
- package/dist/esm/components/Chips/Chips.js +13 -0
- package/dist/esm/components/Chips/Chips.styles.js +15 -0
- package/dist/esm/components/Chips/index.js +1 -0
- package/dist/esm/components/Filters/Filters.js +171 -0
- package/dist/esm/components/Filters/Filters.styles.js +26 -0
- package/dist/esm/components/Filters/filtersHelper.js +43 -0
- package/dist/esm/components/Filters/index.js +2 -0
- package/dist/esm/components/Icons/IconsPath.js +2 -0
- package/dist/esm/components/Table/Table.js +80 -0
- package/dist/esm/components/Table/Table.styles.js +63 -0
- package/dist/esm/components/Table/index.js +1 -0
- package/dist/esm/components/Table/tableHelper.js +23 -0
- package/dist/esm/components/Typography/Typography.styles.js +2 -2
- package/dist/esm/components/common/commonComponents.js +1 -0
- package/dist/esm/index.js +3 -0
- package/dist/types/Theme/Theme.d.ts +11 -0
- package/dist/types/components/Chips/Chips.d.ts +8 -0
- package/dist/types/components/Chips/Chips.styles.d.ts +6 -0
- package/dist/types/components/Chips/index.d.ts +1 -0
- package/dist/types/components/Filters/Filters.d.ts +27 -0
- package/dist/types/components/Filters/Filters.styles.d.ts +5 -0
- package/dist/types/components/Filters/filtersHelper.d.ts +8 -0
- package/dist/types/components/Filters/index.d.ts +2 -0
- package/dist/types/components/Icons/IconsPath.d.ts +2 -0
- package/dist/types/components/Table/Table.d.ts +36 -0
- package/dist/types/components/Table/Table.styles.d.ts +23 -0
- package/dist/types/components/Table/index.d.ts +1 -0
- package/dist/types/components/Table/tableHelper.d.ts +5 -0
- package/dist/types/components/common/commonComponents.d.ts +1 -0
- package/dist/types/index.d.ts +3 -0
- package/package.json +3 -1
package/dist/esm/Theme/Theme.js
CHANGED
|
@@ -9,6 +9,7 @@ export const Theme = {
|
|
|
9
9
|
black: "#333333",
|
|
10
10
|
gray_1: "#b7b7b7",
|
|
11
11
|
gray_2: "#e3e3e3",
|
|
12
|
+
gray_3: '#f3f3f3',
|
|
12
13
|
overlayer: 'rgba(0,0,0,0.4)',
|
|
13
14
|
red: '#ad1616'
|
|
14
15
|
},
|
|
@@ -76,5 +77,17 @@ export const mainTheme = {
|
|
|
76
77
|
contentBackground: Theme.colors.white,
|
|
77
78
|
// selector / dropdown
|
|
78
79
|
optionActiveColor: Theme.colors.primary,
|
|
79
|
-
optionHoverBackground: lighten(0.3, Theme.colors.primary)
|
|
80
|
+
optionHoverBackground: lighten(0.3, Theme.colors.primary),
|
|
81
|
+
//table
|
|
82
|
+
tableBorderColor: Theme.colors.gray_2,
|
|
83
|
+
tableHeaderBackground: Theme.colors.white,
|
|
84
|
+
tableHeaderActiveBackground: lighten(0.3, Theme.colors.primary),
|
|
85
|
+
tableCellBackground: Theme.colors.white,
|
|
86
|
+
tableCellEvenBackground: Theme.colors.gray_3,
|
|
87
|
+
tableCellHoverBackground: lighten(0.3, Theme.colors.primary),
|
|
88
|
+
tableCellActiveBackground: lighten(0.3, Theme.colors.primary),
|
|
89
|
+
tableCellSortIcon: Theme.colors.primary,
|
|
90
|
+
// chips
|
|
91
|
+
chipsNeutralBackground: Theme.colors.primary,
|
|
92
|
+
chipsNeutralTextColor: Theme.colors.white
|
|
80
93
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Aligment } from '../Aligment';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { ThemeProvider } from 'styled-components';
|
|
4
|
+
import { mainTheme } from '../../Theme';
|
|
5
|
+
import { ChipsElement, ChipsLabel } from './Chips.styles';
|
|
6
|
+
import { Icon } from '../Icons';
|
|
7
|
+
export const Chips = ({ theme = mainTheme, label, handleClose, }) => {
|
|
8
|
+
return (React.createElement(ThemeProvider, { theme: theme },
|
|
9
|
+
React.createElement(ChipsElement, { onClick: () => handleClose() },
|
|
10
|
+
React.createElement(Aligment, { gap: 4 },
|
|
11
|
+
React.createElement(ChipsLabel, null, label),
|
|
12
|
+
React.createElement(Icon, { name: 'close', color: theme.chipsNeutralTextColor, size: 14 })))));
|
|
13
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
import { Theme } from "../../Theme";
|
|
3
|
+
export const ChipsElement = styled.div `
|
|
4
|
+
display:inline-block;
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
background-color:${p => p.theme.chipsNeutralBackground};
|
|
7
|
+
color:${p => p.theme.chipsNeutralTextColor};
|
|
8
|
+
padding:4px 8px;
|
|
9
|
+
width:auto;
|
|
10
|
+
box-sizing: border-box;
|
|
11
|
+
border-radius:30px;
|
|
12
|
+
`;
|
|
13
|
+
export const ChipsLabel = styled.div `
|
|
14
|
+
font-size:${Theme.fontSize.s}
|
|
15
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Chips';
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { ThemeProvider } from 'styled-components';
|
|
3
|
+
import { TextAccent } from '../Typography';
|
|
4
|
+
import { Aligment } from '../Aligment';
|
|
5
|
+
import { Icon } from '../Icons';
|
|
6
|
+
import { Modal } from '../Modal';
|
|
7
|
+
import { FilterIconArea, FilterInputWrapper, FiltersArea, FilterSection, } from './Filters.styles';
|
|
8
|
+
import { Theme, mainTheme } from '../../Theme';
|
|
9
|
+
import { PanelOption } from '../common';
|
|
10
|
+
import { Input } from '../Input';
|
|
11
|
+
import { Chips } from '../Chips';
|
|
12
|
+
export const Filters = ({ theme = mainTheme, title = 'Select filters', labelConfirm = 'Approve', labelClose = "Cancel", filters = [], labelClearAll = 'Clear all filters', handleSubmitFilters }) => {
|
|
13
|
+
const generateStateObj = () => {
|
|
14
|
+
const obj = {};
|
|
15
|
+
filters.forEach((filter) => {
|
|
16
|
+
obj[filter.name] = {
|
|
17
|
+
name: filter.name,
|
|
18
|
+
type: filter.type,
|
|
19
|
+
value: [],
|
|
20
|
+
rangeMin: filter.min,
|
|
21
|
+
rangeMax: filter.max,
|
|
22
|
+
min: '',
|
|
23
|
+
max: '',
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
return obj;
|
|
27
|
+
};
|
|
28
|
+
const [openFilters, setOpenFilters] = useState(false);
|
|
29
|
+
const [activeFilters, setActiveFilters] = useState(generateStateObj());
|
|
30
|
+
const toogleFilter = () => {
|
|
31
|
+
setOpenFilters(!openFilters);
|
|
32
|
+
};
|
|
33
|
+
const isFilterActive = (filter) => {
|
|
34
|
+
let isActive = false;
|
|
35
|
+
if (filter.type === 'select') {
|
|
36
|
+
isActive = filter.value.length > 0;
|
|
37
|
+
}
|
|
38
|
+
else if (filter.type === 'range') {
|
|
39
|
+
isActive = filter.min.length > 0 || filter.max.length > 0;
|
|
40
|
+
}
|
|
41
|
+
return isActive;
|
|
42
|
+
};
|
|
43
|
+
const isAnyFilterActive = () => {
|
|
44
|
+
const activs = Object.keys(activeFilters).find((key) => isFilterActive(activeFilters[key]));
|
|
45
|
+
if (activs) {
|
|
46
|
+
return activs.length > 0;
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
};
|
|
50
|
+
const setIconColor = () => {
|
|
51
|
+
return isAnyFilterActive() ? theme.action : theme.textColor;
|
|
52
|
+
};
|
|
53
|
+
const clearAll = () => {
|
|
54
|
+
const resetedFilter = { ...activeFilters };
|
|
55
|
+
Object.keys(resetedFilter).forEach((key) => {
|
|
56
|
+
if (resetedFilter[key].type === 'select') {
|
|
57
|
+
resetedFilter[key].value = [];
|
|
58
|
+
}
|
|
59
|
+
else if (resetedFilter[key].type === 'range') {
|
|
60
|
+
resetedFilter[key].min = '';
|
|
61
|
+
resetedFilter[key].max = '';
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return resetedFilter;
|
|
65
|
+
};
|
|
66
|
+
const resetAllFilters = () => {
|
|
67
|
+
const cleared = clearAll();
|
|
68
|
+
setActiveFilters({
|
|
69
|
+
...cleared,
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
const resetAllFiltersAndSubmit = () => {
|
|
73
|
+
resetAllFilters();
|
|
74
|
+
applyFilter();
|
|
75
|
+
};
|
|
76
|
+
const resetFilter = (filterName, filterType) => {
|
|
77
|
+
if (filterType === 'select') {
|
|
78
|
+
setActiveFilters({
|
|
79
|
+
...activeFilters,
|
|
80
|
+
[filterName]: {
|
|
81
|
+
...activeFilters[filterName],
|
|
82
|
+
value: [],
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
if (filterType === 'range') {
|
|
87
|
+
setActiveFilters({
|
|
88
|
+
...activeFilters,
|
|
89
|
+
[filterName]: {
|
|
90
|
+
...activeFilters[filterName],
|
|
91
|
+
min: '',
|
|
92
|
+
max: '',
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const setSelectFilter = (filterValue, filterName) => {
|
|
98
|
+
let values = [];
|
|
99
|
+
const existingValues = activeFilters[filterName].value;
|
|
100
|
+
if (existingValues.includes(filterValue)) {
|
|
101
|
+
values = existingValues.filter((item) => item !== filterValue);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
existingValues.push(filterValue);
|
|
105
|
+
values = [...existingValues];
|
|
106
|
+
}
|
|
107
|
+
setActiveFilters({
|
|
108
|
+
...activeFilters,
|
|
109
|
+
[filterName]: {
|
|
110
|
+
...activeFilters[filterName],
|
|
111
|
+
value: values,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
const setRangeFilter = (name, value) => {
|
|
116
|
+
const filterName = name.split('_')[0];
|
|
117
|
+
const filterParam = name.split('_')[1];
|
|
118
|
+
setActiveFilters({
|
|
119
|
+
...activeFilters,
|
|
120
|
+
[filterName]: {
|
|
121
|
+
...activeFilters[filterName],
|
|
122
|
+
[filterParam]: value,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
const applyFilter = () => {
|
|
127
|
+
const obj = [];
|
|
128
|
+
Object.keys(activeFilters).forEach((key) => {
|
|
129
|
+
if (activeFilters[key].type === 'select') {
|
|
130
|
+
if (activeFilters[key].value.length > 0) {
|
|
131
|
+
obj.push({
|
|
132
|
+
name: activeFilters[key].name,
|
|
133
|
+
type: activeFilters[key].type,
|
|
134
|
+
value: activeFilters[key].value,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else if (activeFilters[key].type === 'range') {
|
|
139
|
+
if (activeFilters[key].min.length > 0 || activeFilters[key].max.length > 0) {
|
|
140
|
+
obj.push({
|
|
141
|
+
name: activeFilters[key].name,
|
|
142
|
+
type: activeFilters[key].type,
|
|
143
|
+
min: activeFilters[key].min.length > 0 ? activeFilters[key].min : undefined,
|
|
144
|
+
max: activeFilters[key].max.length > 0 ? activeFilters[key].max : undefined,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
handleSubmitFilters && handleSubmitFilters(obj);
|
|
150
|
+
setOpenFilters(false);
|
|
151
|
+
};
|
|
152
|
+
return (React.createElement(ThemeProvider, { theme: theme },
|
|
153
|
+
React.createElement(FilterIconArea, null,
|
|
154
|
+
React.createElement(Icon, { name: "filters", onClick: toogleFilter, color: setIconColor() }),
|
|
155
|
+
isAnyFilterActive() && (React.createElement(Chips, { label: labelClearAll, handleClose: resetAllFiltersAndSubmit }))),
|
|
156
|
+
openFilters && (React.createElement(Modal, { title: title, handleConfirm: applyFilter, handleClose: toogleFilter, labelConfirm: labelConfirm, labelClose: labelClose },
|
|
157
|
+
React.createElement(Aligment, { direction: "column", align: 'flex-end' },
|
|
158
|
+
React.createElement(Chips, { handleClose: resetAllFilters, label: labelClearAll }),
|
|
159
|
+
React.createElement(FiltersArea, null, filters.map((filter) => (React.createElement(FilterSection, null,
|
|
160
|
+
React.createElement(Aligment, { wrap: "nowrap" },
|
|
161
|
+
React.createElement(TextAccent, null, filter.label),
|
|
162
|
+
React.createElement(Icon, { name: "close", size: 14, onClick: () => resetFilter(filter.name, filter.type) })),
|
|
163
|
+
filter.type === 'select' && (React.createElement(Aligment, { wrap: "nowrap", direction: "column", align: "flex-start", vPadding: Theme.padding.s }, filter.allowValues?.map((item) => {
|
|
164
|
+
return (React.createElement(PanelOption, { width: "100%", key: item, active: activeFilters[filter.name].value.includes(item), onClick: () => setSelectFilter(item, filter.name) }, item));
|
|
165
|
+
}))),
|
|
166
|
+
filter.type === 'range' && (React.createElement(Aligment, { wrap: "nowrap", direction: "row", align: "flex-start", vPadding: Theme.padding.s, justify: "flex-start", gap: 8 },
|
|
167
|
+
React.createElement(FilterInputWrapper, null,
|
|
168
|
+
React.createElement(Input, { type: "number", name: `${filter.name}_min`, value: activeFilters[filter.name].min, placeholder: activeFilters[filter.name].rangeMin, handleChange: setRangeFilter })),
|
|
169
|
+
React.createElement(FilterInputWrapper, null,
|
|
170
|
+
React.createElement(Input, { type: "number", name: `${filter.name}_max`, value: activeFilters[filter.name].max, placeholder: activeFilters[filter.name].rangeMax, handleChange: setRangeFilter })))))))))))));
|
|
171
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import styled from "styled-components";
|
|
2
|
+
import { Theme } from "../../Theme";
|
|
3
|
+
export const FilterIconArea = styled.div `
|
|
4
|
+
display:flex;
|
|
5
|
+
flex-direction: row;
|
|
6
|
+
align-items: center;
|
|
7
|
+
gap:8px;
|
|
8
|
+
}
|
|
9
|
+
`;
|
|
10
|
+
export const FiltersArea = styled.div `
|
|
11
|
+
width:100%;
|
|
12
|
+
`;
|
|
13
|
+
export const FilterSection = styled.div `
|
|
14
|
+
width:100%;
|
|
15
|
+
display:flex;
|
|
16
|
+
flex-direction:column;
|
|
17
|
+
padding-bottom:${Theme.padding.m}
|
|
18
|
+
`;
|
|
19
|
+
export const FilterOption = styled.div `
|
|
20
|
+
width:100%;
|
|
21
|
+
display:flex;
|
|
22
|
+
flex-direction:column;
|
|
23
|
+
`;
|
|
24
|
+
export const FilterInputWrapper = styled.div `
|
|
25
|
+
width:100px
|
|
26
|
+
`;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export const getUniqueValues = (elements, source) => {
|
|
2
|
+
const result = [...new Set(elements.map((item) => item[source]))];
|
|
3
|
+
return result;
|
|
4
|
+
};
|
|
5
|
+
export const getMinValue = (elements, source) => {
|
|
6
|
+
return Math.min(...elements.map((item) => item[source]));
|
|
7
|
+
};
|
|
8
|
+
export const getMaxValue = (elements, source) => {
|
|
9
|
+
return Math.max(...elements.map((item) => item[source]));
|
|
10
|
+
};
|
|
11
|
+
export const setTableFilterSet = (headers, elements) => {
|
|
12
|
+
const filterSetting = [];
|
|
13
|
+
headers.forEach((filter) => {
|
|
14
|
+
if (filter.filter) {
|
|
15
|
+
filterSetting.push({
|
|
16
|
+
label: filter.name,
|
|
17
|
+
name: filter.valueSource,
|
|
18
|
+
type: filter.filterType ? filter.filterType : 'select',
|
|
19
|
+
allowValues: getUniqueValues(elements, filter.valueSource),
|
|
20
|
+
min: getMinValue(elements, filter.valueSource),
|
|
21
|
+
max: getMaxValue(elements, filter.valueSource),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return filterSetting;
|
|
26
|
+
};
|
|
27
|
+
export const applyFiltersToTable = (elements, filters) => {
|
|
28
|
+
let filtered = [...elements];
|
|
29
|
+
filters.forEach((filter) => {
|
|
30
|
+
if (filter.type === 'select') {
|
|
31
|
+
filtered = filtered.filter((item) => filter.value?.includes(item[filter.name]));
|
|
32
|
+
}
|
|
33
|
+
else if (filter.type === 'range') {
|
|
34
|
+
filtered = filtered.filter((item) => {
|
|
35
|
+
const minValue = filter.min ? filter.min : item[filter.name];
|
|
36
|
+
const maxValue = filter.max ? filter.max : item[filter.name];
|
|
37
|
+
return (item[filter.name] >= minValue &&
|
|
38
|
+
item[filter.name] <= maxValue);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
return filtered;
|
|
43
|
+
};
|
|
@@ -24,4 +24,6 @@ export const iconsPath = {
|
|
|
24
24
|
check_circle: "m10.6 16.6 7.05-7.05-1.4-1.4-5.65 5.65-2.85-2.85-1.4 1.4ZM12 22q-2.075 0-3.9-.788-1.825-.787-3.175-2.137-1.35-1.35-2.137-3.175Q2 14.075 2 12t.788-3.9q.787-1.825 2.137-3.175 1.35-1.35 3.175-2.138Q9.925 2 12 2t3.9.787q1.825.788 3.175 2.138 1.35 1.35 2.137 3.175Q22 9.925 22 12t-.788 3.9q-.787 1.825-2.137 3.175-1.35 1.35-3.175 2.137Q14.075 22 12 22Zm0-2q3.35 0 5.675-2.325Q20 15.35 20 12q0-3.35-2.325-5.675Q15.35 4 12 4 8.65 4 6.325 6.325 4 8.65 4 12q0 3.35 2.325 5.675Q8.65 20 12 20Zm0-8Z",
|
|
25
25
|
check_box: "m10.6 16.2 7.05-7.05-1.4-1.4-5.65 5.65-2.85-2.85-1.4 1.4ZM5 21q-.825 0-1.413-.587Q3 19.825 3 19V5q0-.825.587-1.413Q4.175 3 5 3h14q.825 0 1.413.587Q21 4.175 21 5v14q0 .825-.587 1.413Q19.825 21 19 21Zm0-2h14V5H5v14ZM5 5v14V5Z",
|
|
26
26
|
check: "m9.55 18-5.7-5.7 1.425-1.425L9.55 15.15l9.175-9.175L20.15 7.4Z",
|
|
27
|
+
arrow_drop_down: 'M7 14L12 9L17 14H7Z',
|
|
28
|
+
arrow_drop_up: 'M12 15L7 10H17L12 15Z',
|
|
27
29
|
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { ThemeProvider } from 'styled-components';
|
|
3
|
+
import { TableCell, TableHead, TableHeaderCell, TableHeaderSortIcon, TableRow, TableTopBar, TableWrapper, } from './Table.styles';
|
|
4
|
+
import { mainTheme } from '../../Theme';
|
|
5
|
+
import { format } from 'date-fns';
|
|
6
|
+
import { Icon } from '../Icons';
|
|
7
|
+
import { Aligment } from '../Aligment';
|
|
8
|
+
import { Filters, setTableFilterSet } from '../Filters';
|
|
9
|
+
import { applySort, setElements, setSortParams } from './tableHelper';
|
|
10
|
+
import { Chips } from '../Chips';
|
|
11
|
+
export const Table = ({ theme = mainTheme, headers, elements,
|
|
12
|
+
// isBulkAction = false,
|
|
13
|
+
hover = true, selectable = true, sortable = true, filtrable = false, sort = {
|
|
14
|
+
name: '',
|
|
15
|
+
order: 'none',
|
|
16
|
+
}, filters = [],
|
|
17
|
+
// haveMore = false,
|
|
18
|
+
// moreActions = [],
|
|
19
|
+
onRowClick, filtersTitle = 'Select filters', filtersConfirmLabel = 'Approve', filtersCancelLabel = 'Cancel', filterClearAllLabel = 'Clear all filters', sortClearLabel = 'Clear sorting', }) => {
|
|
20
|
+
const [tableProps, setTableProps] = useState({
|
|
21
|
+
elements: setElements(elements, sort, filters),
|
|
22
|
+
sort: sort,
|
|
23
|
+
filters: filters,
|
|
24
|
+
});
|
|
25
|
+
const [selectedRow, setSelectedRow] = useState('');
|
|
26
|
+
const handleRowClick = (id) => {
|
|
27
|
+
if (selectable) {
|
|
28
|
+
setSelectedRow(id);
|
|
29
|
+
}
|
|
30
|
+
onRowClick && onRowClick(id);
|
|
31
|
+
};
|
|
32
|
+
const handleHeaderCellClick = (targetValue) => {
|
|
33
|
+
if (sortable) {
|
|
34
|
+
const newSort = setSortParams(targetValue, tableProps.sort);
|
|
35
|
+
setTableProps({
|
|
36
|
+
...tableProps,
|
|
37
|
+
elements: applySort(newSort, tableProps.elements),
|
|
38
|
+
sort: newSort,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const handleFilters = (newFilters) => {
|
|
43
|
+
setTableProps({
|
|
44
|
+
...tableProps,
|
|
45
|
+
elements: setElements(elements, tableProps.sort, newFilters),
|
|
46
|
+
filters: newFilters,
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
const resetSorting = () => {
|
|
50
|
+
setTableProps({
|
|
51
|
+
...tableProps,
|
|
52
|
+
elements: setElements(elements, { name: '', order: 'asc' }, tableProps.filters),
|
|
53
|
+
sort: {
|
|
54
|
+
name: '',
|
|
55
|
+
order: 'asc',
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
return (React.createElement(ThemeProvider, { theme: theme },
|
|
60
|
+
(filtrable || sortable) && (React.createElement(TableTopBar, null,
|
|
61
|
+
React.createElement(Aligment, { justify: "flex-start", gap: 10 },
|
|
62
|
+
filtrable && (React.createElement(Filters, { title: filtersTitle, labelConfirm: filtersConfirmLabel, labelClose: filtersCancelLabel, labelClearAll: filterClearAllLabel, handleSubmitFilters: handleFilters, filters: setTableFilterSet(headers, elements) })),
|
|
63
|
+
sortable && tableProps.sort.name !== '' && (React.createElement(Chips, { label: sortClearLabel, handleClose: resetSorting }))))),
|
|
64
|
+
React.createElement(TableWrapper, { cellPadding: "0", cellSpacing: "0" },
|
|
65
|
+
React.createElement(TableHead, null,
|
|
66
|
+
React.createElement(TableRow, { hover: false, selectable: false, active: false }, headers.map((header) => (React.createElement(TableHeaderCell, { key: header.name, sortable: sortable, onClick: () => handleHeaderCellClick(header.valueSource), isSorted: tableProps.sort.name === header.valueSource &&
|
|
67
|
+
tableProps.sort.order != 'none' },
|
|
68
|
+
header.name,
|
|
69
|
+
tableProps.sort.name === header.valueSource &&
|
|
70
|
+
tableProps.sort.order != 'none' && (React.createElement(TableHeaderSortIcon, null,
|
|
71
|
+
React.createElement(Icon, { name: tableProps.sort.order === 'asc'
|
|
72
|
+
? 'arrow_drop_down'
|
|
73
|
+
: 'arrow_drop_up', color: theme.tableCellSortIcon, size: 20 })))))))),
|
|
74
|
+
React.createElement("tbody", null, tableProps.elements.map((item) => (React.createElement(TableRow, { key: item.id, hover: hover, active: selectedRow === item.id, selectable: selectable, onClick: () => handleRowClick(item.id) }, headers.map((header) => {
|
|
75
|
+
return (React.createElement(TableCell, { key: `${item.id}-${header.name}` }, header.date
|
|
76
|
+
? format(item[header.valueSource], 'dd-MM-yyyy')
|
|
77
|
+
: item[header.valueSource]));
|
|
78
|
+
// }
|
|
79
|
+
}))))))));
|
|
80
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import styled from 'styled-components';
|
|
2
|
+
export const TableWrapper = styled.table `
|
|
3
|
+
width: 100%;
|
|
4
|
+
`;
|
|
5
|
+
export const TableHead = styled.thead `
|
|
6
|
+
tr:first-child {
|
|
7
|
+
position: sticky;
|
|
8
|
+
top: 0;
|
|
9
|
+
}
|
|
10
|
+
`;
|
|
11
|
+
export const TableHeaderCell = styled.th `
|
|
12
|
+
font-weight: bold;
|
|
13
|
+
text-align: left;
|
|
14
|
+
padding: 8px;
|
|
15
|
+
transition: 300ms;
|
|
16
|
+
font-size: 14px;
|
|
17
|
+
background-color: ${(p) => p.isSorted ? p.theme.tableHeaderActiveBackground : p.theme.tableHeaderBackground};
|
|
18
|
+
border-bottom: 1px solid ${(p) => p.theme.tableBorderColor};
|
|
19
|
+
|
|
20
|
+
:hover {
|
|
21
|
+
background-color: ${(p) => p.isSorted ? p.theme.tableHeaderActiveBackground : p.theme.tableHeaderBackground};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
${(p) => p.sortable &&
|
|
25
|
+
`
|
|
26
|
+
cursor:pointer;
|
|
27
|
+
`}
|
|
28
|
+
position:relative;
|
|
29
|
+
|
|
30
|
+
`;
|
|
31
|
+
export const TableHeaderSortIcon = styled.div `
|
|
32
|
+
width: 20px;
|
|
33
|
+
height: 20px;
|
|
34
|
+
position:absolute;
|
|
35
|
+
right:0;
|
|
36
|
+
transition: 300ms;
|
|
37
|
+
top: calc(50% - 10px);
|
|
38
|
+
`;
|
|
39
|
+
export const TableRow = styled.tr `
|
|
40
|
+
background-color: ${(p) => p.active ? p.theme.tableCellActiveBackground : p.theme.tableCellBackground};
|
|
41
|
+
:nth-child(even) {
|
|
42
|
+
background-color: ${(p) => p.active
|
|
43
|
+
? p.theme.tableCellActiveBackground
|
|
44
|
+
: p.theme.tableCellEvenBackground};
|
|
45
|
+
transition: 300ms;
|
|
46
|
+
}
|
|
47
|
+
${(p) => p.selectable &&
|
|
48
|
+
`
|
|
49
|
+
cursor:pointer;`}
|
|
50
|
+
${(p) => p.hover &&
|
|
51
|
+
`
|
|
52
|
+
:hover{
|
|
53
|
+
background-color:${p.theme.tableCellHoverBackground};
|
|
54
|
+
}
|
|
55
|
+
`}
|
|
56
|
+
`;
|
|
57
|
+
export const TableCell = styled.td `
|
|
58
|
+
padding: 8px;
|
|
59
|
+
border-bottom: 1px solid ${(p) => p.theme.tableBorderColor};
|
|
60
|
+
`;
|
|
61
|
+
export const TableTopBar = styled.div `
|
|
62
|
+
padding-bottom:4px;
|
|
63
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Table';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { orderBy } from 'lodash';
|
|
2
|
+
import { applyFiltersToTable } from '../Filters';
|
|
3
|
+
export const setSortParams = (target, sort) => {
|
|
4
|
+
const newSort = {
|
|
5
|
+
name: target,
|
|
6
|
+
order: target === sort.name ? (sort.order === 'asc' ? 'desc' : 'asc') : 'asc',
|
|
7
|
+
};
|
|
8
|
+
return newSort;
|
|
9
|
+
};
|
|
10
|
+
export const applySort = (sort, elements) => {
|
|
11
|
+
let sorted = [...elements];
|
|
12
|
+
if (sort.name !== '') {
|
|
13
|
+
sorted = orderBy(sorted, sort.name, sort.order);
|
|
14
|
+
}
|
|
15
|
+
return sorted;
|
|
16
|
+
};
|
|
17
|
+
export const setElements = (elements, sort, filters) => {
|
|
18
|
+
let tableElements = [...applyFiltersToTable(elements, filters)];
|
|
19
|
+
if (sort.name !== '') {
|
|
20
|
+
tableElements = applySort(sort, tableElements);
|
|
21
|
+
}
|
|
22
|
+
return tableElements;
|
|
23
|
+
};
|
|
@@ -41,7 +41,7 @@ export const TextLabel = styled.div `
|
|
|
41
41
|
${(p) => p.size && p.labelPosition === 'left'
|
|
42
42
|
? setLabelFontSize(p.size)
|
|
43
43
|
: `
|
|
44
|
-
font-size: ${Theme.fontSize.
|
|
45
|
-
line-height: ${Theme.lineHeight.
|
|
44
|
+
font-size: ${Theme.fontSize.s};
|
|
45
|
+
line-height: ${Theme.lineHeight.s};
|
|
46
46
|
`}
|
|
47
47
|
`;
|
package/dist/esm/index.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export * from './components/Aligment';
|
|
2
2
|
export * from './components/Button';
|
|
3
3
|
export * from './components/Card';
|
|
4
|
+
export * from './components/Chips';
|
|
4
5
|
export * from './components/Dropdown';
|
|
5
6
|
export * from './components/DropdownMenu';
|
|
6
7
|
export * from './components/ElementHeader';
|
|
7
8
|
export * from './components/DropdownMenu';
|
|
8
9
|
export * from './components/File';
|
|
10
|
+
export * from './components/Filters';
|
|
9
11
|
export * from './components/Icons';
|
|
10
12
|
export * from "./components/Input";
|
|
11
13
|
export * from './components/Loader';
|
|
@@ -13,5 +15,6 @@ export * from './components/Modal';
|
|
|
13
15
|
export * from './components/Section';
|
|
14
16
|
export * from './components/Selector';
|
|
15
17
|
export * from './components/Sidepanel';
|
|
18
|
+
export * from './components/Table';
|
|
16
19
|
export * from './components/Tile';
|
|
17
20
|
export * from './components/Typography';
|
|
@@ -8,6 +8,7 @@ export declare const Theme: {
|
|
|
8
8
|
black: string;
|
|
9
9
|
gray_1: string;
|
|
10
10
|
gray_2: string;
|
|
11
|
+
gray_3: string;
|
|
11
12
|
overlayer: string;
|
|
12
13
|
red: string;
|
|
13
14
|
};
|
|
@@ -71,4 +72,14 @@ export declare const mainTheme: {
|
|
|
71
72
|
contentBackground: string;
|
|
72
73
|
optionActiveColor: string;
|
|
73
74
|
optionHoverBackground: string;
|
|
75
|
+
tableBorderColor: string;
|
|
76
|
+
tableHeaderBackground: string;
|
|
77
|
+
tableHeaderActiveBackground: string;
|
|
78
|
+
tableCellBackground: string;
|
|
79
|
+
tableCellEvenBackground: string;
|
|
80
|
+
tableCellHoverBackground: string;
|
|
81
|
+
tableCellActiveBackground: string;
|
|
82
|
+
tableCellSortIcon: string;
|
|
83
|
+
chipsNeutralBackground: string;
|
|
84
|
+
chipsNeutralTextColor: string;
|
|
74
85
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
interface IChipsElementProps {
|
|
2
|
+
theme: any;
|
|
3
|
+
}
|
|
4
|
+
export declare const ChipsElement: import("styled-components").StyledComponent<"div", any, IChipsElementProps, never>;
|
|
5
|
+
export declare const ChipsLabel: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Chips';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
export interface IApplyFilterResults {
|
|
3
|
+
name: string;
|
|
4
|
+
type: string;
|
|
5
|
+
value?: string[];
|
|
6
|
+
min?: number;
|
|
7
|
+
max?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface IFilterProps {
|
|
10
|
+
label: string;
|
|
11
|
+
name: string;
|
|
12
|
+
type: 'select' | 'range' | string;
|
|
13
|
+
allowValues?: string[] | number[];
|
|
14
|
+
min?: number;
|
|
15
|
+
max?: number;
|
|
16
|
+
}
|
|
17
|
+
interface IFiltersProps {
|
|
18
|
+
theme?: any;
|
|
19
|
+
title: string;
|
|
20
|
+
labelConfirm: string;
|
|
21
|
+
labelClose: string;
|
|
22
|
+
filters: IFilterProps[];
|
|
23
|
+
labelClearAll: string;
|
|
24
|
+
handleSubmitFilters: (filters: IApplyFilterResults[]) => void;
|
|
25
|
+
}
|
|
26
|
+
export declare const Filters: FC<IFiltersProps>;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const FilterIconArea: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
2
|
+
export declare const FiltersArea: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
3
|
+
export declare const FilterSection: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
4
|
+
export declare const FilterOption: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
5
|
+
export declare const FilterInputWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ITableHeaderProps, ITableElementProps } from '../Table';
|
|
2
|
+
import { IApplyFilterResults, IFilterProps } from './Filters';
|
|
3
|
+
export declare type TAllowValues = 'string' | 'number';
|
|
4
|
+
export declare const getUniqueValues: (elements: ITableElementProps[], source: string) => string[];
|
|
5
|
+
export declare const getMinValue: (elements: ITableElementProps[], source: string) => number;
|
|
6
|
+
export declare const getMaxValue: (elements: ITableElementProps[], source: string) => number;
|
|
7
|
+
export declare const setTableFilterSet: (headers: ITableHeaderProps[], elements: ITableElementProps[]) => IFilterProps[];
|
|
8
|
+
export declare const applyFiltersToTable: (elements: ITableElementProps[], filters: IApplyFilterResults[]) => ITableElementProps[];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { IApplyFilterResults } from '../Filters';
|
|
3
|
+
export interface ITableHeaderProps {
|
|
4
|
+
name: string;
|
|
5
|
+
valueSource: string;
|
|
6
|
+
sort?: boolean;
|
|
7
|
+
date?: boolean;
|
|
8
|
+
filter?: boolean;
|
|
9
|
+
filterType?: 'select' | 'range';
|
|
10
|
+
}
|
|
11
|
+
export interface ITableElementProps {
|
|
12
|
+
[key: string]: number | string;
|
|
13
|
+
}
|
|
14
|
+
export interface ITableSortProps {
|
|
15
|
+
name: string;
|
|
16
|
+
order: string;
|
|
17
|
+
}
|
|
18
|
+
interface ITableProps {
|
|
19
|
+
theme?: any;
|
|
20
|
+
headers: ITableHeaderProps[];
|
|
21
|
+
elements: ITableElementProps[];
|
|
22
|
+
hover?: boolean;
|
|
23
|
+
selectable?: boolean;
|
|
24
|
+
sortable?: boolean;
|
|
25
|
+
filtrable?: boolean;
|
|
26
|
+
sort?: ITableSortProps;
|
|
27
|
+
filters?: IApplyFilterResults[];
|
|
28
|
+
onRowClick?: (id: string) => void;
|
|
29
|
+
filtersTitle?: string;
|
|
30
|
+
filtersConfirmLabel?: string;
|
|
31
|
+
filtersCancelLabel?: string;
|
|
32
|
+
filterClearAllLabel?: string;
|
|
33
|
+
sortClearLabel?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare const Table: FC<ITableProps>;
|
|
36
|
+
export {};
|