next-helios-fe 1.6.13 → 1.6.15
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
@@ -13,9 +13,11 @@ export interface DateProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
13
13
|
}
|
14
14
|
|
15
15
|
export const Date: React.FC<DateProps> = ({ options, label, ...rest }) => {
|
16
|
-
const [tempValue, setTempValue] = useState<any>([
|
16
|
+
const [tempValue, setTempValue] = useState<any>([
|
17
|
+
dayjs().startOf("day"),
|
18
|
+
dayjs().endOf("day"),
|
19
|
+
]);
|
17
20
|
const [selectedRange, setSelectedRange] = useState<string | any[]>("Today");
|
18
|
-
const [manualDate, setManualDate] = useState<any>("");
|
19
21
|
const dropdownRef = useRef<HTMLButtonElement>(null);
|
20
22
|
const width = options?.width === "fit" ? "w-fit" : "w-full";
|
21
23
|
const height =
|
@@ -25,16 +27,6 @@ export const Date: React.FC<DateProps> = ({ options, label, ...rest }) => {
|
|
25
27
|
? "py-2"
|
26
28
|
: "py-1.5";
|
27
29
|
|
28
|
-
useEffect(() => {
|
29
|
-
if (rest.value) {
|
30
|
-
setTempValue(rest.value as any);
|
31
|
-
return;
|
32
|
-
} else if (rest.defaultValue) {
|
33
|
-
setTempValue(rest.defaultValue as any);
|
34
|
-
return;
|
35
|
-
}
|
36
|
-
}, [rest.value, rest.defaultValue]);
|
37
|
-
|
38
30
|
useEffect(() => {
|
39
31
|
rest.onChange &&
|
40
32
|
rest.onChange({
|
@@ -62,9 +54,7 @@ export const Date: React.FC<DateProps> = ({ options, label, ...rest }) => {
|
|
62
54
|
type="text"
|
63
55
|
className={`accent-primary w-full px-4 border-default border rounded-md bg-secondary-bg placeholder:duration-300 placeholder:translate-x-0 focus:placeholder:translate-x-1 placeholder:text-slate-300 focus:outline-none focus:ring-1 focus:ring-primary focus:shadow focus:shadow-primary focus:border-primary-dark disabled:bg-secondary-light disabled:text-slate-400 ${height}`}
|
64
56
|
value={
|
65
|
-
selectedRange === "
|
66
|
-
? manualDate
|
67
|
-
: selectedRange === "Custom"
|
57
|
+
selectedRange === "Custom"
|
68
58
|
? `${
|
69
59
|
dayjs(tempValue[0]).format("MMM YYYY") ===
|
70
60
|
dayjs(tempValue[1]).format("MMM YYYY")
|
@@ -73,15 +63,6 @@ export const Date: React.FC<DateProps> = ({ options, label, ...rest }) => {
|
|
73
63
|
} - ${dayjs(tempValue[1]).format("DD MMM YYYY")}`
|
74
64
|
: selectedRange
|
75
65
|
}
|
76
|
-
onChange={(e) => {
|
77
|
-
setManualDate(e.target.value);
|
78
|
-
}}
|
79
|
-
onKeyDown={(e) => {
|
80
|
-
if (e.key === "Backspace" && selectedRange !== "Manual Input") {
|
81
|
-
setSelectedRange("Manual Input");
|
82
|
-
}
|
83
|
-
}}
|
84
|
-
{...rest}
|
85
66
|
/>
|
86
67
|
<button
|
87
68
|
type="button"
|
@@ -112,21 +93,12 @@ export const Date: React.FC<DateProps> = ({ options, label, ...rest }) => {
|
|
112
93
|
>
|
113
94
|
<div className="flex gap-2 w-80 md:w-full overflow-auto md:overflow-clip">
|
114
95
|
<div className="w-full">
|
115
|
-
{/* <button
|
116
|
-
className="min-w-40 w-full my-0.5 px-4 py-2 rounded-md text-sm text-left hover:bg-secondary-light disabled:bg-primary-transparent disabled:text-primary"
|
117
|
-
disabled={tempValue === "Manual Input"}
|
118
|
-
onClick={() => {
|
119
|
-
setTempValue("Manual Input");
|
120
|
-
}}
|
121
|
-
>
|
122
|
-
Manual Input
|
123
|
-
</button> */}
|
124
96
|
<button
|
125
97
|
className="min-w-40 w-full my-0.5 px-4 py-2 rounded-md text-sm text-left hover:bg-secondary-light disabled:bg-primary-transparent disabled:text-primary"
|
126
98
|
disabled={selectedRange === "Today"}
|
127
99
|
onClick={() => {
|
128
100
|
setSelectedRange("Today");
|
129
|
-
setTempValue([dayjs(), dayjs()]);
|
101
|
+
setTempValue([dayjs().startOf("day"), dayjs().endOf("day")]);
|
130
102
|
}}
|
131
103
|
>
|
132
104
|
Today
|
@@ -137,8 +109,8 @@ export const Date: React.FC<DateProps> = ({ options, label, ...rest }) => {
|
|
137
109
|
onClick={() => {
|
138
110
|
setSelectedRange("Yesterday");
|
139
111
|
setTempValue([
|
140
|
-
dayjs().subtract(1, "days"),
|
141
|
-
dayjs().subtract(1, "days"),
|
112
|
+
dayjs().subtract(1, "days").startOf("day"),
|
113
|
+
dayjs().subtract(1, "days").endOf("day"),
|
142
114
|
]);
|
143
115
|
}}
|
144
116
|
>
|
@@ -149,7 +121,10 @@ export const Date: React.FC<DateProps> = ({ options, label, ...rest }) => {
|
|
149
121
|
disabled={selectedRange === "Last 7 days"}
|
150
122
|
onClick={() => {
|
151
123
|
setSelectedRange("Last 7 days");
|
152
|
-
setTempValue([
|
124
|
+
setTempValue([
|
125
|
+
dayjs().subtract(7, "days").startOf("day"),
|
126
|
+
dayjs().endOf("day"),
|
127
|
+
]);
|
153
128
|
}}
|
154
129
|
>
|
155
130
|
Last 7 days
|
@@ -159,7 +134,10 @@ export const Date: React.FC<DateProps> = ({ options, label, ...rest }) => {
|
|
159
134
|
disabled={selectedRange === "Last 30 days"}
|
160
135
|
onClick={() => {
|
161
136
|
setSelectedRange("Last 30 days");
|
162
|
-
setTempValue([
|
137
|
+
setTempValue([
|
138
|
+
dayjs().subtract(1, "months").startOf("day"),
|
139
|
+
dayjs().endOf("day"),
|
140
|
+
]);
|
163
141
|
}}
|
164
142
|
>
|
165
143
|
Last 30 days
|
@@ -169,7 +147,7 @@ export const Date: React.FC<DateProps> = ({ options, label, ...rest }) => {
|
|
169
147
|
disabled={selectedRange === "Custom"}
|
170
148
|
onClick={() => {
|
171
149
|
setSelectedRange("Custom");
|
172
|
-
setTempValue([dayjs(), dayjs()]);
|
150
|
+
setTempValue([dayjs().startOf("day"), dayjs().endOf("day")]);
|
173
151
|
}}
|
174
152
|
>
|
175
153
|
Custom
|
@@ -180,7 +158,7 @@ export const Date: React.FC<DateProps> = ({ options, label, ...rest }) => {
|
|
180
158
|
value={tempValue}
|
181
159
|
onChange={(value) => {
|
182
160
|
setSelectedRange("Custom");
|
183
|
-
setTempValue(value);
|
161
|
+
setTempValue([dayjs(value[0]), dayjs(value[1])]);
|
184
162
|
}}
|
185
163
|
/>
|
186
164
|
</div>
|
@@ -1,13 +1,10 @@
|
|
1
1
|
"use client";
|
2
2
|
import React, { useState, useEffect, useRef } from "react";
|
3
|
+
import { Dropdown } from "../../../components";
|
3
4
|
import { Icon } from "@iconify/react";
|
4
|
-
import { createPortal } from "react-dom";
|
5
5
|
|
6
6
|
export interface MultipleSelectProps
|
7
|
-
extends Omit<
|
8
|
-
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
9
|
-
"onChange" | "value"
|
10
|
-
> {
|
7
|
+
extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange" | "value"> {
|
11
8
|
options?: {
|
12
9
|
width?: "full" | "fit";
|
13
10
|
height?: "short" | "medium" | "high";
|
@@ -20,6 +17,7 @@ export interface MultipleSelectProps
|
|
20
17
|
}[];
|
21
18
|
placeholder?: string;
|
22
19
|
required?: boolean;
|
20
|
+
disabled?: boolean;
|
23
21
|
value?: string[];
|
24
22
|
onClick?: () => void;
|
25
23
|
onChange?: (e: {
|
@@ -35,6 +33,7 @@ export const MultipleSelect: React.FC<MultipleSelectProps> = ({
|
|
35
33
|
menus,
|
36
34
|
placeholder,
|
37
35
|
required,
|
36
|
+
disabled,
|
38
37
|
value,
|
39
38
|
onClick,
|
40
39
|
onChange,
|
@@ -42,13 +41,10 @@ export const MultipleSelect: React.FC<MultipleSelectProps> = ({
|
|
42
41
|
}) => {
|
43
42
|
const [tempValue, setTempValue] = useState<string[]>([]);
|
44
43
|
const [openDropdown, setOpenDropdown] = useState(false);
|
45
|
-
const [position, setPosition] = useState<{
|
46
|
-
top: number;
|
47
|
-
left: number;
|
48
|
-
} | null>(null);
|
49
44
|
const [dropdownWidth, setDropdownWidth] = useState<number>(0);
|
50
|
-
const
|
51
|
-
const
|
45
|
+
const [dropdownHeight, setDropdownHeight] = useState<number>(0);
|
46
|
+
const inputRef = useRef<HTMLDivElement>(null);
|
47
|
+
const dropdownRef = useRef<HTMLButtonElement>(null);
|
52
48
|
const width = options?.width === "fit" ? "w-fit" : "w-full";
|
53
49
|
const height =
|
54
50
|
options?.height === "short"
|
@@ -58,51 +54,13 @@ export const MultipleSelect: React.FC<MultipleSelectProps> = ({
|
|
58
54
|
: "py-1";
|
59
55
|
|
60
56
|
useEffect(() => {
|
61
|
-
|
62
|
-
if (
|
63
|
-
dropdownRef.current &&
|
64
|
-
!dropdownRef.current.contains(e.target as Node) &&
|
65
|
-
!triggerRef.current?.contains(e.target as Node)
|
66
|
-
) {
|
57
|
+
document.addEventListener("mousedown", (e) => {
|
58
|
+
if (e.target instanceof HTMLElement) {
|
67
59
|
setOpenDropdown(false);
|
68
60
|
}
|
69
|
-
};
|
70
|
-
|
71
|
-
document.addEventListener("mousedown", handleClickOutside);
|
72
|
-
return () => {
|
73
|
-
document.removeEventListener("mousedown", handleClickOutside);
|
74
|
-
};
|
61
|
+
});
|
75
62
|
}, []);
|
76
63
|
|
77
|
-
useEffect(() => {
|
78
|
-
if (triggerRef.current) {
|
79
|
-
const rect = triggerRef.current.getBoundingClientRect();
|
80
|
-
const dropdownHeight = dropdownRef.current?.offsetHeight || 0;
|
81
|
-
const windowHeight = window.innerHeight;
|
82
|
-
|
83
|
-
setPosition({
|
84
|
-
top: rect.bottom + window.scrollY + 10,
|
85
|
-
left: rect.left + window.scrollX,
|
86
|
-
});
|
87
|
-
|
88
|
-
setDropdownWidth(rect.width);
|
89
|
-
|
90
|
-
if (rect.bottom + dropdownHeight > windowHeight) {
|
91
|
-
setPosition((prev) =>
|
92
|
-
prev
|
93
|
-
? { ...prev, top: rect.top + window.scrollY - dropdownHeight - 10 }
|
94
|
-
: null
|
95
|
-
);
|
96
|
-
}
|
97
|
-
}
|
98
|
-
|
99
|
-
if (openDropdown) {
|
100
|
-
document.getElementById("body")!.style.overflow = "hidden";
|
101
|
-
} else {
|
102
|
-
document.getElementById("body")!.style.overflow = "auto";
|
103
|
-
}
|
104
|
-
}, [openDropdown]);
|
105
|
-
|
106
64
|
useEffect(() => {
|
107
65
|
if (value) {
|
108
66
|
setTempValue(value);
|
@@ -118,94 +76,154 @@ export const MultipleSelect: React.FC<MultipleSelectProps> = ({
|
|
118
76
|
}, [tempValue]);
|
119
77
|
|
120
78
|
return (
|
121
|
-
<
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
<
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
79
|
+
<div className="flex flex-row-reverse items-end">
|
80
|
+
<label className={`grid gap-2 ${width}`}>
|
81
|
+
{label && (
|
82
|
+
<span
|
83
|
+
className={`text-sm select-none ${
|
84
|
+
required && "after:content-['*'] after:ml-1 after:text-danger"
|
85
|
+
}`}
|
86
|
+
>
|
87
|
+
{label}
|
88
|
+
</span>
|
89
|
+
)}
|
90
|
+
<div className="relative flex items-center">
|
91
|
+
<div
|
92
|
+
ref={inputRef}
|
93
|
+
className={`group/button flex justify-between items-center gap-2 w-full min-h-10 px-4 border rounded-md caret-transparent focus:outline-none focus:ring-1 focus:ring-primary focus:shadow focus:shadow-primary focus:border-primary-dark ${height} ${
|
94
|
+
disabled
|
95
|
+
? "bg-secondary-light cursor-default pointer-events-none"
|
96
|
+
: "bg-secondary-bg cursor-pointer"
|
97
|
+
} ${
|
98
|
+
openDropdown
|
99
|
+
? "outline-none ring-1 ring-primary shadow shadow-primary border-primary-dark"
|
100
|
+
: "border-default"
|
101
|
+
}`}
|
102
|
+
onClick={(e) => {
|
103
|
+
e.preventDefault();
|
104
|
+
onClick && onClick();
|
105
|
+
setOpenDropdown(true);
|
106
|
+
dropdownRef.current?.click();
|
107
|
+
setDropdownWidth(
|
108
|
+
inputRef?.current?.getBoundingClientRect()?.width || 0
|
109
|
+
);
|
110
|
+
setDropdownHeight(
|
111
|
+
inputRef?.current?.getBoundingClientRect()?.height || 0
|
112
|
+
);
|
113
|
+
}}
|
114
|
+
{...rest}
|
115
|
+
>
|
116
|
+
{!tempValue || tempValue?.length === 0 ? (
|
117
|
+
<span
|
118
|
+
className={`text-slate-300 select-none duration-300 ${
|
119
|
+
openDropdown ? "translate-x-1" : "translate-x-0"
|
120
|
+
}`}
|
121
|
+
>
|
122
|
+
{placeholder}
|
123
|
+
</span>
|
124
|
+
) : (
|
125
|
+
<div className="flex flex-wrap gap-2 h-min pointer-events-none invisible">
|
126
|
+
{tempValue?.map((item) => {
|
127
|
+
return (
|
155
128
|
<div
|
156
|
-
|
157
|
-
|
158
|
-
setTempValue(tempValue.filter((i) => i !== item));
|
159
|
-
}}
|
129
|
+
key={item}
|
130
|
+
className="flex items-center gap-2 px-2 py-0.5 rounded-md bg-primary text-white cursor-default pointer-events-auto"
|
160
131
|
>
|
161
|
-
<
|
132
|
+
<span>{menus.find((i) => i.value === item)?.label}</span>
|
133
|
+
<div
|
134
|
+
className="cursor-pointer"
|
135
|
+
onClick={() => {
|
136
|
+
setTempValue(tempValue.filter((i) => i !== item));
|
137
|
+
}}
|
138
|
+
>
|
139
|
+
<Icon icon="pajamas:close" />
|
140
|
+
</div>
|
162
141
|
</div>
|
163
|
-
|
164
|
-
)
|
165
|
-
|
142
|
+
);
|
143
|
+
})}
|
144
|
+
</div>
|
145
|
+
)}
|
146
|
+
<div className="ms-auto text-xl text-slate-400 pointer-events-none">
|
147
|
+
<Icon
|
148
|
+
icon={`gravity-ui:chevron-${openDropdown ? "up" : "down"}`}
|
149
|
+
/>
|
166
150
|
</div>
|
167
|
-
)}
|
168
|
-
<div className="text-xl text-slate-400 pointer-events-none">
|
169
|
-
<Icon icon={`gravity-ui:chevron-${openDropdown ? "up" : "down"}`} />
|
170
151
|
</div>
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
152
|
+
<div
|
153
|
+
className="absolute flex flex-wrap gap-2 h-min px-4 pointer-events-none"
|
154
|
+
style={{ width: dropdownWidth - 52 }}
|
155
|
+
>
|
156
|
+
{tempValue?.map((item) => {
|
157
|
+
return (
|
158
|
+
<div
|
159
|
+
key={item}
|
160
|
+
className={`flex items-center gap-2 px-2 py-0.5 rounded-md text-white select-none cursor-default pointer-events-auto ${
|
161
|
+
disabled ? "bg-secondary" : "bg-primary"
|
162
|
+
}`}
|
163
|
+
>
|
164
|
+
<span>{menus.find((i) => i.value === item)?.label}</span>
|
165
|
+
<div
|
166
|
+
className="cursor-pointer active:opacity-70 active:duration-300 active:ease-out disabled:active:opacity-100"
|
167
|
+
onClick={() => {
|
168
|
+
if (!disabled) {
|
169
|
+
setTempValue(tempValue.filter((i) => i !== item));
|
170
|
+
}
|
171
|
+
}}
|
172
|
+
>
|
173
|
+
<Icon icon="pajamas:close" />
|
174
|
+
</div>
|
175
|
+
</div>
|
176
|
+
);
|
177
|
+
})}
|
178
|
+
</div>
|
179
|
+
</div>
|
180
|
+
</label>
|
181
|
+
<div className="w-0 overflow-hidden">
|
182
|
+
<Dropdown
|
183
|
+
placement="bottom-start"
|
184
|
+
dismissOnClick={false}
|
185
|
+
trigger={
|
186
|
+
<button
|
187
|
+
type="button"
|
176
188
|
ref={dropdownRef}
|
177
|
-
className="
|
189
|
+
className="w-0 my-0.5"
|
178
190
|
style={{
|
179
|
-
|
180
|
-
left: position.left,
|
181
|
-
width: dropdownWidth,
|
191
|
+
height: dropdownHeight,
|
182
192
|
}}
|
183
193
|
>
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
194
|
+
1
|
195
|
+
</button>
|
196
|
+
}
|
197
|
+
>
|
198
|
+
<div
|
199
|
+
style={{
|
200
|
+
width: dropdownWidth - 11,
|
201
|
+
}}
|
202
|
+
>
|
203
|
+
{menus.length === 0 ? (
|
204
|
+
<div className="flex justify-center">
|
205
|
+
<span className="px-4 py-1">No data found</span>
|
206
|
+
</div>
|
207
|
+
) : (
|
208
|
+
menus.map((item, index) => (
|
209
|
+
<button
|
210
|
+
key={index}
|
211
|
+
type="button"
|
212
|
+
className="min-w-40 w-full my-0.5 px-4 py-2 rounded-md text-sm text-left text-default hover:bg-secondary-light disabled:bg-primary-transparent"
|
213
|
+
disabled={
|
214
|
+
tempValue?.find((i) => i === item.value) ? true : false
|
215
|
+
}
|
216
|
+
onClick={() => {
|
217
|
+
setTempValue([...tempValue, item.value]);
|
218
|
+
}}
|
219
|
+
>
|
220
|
+
{item.label}
|
221
|
+
</button>
|
222
|
+
))
|
223
|
+
)}
|
224
|
+
</div>
|
225
|
+
</Dropdown>
|
208
226
|
</div>
|
209
|
-
</
|
227
|
+
</div>
|
210
228
|
);
|
211
229
|
};
|