next-helios-fe 1.0.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 (112) hide show
  1. package/@types/index.d.ts +2 -0
  2. package/dist/components/button/index.d.ts +15 -0
  3. package/dist/components/calendar/big-calendar/event.d.ts +7 -0
  4. package/dist/components/calendar/big-calendar/index.d.ts +14 -0
  5. package/dist/components/calendar/big-calendar/toolbar.d.ts +8 -0
  6. package/dist/components/calendar/calendar/index.d.ts +11 -0
  7. package/dist/components/chart/index.d.ts +17 -0
  8. package/dist/components/chip/index.d.ts +12 -0
  9. package/dist/components/content-container/accordion/index.d.ts +10 -0
  10. package/dist/components/content-container/accordion/item.d.ts +6 -0
  11. package/dist/components/content-container/card.d.ts +10 -0
  12. package/dist/components/content-container/carousel.d.ts +10 -0
  13. package/dist/components/content-container/drawer.d.ts +8 -0
  14. package/dist/components/content-container/modal/index.d.ts +21 -0
  15. package/dist/components/content-container/sortable/index.d.ts +14 -0
  16. package/dist/components/content-container/sortable/item.d.ts +8 -0
  17. package/dist/components/content-container/sortable/knob.d.ts +5 -0
  18. package/dist/components/content-container/tab/index.d.ts +17 -0
  19. package/dist/components/content-container/tab/window.d.ts +5 -0
  20. package/dist/components/data-tree/index.d.ts +6 -0
  21. package/dist/components/dialog/index.d.ts +16 -0
  22. package/dist/components/dropdown/header.d.ts +5 -0
  23. package/dist/components/dropdown/index.d.ts +15 -0
  24. package/dist/components/dropdown/item.d.ts +7 -0
  25. package/dist/components/form/index.d.ts +44 -0
  26. package/dist/components/form/input/checkbox.d.ts +9 -0
  27. package/dist/components/form/input/color.d.ts +10 -0
  28. package/dist/components/form/input/email.d.ts +9 -0
  29. package/dist/components/form/input/file.d.ts +14 -0
  30. package/dist/components/form/input/number.d.ts +9 -0
  31. package/dist/components/form/input/password.d.ts +9 -0
  32. package/dist/components/form/input/radio.d.ts +9 -0
  33. package/dist/components/form/input/range.d.ts +9 -0
  34. package/dist/components/form/input/search.d.ts +8 -0
  35. package/dist/components/form/input/text.d.ts +9 -0
  36. package/dist/components/form/input/time.d.ts +9 -0
  37. package/dist/components/form/other/autocomplete.d.ts +15 -0
  38. package/dist/components/form/other/multipleSelect.d.ts +23 -0
  39. package/dist/components/form/other/phoneNumber.d.ts +10 -0
  40. package/dist/components/form/other/pin.d.ts +10 -0
  41. package/dist/components/form/other/secret.d.ts +11 -0
  42. package/dist/components/form/other/select.d.ts +15 -0
  43. package/dist/components/form/other/textarea.d.ts +9 -0
  44. package/dist/components/index.d.ts +19 -0
  45. package/dist/components/map/index.d.ts +13 -0
  46. package/dist/components/map/marker.d.ts +8 -0
  47. package/dist/components/syntax-highlighter/index.d.ts +9 -0
  48. package/dist/components/table/action.d.ts +5 -0
  49. package/dist/components/table/index.d.ts +24 -0
  50. package/dist/components/timeline/index.d.ts +10 -0
  51. package/dist/components/timeline/item.d.ts +7 -0
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.js +2 -0
  54. package/dist/index.js.LICENSE.txt +62 -0
  55. package/package.json +72 -0
  56. package/src/components/button/index.tsx +74 -0
  57. package/src/components/calendar/big-calendar/event.tsx +46 -0
  58. package/src/components/calendar/big-calendar/index.tsx +102 -0
  59. package/src/components/calendar/big-calendar/toolbar.tsx +98 -0
  60. package/src/components/calendar/calendar/index.tsx +26 -0
  61. package/src/components/chart/index.tsx +121 -0
  62. package/src/components/chip/index.tsx +47 -0
  63. package/src/components/content-container/accordion/index.tsx +28 -0
  64. package/src/components/content-container/accordion/item.tsx +40 -0
  65. package/src/components/content-container/card.tsx +21 -0
  66. package/src/components/content-container/carousel.tsx +35 -0
  67. package/src/components/content-container/drawer.tsx +78 -0
  68. package/src/components/content-container/modal/index.tsx +127 -0
  69. package/src/components/content-container/sortable/index.tsx +47 -0
  70. package/src/components/content-container/sortable/item.tsx +20 -0
  71. package/src/components/content-container/sortable/knob.tsx +11 -0
  72. package/src/components/content-container/tab/index.tsx +94 -0
  73. package/src/components/content-container/tab/window.tsx +10 -0
  74. package/src/components/data-tree/index.tsx +60 -0
  75. package/src/components/dialog/index.tsx +88 -0
  76. package/src/components/dropdown/header.tsx +11 -0
  77. package/src/components/dropdown/index.tsx +69 -0
  78. package/src/components/dropdown/item.tsx +22 -0
  79. package/src/components/form/index.tsx +81 -0
  80. package/src/components/form/input/checkbox.tsx +49 -0
  81. package/src/components/form/input/color.tsx +104 -0
  82. package/src/components/form/input/email.tsx +40 -0
  83. package/src/components/form/input/file.tsx +189 -0
  84. package/src/components/form/input/number.tsx +93 -0
  85. package/src/components/form/input/password.tsx +57 -0
  86. package/src/components/form/input/radio.tsx +49 -0
  87. package/src/components/form/input/range.tsx +67 -0
  88. package/src/components/form/input/search.tsx +50 -0
  89. package/src/components/form/input/text.tsx +39 -0
  90. package/src/components/form/input/time.tsx +315 -0
  91. package/src/components/form/other/autocomplete.tsx +199 -0
  92. package/src/components/form/other/multipleSelect.tsx +211 -0
  93. package/src/components/form/other/phoneNumber.tsx +1668 -0
  94. package/src/components/form/other/pin.tsx +56 -0
  95. package/src/components/form/other/secret.tsx +74 -0
  96. package/src/components/form/other/select.tsx +187 -0
  97. package/src/components/form/other/textarea.tsx +44 -0
  98. package/src/components/index.ts +29 -0
  99. package/src/components/map/index.tsx +72 -0
  100. package/src/components/map/marker.tsx +40 -0
  101. package/src/components/syntax-highlighter/index.tsx +45 -0
  102. package/src/components/table/action.tsx +22 -0
  103. package/src/components/table/index.tsx +431 -0
  104. package/src/components/timeline/index.tsx +28 -0
  105. package/src/components/timeline/item.tsx +25 -0
  106. package/src/index.css +1 -0
  107. package/src/index.ts +3 -0
  108. package/src/styles/big-calendar.scss +810 -0
  109. package/src/styles/calendar.scss +195 -0
  110. package/src/styles/index.css +2 -0
  111. package/tsconfig.json +17 -0
  112. package/webpack.config.js +35 -0
@@ -0,0 +1,199 @@
1
+ "use client";
2
+ import React, { useState, useEffect, useRef } from "react";
3
+ import { Icon } from "@iconify/react";
4
+ import { createPortal } from "react-dom";
5
+
6
+ export interface AutocompleteProps
7
+ extends React.SelectHTMLAttributes<HTMLSelectElement> {
8
+ options?: {
9
+ width?: "full" | "fit";
10
+ height?: "short" | "medium" | "high";
11
+ };
12
+ label?: string;
13
+ menus: {
14
+ label: string;
15
+ value: string;
16
+ [key: string]: any;
17
+ }[];
18
+ placeholder?: string;
19
+ }
20
+
21
+ export const Autocomplete: React.FC<AutocompleteProps> = ({
22
+ options,
23
+ label,
24
+ menus,
25
+ placeholder,
26
+ ...rest
27
+ }) => {
28
+ const [tempValue, setTempValue] = useState("");
29
+ const [isOpen, setIsOpen] = useState(false);
30
+ const [position, setPosition] = useState<{
31
+ top: number;
32
+ left: number;
33
+ } | null>(null);
34
+ const [dropdownWidth, setDropdownWidth] = useState<number>(0);
35
+ const triggerRef = useRef<HTMLDivElement>(null);
36
+ const dropdownRef = useRef<HTMLDivElement>(null);
37
+ const width = options?.width === "fit" ? "w-fit" : "w-full";
38
+ const height =
39
+ options?.height === "short"
40
+ ? "py-1"
41
+ : options?.height === "high"
42
+ ? "py-2"
43
+ : "py-1.5";
44
+
45
+ useEffect(() => {
46
+ const handleClickOutside = (e: MouseEvent) => {
47
+ if (
48
+ dropdownRef.current &&
49
+ !dropdownRef.current.contains(e.target as Node) &&
50
+ !triggerRef.current?.contains(e.target as Node)
51
+ ) {
52
+ setIsOpen(false);
53
+ }
54
+ };
55
+
56
+ document.addEventListener("mousedown", handleClickOutside);
57
+ return () => {
58
+ document.removeEventListener("mousedown", handleClickOutside);
59
+ };
60
+ }, []);
61
+
62
+ useEffect(() => {
63
+ if (triggerRef.current) {
64
+ const rect = triggerRef.current.getBoundingClientRect();
65
+ const dropdownHeight = dropdownRef.current?.offsetHeight || 0;
66
+ const windowHeight = window.innerHeight;
67
+
68
+ setPosition({
69
+ top: rect.bottom + window.scrollY + 10,
70
+ left: rect.left + window.scrollX,
71
+ });
72
+
73
+ setDropdownWidth(rect.width);
74
+
75
+ if (rect.bottom + dropdownHeight > windowHeight) {
76
+ setPosition((prev) =>
77
+ prev
78
+ ? { ...prev, top: rect.top + window.scrollY - dropdownHeight - 10 }
79
+ : null
80
+ );
81
+ }
82
+ }
83
+
84
+ if (isOpen) {
85
+ document.getElementById("body")!.style.overflow = "hidden";
86
+ } else {
87
+ document.getElementById("body")!.style.overflow = "auto";
88
+ }
89
+ }, [isOpen, tempValue]);
90
+
91
+ useEffect(() => {
92
+ if (rest.value) {
93
+ setTempValue(rest.value as string);
94
+ return;
95
+ } else if (rest.defaultValue) {
96
+ setTempValue(rest.defaultValue as string);
97
+ return;
98
+ }
99
+ }, [rest.value, rest.defaultValue]);
100
+
101
+ useEffect(() => {
102
+ if (tempValue) {
103
+ rest.onChange &&
104
+ rest.onChange({
105
+ target: { value: tempValue } as HTMLSelectElement,
106
+ } as any);
107
+ }
108
+ }, [tempValue]);
109
+
110
+ return (
111
+ <label className={`grid gap-2 ${width}`}>
112
+ {label && (
113
+ <span
114
+ className={`text-sm select-none ${
115
+ rest.required && "after:content-['*'] after:ml-1 after:text-danger"
116
+ }`}
117
+ >
118
+ {label}
119
+ </span>
120
+ )}
121
+ <div className="relative" ref={triggerRef}>
122
+ <div
123
+ className="relative flex items-center cursor-pointer"
124
+ onClick={() => setIsOpen(!isOpen)}
125
+ >
126
+ <input
127
+ type="text"
128
+ className={`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}`}
129
+ placeholder={placeholder}
130
+ disabled={rest.disabled}
131
+ value={tempValue}
132
+ onChange={(e) => {
133
+ setTempValue(e.target.value);
134
+ }}
135
+ onClick={() => {
136
+ setIsOpen(true);
137
+ setTempValue("");
138
+ }}
139
+ />
140
+ <div className="absolute right-4 text-xl text-slate-400 pointer-events-none">
141
+ <Icon icon={`gravity-ui:chevron-${isOpen ? "up" : "down"}`} />
142
+ </div>
143
+ </div>
144
+ {isOpen &&
145
+ position &&
146
+ createPortal(
147
+ <div
148
+ ref={dropdownRef}
149
+ className="absolute max-h-40 p-1 z-50 pointer-events-auto bg-secondary-bg shadow border rounded-md overflow-auto"
150
+ style={{
151
+ top: position.top,
152
+ left: position.left,
153
+ width: dropdownWidth,
154
+ }}
155
+ >
156
+ {menus.filter((item) =>
157
+ item.label.toLowerCase().includes(tempValue.toLowerCase())
158
+ ).length === 0 ? (
159
+ <div className="flex justify-center">
160
+ <span className="px-4 py-1">No data found</span>
161
+ </div>
162
+ ) : (
163
+ menus
164
+ .filter((item) =>
165
+ item.label.toLowerCase().includes(tempValue.toLowerCase())
166
+ )
167
+ .map((item, index) => (
168
+ <button
169
+ key={index}
170
+ type="button"
171
+ className={`min-w-40 w-full my-0.5 px-4 py-2 rounded-md text-sm text-left text-default ${
172
+ (menus.find((item) => item.value === rest.value)
173
+ ?.label || tempValue) === item.label
174
+ ? "bg-primary-transparent cursor-default"
175
+ : "hover:bg-secondary-light "
176
+ }`}
177
+ onMouseDown={() => {
178
+ setTempValue(item.label);
179
+ setIsOpen(false);
180
+ }}
181
+ >
182
+ {item.label}
183
+ </button>
184
+ ))
185
+ )}
186
+ </div>,
187
+ document.body
188
+ )}
189
+ </div>
190
+ <select className="hidden" {...rest}>
191
+ {menus.map((item, index) => (
192
+ <option key={index} value={item.value}>
193
+ {item.label}
194
+ </option>
195
+ ))}
196
+ </select>
197
+ </label>
198
+ );
199
+ };
@@ -0,0 +1,211 @@
1
+ "use client";
2
+ import React, { useState, useEffect, useRef } from "react";
3
+ import { Icon } from "@iconify/react";
4
+ import { createPortal } from "react-dom";
5
+
6
+ export interface MultipleSelectProps
7
+ extends Omit<
8
+ React.ButtonHTMLAttributes<HTMLButtonElement>,
9
+ "onChange" | "value"
10
+ > {
11
+ options?: {
12
+ width?: "full" | "fit";
13
+ height?: "short" | "medium" | "high";
14
+ };
15
+ label?: string;
16
+ menus: {
17
+ label: string;
18
+ value: string;
19
+ [key: string]: any;
20
+ }[];
21
+ placeholder?: string;
22
+ required?: boolean;
23
+ value?: string[];
24
+ onClick?: () => void;
25
+ onChange?: (e: {
26
+ target: {
27
+ value: string[];
28
+ };
29
+ }) => void;
30
+ }
31
+
32
+ export const MultipleSelect: React.FC<MultipleSelectProps> = ({
33
+ options,
34
+ label,
35
+ menus,
36
+ placeholder,
37
+ required,
38
+ value,
39
+ onClick,
40
+ onChange,
41
+ ...rest
42
+ }) => {
43
+ const [tempValue, setTempValue] = useState<string[]>([]);
44
+ const [isOpen, setIsOpen] = useState(false);
45
+ const [position, setPosition] = useState<{
46
+ top: number;
47
+ left: number;
48
+ } | null>(null);
49
+ const [dropdownWidth, setDropdownWidth] = useState<number>(0);
50
+ const triggerRef = useRef<HTMLDivElement>(null);
51
+ const dropdownRef = useRef<HTMLDivElement>(null);
52
+ const width = options?.width === "fit" ? "w-fit" : "w-full";
53
+ const height =
54
+ options?.height === "short"
55
+ ? "py-0.5"
56
+ : options?.height === "high"
57
+ ? "py-1.5"
58
+ : "py-1";
59
+
60
+ 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
+ ) {
67
+ setIsOpen(false);
68
+ }
69
+ };
70
+
71
+ document.addEventListener("mousedown", handleClickOutside);
72
+ return () => {
73
+ document.removeEventListener("mousedown", handleClickOutside);
74
+ };
75
+ }, []);
76
+
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 (isOpen) {
100
+ document.getElementById("body")!.style.overflow = "hidden";
101
+ } else {
102
+ document.getElementById("body")!.style.overflow = "auto";
103
+ }
104
+ }, [isOpen]);
105
+
106
+ useEffect(() => {
107
+ if (value) {
108
+ setTempValue(value);
109
+ return;
110
+ }
111
+ }, [value]);
112
+
113
+ useEffect(() => {
114
+ onChange &&
115
+ onChange({
116
+ target: { value: tempValue },
117
+ });
118
+ }, [tempValue]);
119
+
120
+ 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
+ setIsOpen(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>
155
+ <div
156
+ className="cursor-pointer"
157
+ onClick={() => {
158
+ setTempValue(tempValue.filter((i) => i !== item));
159
+ }}
160
+ >
161
+ <Icon icon="pajamas:close" />
162
+ </div>
163
+ </div>
164
+ );
165
+ })}
166
+ </div>
167
+ )}
168
+ <div className="text-xl text-slate-400 pointer-events-none">
169
+ <Icon icon={`gravity-ui:chevron-${isOpen ? "up" : "down"}`} />
170
+ </div>
171
+ </button>
172
+ {isOpen &&
173
+ position &&
174
+ createPortal(
175
+ <div
176
+ ref={dropdownRef}
177
+ className="absolute max-h-40 p-1 z-50 pointer-events-auto bg-secondary-bg shadow border rounded-md overflow-auto"
178
+ style={{
179
+ top: position.top,
180
+ left: position.left,
181
+ width: dropdownWidth,
182
+ }}
183
+ >
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
+ )}
208
+ </div>
209
+ </label>
210
+ );
211
+ };