sprint-asia-custom-component 0.1.151 → 0.1.152
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/index.js +138 -58
- package/package.json +1 -1
- package/src/components/filter/filterDropdown/index.js +228 -205
package/package.json
CHANGED
|
@@ -1,229 +1,252 @@
|
|
|
1
|
-
import React, { useState, useEffect, useRef } from
|
|
2
|
-
import { PiFunnel, PiCaretRight, PiX } from
|
|
1
|
+
import React, { useState, useEffect, useRef } from "react";
|
|
2
|
+
import { PiFunnel, PiCaretRight, PiX } from "react-icons/pi";
|
|
3
3
|
|
|
4
|
-
const FilterDropdown = ({
|
|
5
|
-
|
|
4
|
+
const FilterDropdown = ({
|
|
5
|
+
options = [
|
|
6
|
+
{
|
|
7
|
+
menu: "Type",
|
|
8
|
+
parameter: "type",
|
|
9
|
+
submenu: [
|
|
6
10
|
{
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
submenu:[{
|
|
10
|
-
option:"Type 1",
|
|
11
|
-
value : "type1"
|
|
12
|
-
}],
|
|
13
|
-
type:"checkbox"
|
|
11
|
+
option: "Type 1",
|
|
12
|
+
value: "type1",
|
|
14
13
|
},
|
|
14
|
+
],
|
|
15
|
+
type: "checkbox",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
menu: "Status",
|
|
19
|
+
parameter: "status",
|
|
20
|
+
submenu: [
|
|
15
21
|
{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
submenu:[{
|
|
19
|
-
option : "Status 1",
|
|
20
|
-
value : "status1"
|
|
21
|
-
}],
|
|
22
|
-
type:"radiobutton"
|
|
22
|
+
option: "Status 1",
|
|
23
|
+
value: "status1",
|
|
23
24
|
},
|
|
25
|
+
],
|
|
26
|
+
type: "radiobutton",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
menu: "Payment",
|
|
30
|
+
parameter: "payment",
|
|
31
|
+
submenu: [
|
|
24
32
|
{
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
submenu:[{
|
|
28
|
-
option : "Payment 1",
|
|
29
|
-
value : "payment1"
|
|
30
|
-
}],
|
|
31
|
-
type:"checkbox"
|
|
33
|
+
option: "Payment 1",
|
|
34
|
+
value: "payment1",
|
|
32
35
|
},
|
|
36
|
+
],
|
|
37
|
+
type: "checkbox",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
menu: "Payment 2",
|
|
41
|
+
parameter: "payment 2",
|
|
42
|
+
submenu: [
|
|
33
43
|
{
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
submenu:[{
|
|
37
|
-
option : "Payment 2",
|
|
38
|
-
value : "payment2"
|
|
39
|
-
}],
|
|
40
|
-
type:"checkbox"
|
|
44
|
+
option: "Payment 2",
|
|
45
|
+
value: "payment2",
|
|
41
46
|
},
|
|
47
|
+
],
|
|
48
|
+
type: "checkbox",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
menu: "Payment 3",
|
|
52
|
+
parameter: "payment 3",
|
|
53
|
+
submenu: [
|
|
42
54
|
{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
submenu:[{
|
|
46
|
-
option : "Payment 3",
|
|
47
|
-
value : "payment3"
|
|
48
|
-
}],
|
|
49
|
-
type:"checkbox"
|
|
55
|
+
option: "Payment 3",
|
|
56
|
+
value: "payment3",
|
|
50
57
|
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
],
|
|
59
|
+
type: "checkbox",
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
dataFilterResult,
|
|
63
|
+
setDataFilterResult = () => {},
|
|
54
64
|
}) => {
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
const [showFilterMenu, setShowFilterMenu] = useState(false);
|
|
66
|
+
const [showFilterSubmenu, setShowFilterSubmenu] = useState(false);
|
|
57
67
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
68
|
+
const [dataSelectionOptionMenu, setDataSelectionOptionMenu] = useState();
|
|
69
|
+
const [dataFilterCheckbox, setDataFilterCheckbox] = useState([]);
|
|
70
|
+
const [dataFilterStatus, setDataFilterStatus] = useState([]);
|
|
71
|
+
const dropdownRef = useRef(null);
|
|
62
72
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
const handleOutsideClick = (event) => {
|
|
75
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
76
|
+
setShowFilterMenu(false);
|
|
77
|
+
setShowFilterSubmenu(false);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
70
80
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
81
|
+
if (showFilterMenu) {
|
|
82
|
+
document.addEventListener("mousedown", handleOutsideClick);
|
|
83
|
+
}
|
|
74
84
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
85
|
+
return () => {
|
|
86
|
+
document.removeEventListener("mousedown", handleOutsideClick);
|
|
87
|
+
};
|
|
88
|
+
}, [showFilterMenu]);
|
|
79
89
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
setShowFilterSubmenu(false)
|
|
87
|
-
}
|
|
90
|
+
const handleResetFilter = () => {
|
|
91
|
+
const resetDataFilterResult = Object.fromEntries(Object.keys(dataFilterResult).map((key) => [key, []]));
|
|
92
|
+
setDataFilterResult(resetDataFilterResult);
|
|
93
|
+
setShowFilterMenu(false);
|
|
94
|
+
setShowFilterSubmenu(false);
|
|
95
|
+
};
|
|
88
96
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (isSubmenuExist) {
|
|
95
|
-
const index = updatedData.indexOf(submenu.value);
|
|
96
|
-
updatedData.splice(index, 1);
|
|
97
|
-
} else {
|
|
98
|
-
updatedData.push(submenu.value);
|
|
99
|
-
}
|
|
100
|
-
setDataFilterResult(prevState => ({
|
|
101
|
-
...prevState,
|
|
102
|
-
[parameter]: updatedData
|
|
103
|
-
}));
|
|
104
|
-
} else if (type === "radiobutton") {
|
|
105
|
-
if (dataFilterResult[parameter]?.[0] === submenu.value) {
|
|
106
|
-
setDataFilterResult(prevState => ({
|
|
107
|
-
...prevState,
|
|
108
|
-
[parameter]: []
|
|
109
|
-
}));
|
|
110
|
-
} else {
|
|
111
|
-
setDataFilterResult(prevState => ({
|
|
112
|
-
...prevState,
|
|
113
|
-
[parameter]: [submenu.value]
|
|
114
|
-
}));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
};
|
|
97
|
+
const handleOnClickOption = (submenu, type, parameter) => {
|
|
98
|
+
if (type === "checkbox") {
|
|
99
|
+
const isSubmenuExist = dataFilterResult[parameter]?.includes(submenu.value);
|
|
100
|
+
const updatedData = [...(dataFilterResult[parameter] || [])];
|
|
118
101
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
102
|
+
if (isSubmenuExist) {
|
|
103
|
+
const index = updatedData.indexOf(submenu.value);
|
|
104
|
+
updatedData.splice(index, 1);
|
|
105
|
+
} else {
|
|
106
|
+
updatedData.push(submenu.value);
|
|
107
|
+
}
|
|
108
|
+
setDataFilterResult((prevState) => ({
|
|
109
|
+
...prevState,
|
|
110
|
+
[parameter]: updatedData,
|
|
111
|
+
}));
|
|
112
|
+
} else if (type === "radiobutton") {
|
|
113
|
+
if (dataFilterResult[parameter]?.[0] === submenu.value) {
|
|
114
|
+
setDataFilterResult((prevState) => ({
|
|
115
|
+
...prevState,
|
|
116
|
+
[parameter]: [],
|
|
117
|
+
}));
|
|
118
|
+
} else {
|
|
119
|
+
setDataFilterResult((prevState) => ({
|
|
120
|
+
...prevState,
|
|
121
|
+
[parameter]: [submenu.value],
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
123
126
|
|
|
127
|
+
const buttonText =
|
|
128
|
+
Object.values(dataFilterResult).flat().length > 0
|
|
129
|
+
? `${Object.values(dataFilterResult).flat().length} Filter Selected`
|
|
130
|
+
: "Filter";
|
|
124
131
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
132
|
+
return (
|
|
133
|
+
<div>
|
|
134
|
+
<div>
|
|
135
|
+
<span className="rounded-md shadow-sm">
|
|
136
|
+
<div className="flex">
|
|
137
|
+
<button
|
|
138
|
+
type="button"
|
|
139
|
+
className={`${
|
|
140
|
+
Object.values(dataFilterResult).flat().length
|
|
141
|
+
? "border-black text-black"
|
|
142
|
+
: "border-neutral50 text-neutral300"
|
|
143
|
+
} flex items-center w-60 text-left px-4 bg-white font-normal text-sm rounded-md border focus:outline-none`}
|
|
144
|
+
>
|
|
145
|
+
<span className="flex-grow py-2.5" onClick={() => setShowFilterMenu(!showFilterMenu)}>
|
|
146
|
+
{buttonText}
|
|
147
|
+
</span>
|
|
148
|
+
{Object.values(dataFilterResult).flat().length ? (
|
|
149
|
+
<span className="ml-2" onClick={handleResetFilter}>
|
|
150
|
+
<PiX size={16} className="text-black" />
|
|
151
|
+
</span>
|
|
152
|
+
) : (
|
|
153
|
+
<span className="ml-2">
|
|
154
|
+
<PiFunnel size={16} className="text-neutral300" />
|
|
147
155
|
</span>
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
{
|
|
177
|
-
showFilterSubmenu && option.submenu.length > 0 && dataSelectionOptionMenu === option.menu &&
|
|
178
|
-
<div className={`ml-1 border border-neutral40 bg-white p-3 shadow-md rounded-md w-56 absolute left-48 cursor-pointer ${index == 0 && "top-0"} ${index == 1 && "top-16"} ${index == 2 && "top-24"} ${index == 3 && "top-36"} ${index == 4 && "top-48"}`}>
|
|
179
|
-
{
|
|
180
|
-
option.submenu.map((submenu, subIndex) => (
|
|
181
|
-
<div key={subIndex} className='flex bg-white hover:bg-neutral20 rounded-md py-2.5 px-4 my-0.5'
|
|
182
|
-
onClick={() => {
|
|
183
|
-
handleOnClickOption(submenu, option.type, option.parameter)
|
|
184
|
-
}}
|
|
185
|
-
>
|
|
186
|
-
{
|
|
187
|
-
option.type === "checkbox" &&
|
|
188
|
-
<div className='flex items-center'>
|
|
189
|
-
<input
|
|
190
|
-
type='checkbox'
|
|
191
|
-
className='mr-2'
|
|
192
|
-
checked={dataFilterResult[option.parameter]?.includes(submenu.value) || false}
|
|
193
|
-
onChange={() => handleOnClickOption(submenu, option.type, option.parameter)}
|
|
194
|
-
/>
|
|
195
|
-
<p className={`text-sm ${dataFilterResult[option.parameter]?.includes(submenu.value) ? 'text-primary500' : 'text-black'}`}>
|
|
196
|
-
{submenu.option}
|
|
197
|
-
</p>
|
|
198
|
-
</div>
|
|
199
|
-
}
|
|
200
|
-
{
|
|
201
|
-
option.type === "radiobutton" &&
|
|
202
|
-
<div className='flex items-center'>
|
|
203
|
-
<input
|
|
204
|
-
type='radio'
|
|
205
|
-
className='mr-2'
|
|
206
|
-
checked={dataFilterResult[option.parameter]?.[0] === submenu.value}
|
|
207
|
-
onChange={() => handleOnClickOption(submenu, option.type, option.parameter)}
|
|
208
|
-
/>
|
|
209
|
-
<p className={`text-sm ${dataFilterResult[option.parameter]?.[0] === submenu.value ? 'text-primary500' : 'text-black'}`}>
|
|
210
|
-
{submenu.option}
|
|
211
|
-
</p>
|
|
212
|
-
</div>
|
|
213
|
-
}
|
|
214
|
-
</div>
|
|
215
|
-
))
|
|
216
|
-
}
|
|
217
|
-
</div>
|
|
218
|
-
}
|
|
219
|
-
</div>
|
|
220
|
-
))
|
|
221
|
-
}
|
|
222
|
-
</div>
|
|
223
|
-
}
|
|
156
|
+
)}
|
|
157
|
+
</button>
|
|
158
|
+
</div>
|
|
159
|
+
</span>
|
|
160
|
+
</div>
|
|
161
|
+
<div className="relative">
|
|
162
|
+
{showFilterMenu && (
|
|
163
|
+
<div
|
|
164
|
+
ref={dropdownRef}
|
|
165
|
+
className="bg-white border border-neutral40 w-48 rounded-md p-3 top-1 absolute z-10 shadow-md"
|
|
166
|
+
>
|
|
167
|
+
{options.map((option, index) => (
|
|
168
|
+
<div key={index}>
|
|
169
|
+
<div
|
|
170
|
+
className={`hover:bg-neutral20 bg-white py-2.5 px-4 my-0.5 rounded-md flex items-center cursor-pointer justify-between`}
|
|
171
|
+
onClick={() => {
|
|
172
|
+
setShowFilterSubmenu(true);
|
|
173
|
+
setDataSelectionOptionMenu(option.menu);
|
|
174
|
+
}}
|
|
175
|
+
>
|
|
176
|
+
<p>{option.menu}</p>
|
|
177
|
+
{(dataFilterResult[option.parameter]?.length || 0) === 0 ? (
|
|
178
|
+
<PiCaretRight size={16} className="text-neutral300" />
|
|
179
|
+
) : (
|
|
180
|
+
<div className="w-4 h-4 border border-primary500 rounded-full flex items-center justify-center text-primary500">
|
|
181
|
+
<p style={{ fontSize: "8px" }}>{dataFilterResult[option.parameter]?.length || 0}</p>
|
|
182
|
+
</div>
|
|
183
|
+
)}
|
|
224
184
|
</div>
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
185
|
+
{showFilterSubmenu && option.submenu.length > 0 && dataSelectionOptionMenu === option.menu && (
|
|
186
|
+
<div
|
|
187
|
+
className={`ml-1 border border-neutral40 bg-white p-3 shadow-md rounded-md w-56 absolute left-48 cursor-pointer max-h-64 overflow-hidden overflow-y-auto ${
|
|
188
|
+
index == 0 && "top-0"
|
|
189
|
+
} ${index == 1 && "top-16"} ${index == 2 && "top-24"} ${index == 3 && "top-36"} ${
|
|
190
|
+
index == 4 && "top-48"
|
|
191
|
+
}`}
|
|
192
|
+
>
|
|
193
|
+
{option.submenu.map((submenu, subIndex) => (
|
|
194
|
+
<div
|
|
195
|
+
key={subIndex}
|
|
196
|
+
className="flex bg-white hover:bg-neutral20 rounded-md py-2.5 px-4 my-0.5"
|
|
197
|
+
onClick={() => {
|
|
198
|
+
handleOnClickOption(submenu, option.type, option.parameter);
|
|
199
|
+
}}
|
|
200
|
+
>
|
|
201
|
+
{option.type === "checkbox" && (
|
|
202
|
+
<div className="flex items-center">
|
|
203
|
+
<input
|
|
204
|
+
type="checkbox"
|
|
205
|
+
className="mr-2"
|
|
206
|
+
checked={dataFilterResult[option.parameter]?.includes(submenu.value) || false}
|
|
207
|
+
onChange={() => handleOnClickOption(submenu, option.type, option.parameter)}
|
|
208
|
+
/>
|
|
209
|
+
<p
|
|
210
|
+
className={`text-sm ${
|
|
211
|
+
dataFilterResult[option.parameter]?.includes(submenu.value)
|
|
212
|
+
? "text-primary500"
|
|
213
|
+
: "text-black"
|
|
214
|
+
}`}
|
|
215
|
+
>
|
|
216
|
+
{submenu.option}
|
|
217
|
+
</p>
|
|
218
|
+
</div>
|
|
219
|
+
)}
|
|
220
|
+
{option.type === "radiobutton" && (
|
|
221
|
+
<div className="flex items-center">
|
|
222
|
+
<input
|
|
223
|
+
type="radio"
|
|
224
|
+
className="mr-2"
|
|
225
|
+
checked={dataFilterResult[option.parameter]?.[0] === submenu.value}
|
|
226
|
+
onChange={() => handleOnClickOption(submenu, option.type, option.parameter)}
|
|
227
|
+
/>
|
|
228
|
+
<p
|
|
229
|
+
className={`text-sm ${
|
|
230
|
+
dataFilterResult[option.parameter]?.[0] === submenu.value
|
|
231
|
+
? "text-primary500"
|
|
232
|
+
: "text-black"
|
|
233
|
+
}`}
|
|
234
|
+
>
|
|
235
|
+
{submenu.option}
|
|
236
|
+
</p>
|
|
237
|
+
</div>
|
|
238
|
+
)}
|
|
239
|
+
</div>
|
|
240
|
+
))}
|
|
241
|
+
</div>
|
|
242
|
+
)}
|
|
243
|
+
</div>
|
|
244
|
+
))}
|
|
245
|
+
</div>
|
|
246
|
+
)}
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
);
|
|
250
|
+
};
|
|
228
251
|
|
|
229
|
-
export default FilterDropdown;
|
|
252
|
+
export default FilterDropdown;
|