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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-helios-fe",
3
- "version": "1.6.13",
3
+ "version": "1.6.15",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -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>([dayjs(), dayjs()]);
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 === "Manual Input"
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([dayjs().subtract(7, "days"), dayjs()]);
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([dayjs().subtract(1, "months"), dayjs()]);
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 triggerRef = useRef<HTMLDivElement>(null);
51
- const dropdownRef = useRef<HTMLDivElement>(null);
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
- const handleClickOutside = (e: MouseEvent) => {
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
- <label className={`grid gap-2 ${width}`}>
122
- {label && (
123
- <span
124
- className={`text-sm select-none ${
125
- required && "after:content-['*'] after:ml-1 after:text-danger"
126
- }`}
127
- >
128
- {label}
129
- </span>
130
- )}
131
- <div className="relative" ref={triggerRef}>
132
- <button
133
- type="button"
134
- className={`group/button flex justify-between items-center gap-2 w-full min-h-10 px-4 border-default border rounded-md bg-secondary-bg cursor-pointer caret-transparent 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 disabled:cursor-default ${height}`}
135
- disabled={rest.disabled}
136
- onClick={() => {
137
- onClick && onClick();
138
- setOpenDropdown(true);
139
- }}
140
- {...rest}
141
- >
142
- {!tempValue || tempValue?.length === 0 ? (
143
- <span className="text-slate-300 duration-300 translate-x-0 group-focus/button:translate-x-1">
144
- {placeholder}
145
- </span>
146
- ) : (
147
- <div className="flex flex-wrap gap-2 h-min">
148
- {tempValue?.map((item) => {
149
- return (
150
- <div
151
- key={item}
152
- className="flex items-center gap-2 px-2 py-0.5 rounded-md bg-primary text-white cursor-default"
153
- >
154
- <span>{menus.find((i) => i.value === item)?.label}</span>
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
- className="cursor-pointer"
157
- onClick={() => {
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
- <Icon icon="pajamas:close" />
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
- </div>
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
- </button>
172
- {openDropdown &&
173
- position &&
174
- createPortal(
175
- <div
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="absolute max-h-40 p-1 z-50 pointer-events-auto bg-secondary-bg shadow border rounded-md overflow-auto"
189
+ className="w-0 my-0.5"
178
190
  style={{
179
- top: position.top,
180
- left: position.left,
181
- width: dropdownWidth,
191
+ height: dropdownHeight,
182
192
  }}
183
193
  >
184
- {menus.length === 0 ? (
185
- <div className="flex justify-center">
186
- <span className="px-4 py-1">No data found</span>
187
- </div>
188
- ) : (
189
- menus.map((item, index) => (
190
- <button
191
- key={index}
192
- type="button"
193
- 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"
194
- disabled={
195
- tempValue?.find((i) => i === item.value) ? true : false
196
- }
197
- onMouseDown={() => {
198
- setTempValue([...tempValue, item.value]);
199
- }}
200
- >
201
- {item.label}
202
- </button>
203
- ))
204
- )}
205
- </div>,
206
- document.body
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
- </label>
227
+ </div>
210
228
  );
211
229
  };