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.
- package/@types/index.d.ts +2 -0
- package/dist/components/button/index.d.ts +15 -0
- package/dist/components/calendar/big-calendar/event.d.ts +7 -0
- package/dist/components/calendar/big-calendar/index.d.ts +14 -0
- package/dist/components/calendar/big-calendar/toolbar.d.ts +8 -0
- package/dist/components/calendar/calendar/index.d.ts +11 -0
- package/dist/components/chart/index.d.ts +17 -0
- package/dist/components/chip/index.d.ts +12 -0
- package/dist/components/content-container/accordion/index.d.ts +10 -0
- package/dist/components/content-container/accordion/item.d.ts +6 -0
- package/dist/components/content-container/card.d.ts +10 -0
- package/dist/components/content-container/carousel.d.ts +10 -0
- package/dist/components/content-container/drawer.d.ts +8 -0
- package/dist/components/content-container/modal/index.d.ts +21 -0
- package/dist/components/content-container/sortable/index.d.ts +14 -0
- package/dist/components/content-container/sortable/item.d.ts +8 -0
- package/dist/components/content-container/sortable/knob.d.ts +5 -0
- package/dist/components/content-container/tab/index.d.ts +17 -0
- package/dist/components/content-container/tab/window.d.ts +5 -0
- package/dist/components/data-tree/index.d.ts +6 -0
- package/dist/components/dialog/index.d.ts +16 -0
- package/dist/components/dropdown/header.d.ts +5 -0
- package/dist/components/dropdown/index.d.ts +15 -0
- package/dist/components/dropdown/item.d.ts +7 -0
- package/dist/components/form/index.d.ts +44 -0
- package/dist/components/form/input/checkbox.d.ts +9 -0
- package/dist/components/form/input/color.d.ts +10 -0
- package/dist/components/form/input/email.d.ts +9 -0
- package/dist/components/form/input/file.d.ts +14 -0
- package/dist/components/form/input/number.d.ts +9 -0
- package/dist/components/form/input/password.d.ts +9 -0
- package/dist/components/form/input/radio.d.ts +9 -0
- package/dist/components/form/input/range.d.ts +9 -0
- package/dist/components/form/input/search.d.ts +8 -0
- package/dist/components/form/input/text.d.ts +9 -0
- package/dist/components/form/input/time.d.ts +9 -0
- package/dist/components/form/other/autocomplete.d.ts +15 -0
- package/dist/components/form/other/multipleSelect.d.ts +23 -0
- package/dist/components/form/other/phoneNumber.d.ts +10 -0
- package/dist/components/form/other/pin.d.ts +10 -0
- package/dist/components/form/other/secret.d.ts +11 -0
- package/dist/components/form/other/select.d.ts +15 -0
- package/dist/components/form/other/textarea.d.ts +9 -0
- package/dist/components/index.d.ts +19 -0
- package/dist/components/map/index.d.ts +13 -0
- package/dist/components/map/marker.d.ts +8 -0
- package/dist/components/syntax-highlighter/index.d.ts +9 -0
- package/dist/components/table/action.d.ts +5 -0
- package/dist/components/table/index.d.ts +24 -0
- package/dist/components/timeline/index.d.ts +10 -0
- package/dist/components/timeline/item.d.ts +7 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.LICENSE.txt +62 -0
- package/package.json +72 -0
- package/src/components/button/index.tsx +74 -0
- package/src/components/calendar/big-calendar/event.tsx +46 -0
- package/src/components/calendar/big-calendar/index.tsx +102 -0
- package/src/components/calendar/big-calendar/toolbar.tsx +98 -0
- package/src/components/calendar/calendar/index.tsx +26 -0
- package/src/components/chart/index.tsx +121 -0
- package/src/components/chip/index.tsx +47 -0
- package/src/components/content-container/accordion/index.tsx +28 -0
- package/src/components/content-container/accordion/item.tsx +40 -0
- package/src/components/content-container/card.tsx +21 -0
- package/src/components/content-container/carousel.tsx +35 -0
- package/src/components/content-container/drawer.tsx +78 -0
- package/src/components/content-container/modal/index.tsx +127 -0
- package/src/components/content-container/sortable/index.tsx +47 -0
- package/src/components/content-container/sortable/item.tsx +20 -0
- package/src/components/content-container/sortable/knob.tsx +11 -0
- package/src/components/content-container/tab/index.tsx +94 -0
- package/src/components/content-container/tab/window.tsx +10 -0
- package/src/components/data-tree/index.tsx +60 -0
- package/src/components/dialog/index.tsx +88 -0
- package/src/components/dropdown/header.tsx +11 -0
- package/src/components/dropdown/index.tsx +69 -0
- package/src/components/dropdown/item.tsx +22 -0
- package/src/components/form/index.tsx +81 -0
- package/src/components/form/input/checkbox.tsx +49 -0
- package/src/components/form/input/color.tsx +104 -0
- package/src/components/form/input/email.tsx +40 -0
- package/src/components/form/input/file.tsx +189 -0
- package/src/components/form/input/number.tsx +93 -0
- package/src/components/form/input/password.tsx +57 -0
- package/src/components/form/input/radio.tsx +49 -0
- package/src/components/form/input/range.tsx +67 -0
- package/src/components/form/input/search.tsx +50 -0
- package/src/components/form/input/text.tsx +39 -0
- package/src/components/form/input/time.tsx +315 -0
- package/src/components/form/other/autocomplete.tsx +199 -0
- package/src/components/form/other/multipleSelect.tsx +211 -0
- package/src/components/form/other/phoneNumber.tsx +1668 -0
- package/src/components/form/other/pin.tsx +56 -0
- package/src/components/form/other/secret.tsx +74 -0
- package/src/components/form/other/select.tsx +187 -0
- package/src/components/form/other/textarea.tsx +44 -0
- package/src/components/index.ts +29 -0
- package/src/components/map/index.tsx +72 -0
- package/src/components/map/marker.tsx +40 -0
- package/src/components/syntax-highlighter/index.tsx +45 -0
- package/src/components/table/action.tsx +22 -0
- package/src/components/table/index.tsx +431 -0
- package/src/components/timeline/index.tsx +28 -0
- package/src/components/timeline/item.tsx +25 -0
- package/src/index.css +1 -0
- package/src/index.ts +3 -0
- package/src/styles/big-calendar.scss +810 -0
- package/src/styles/calendar.scss +195 -0
- package/src/styles/index.css +2 -0
- package/tsconfig.json +17 -0
- package/webpack.config.js +35 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { PinField } from "react-pin-field";
|
|
4
|
+
|
|
5
|
+
export interface PinProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
6
|
+
options?: {
|
|
7
|
+
height?: "short" | "medium" | "high";
|
|
8
|
+
length: number;
|
|
9
|
+
};
|
|
10
|
+
label?: string;
|
|
11
|
+
onChange?: (e: any) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const Pin: React.FC<PinProps> = ({
|
|
15
|
+
options,
|
|
16
|
+
label,
|
|
17
|
+
onChange,
|
|
18
|
+
...rest
|
|
19
|
+
}) => {
|
|
20
|
+
const height =
|
|
21
|
+
options?.height === "short"
|
|
22
|
+
? "py-1"
|
|
23
|
+
: options?.height === "high"
|
|
24
|
+
? "py-2"
|
|
25
|
+
: "py-1.5";
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<label className="grid gap-2 w-fit">
|
|
29
|
+
{label && (
|
|
30
|
+
<span
|
|
31
|
+
className={`text-sm select-none ${
|
|
32
|
+
rest.required && "after:content-['*'] after:ml-1 after:text-danger"
|
|
33
|
+
}`}
|
|
34
|
+
>
|
|
35
|
+
{label}
|
|
36
|
+
</span>
|
|
37
|
+
)}
|
|
38
|
+
<div className="flex items-center gap-4">
|
|
39
|
+
<PinField
|
|
40
|
+
className={`text-center w-10 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}`}
|
|
41
|
+
length={6}
|
|
42
|
+
validate={/^[0-9]$/}
|
|
43
|
+
onChange={(value) => {
|
|
44
|
+
const e = {
|
|
45
|
+
target: {
|
|
46
|
+
value,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
onChange && onChange!(e);
|
|
50
|
+
}}
|
|
51
|
+
{...rest}
|
|
52
|
+
/>
|
|
53
|
+
</div>
|
|
54
|
+
</label>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { useState } from "react";
|
|
3
|
+
import { Icon } from "@iconify/react";
|
|
4
|
+
|
|
5
|
+
export interface SecretProps
|
|
6
|
+
extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
7
|
+
options?: {
|
|
8
|
+
width?: "full" | "fit";
|
|
9
|
+
height?: "short" | "medium" | "high";
|
|
10
|
+
};
|
|
11
|
+
label?: string;
|
|
12
|
+
value?: string;
|
|
13
|
+
onClipboardClick?: (value: string) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const Secret: React.FC<SecretProps> = ({
|
|
17
|
+
options,
|
|
18
|
+
label,
|
|
19
|
+
value,
|
|
20
|
+
onClipboardClick,
|
|
21
|
+
...rest
|
|
22
|
+
}) => {
|
|
23
|
+
const [show, setShow] = useState(false);
|
|
24
|
+
const width = options?.width === "fit" ? "w-fit" : "w-full";
|
|
25
|
+
const height =
|
|
26
|
+
options?.height === "short"
|
|
27
|
+
? "py-1"
|
|
28
|
+
: options?.height === "high"
|
|
29
|
+
? "py-2"
|
|
30
|
+
: "py-1.5";
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<label className={`grid gap-2 ${width}`}>
|
|
34
|
+
{label && (
|
|
35
|
+
<span
|
|
36
|
+
className={`text-sm select-none ${
|
|
37
|
+
rest.required && "after:content-['*'] after:ml-1 after:text-danger"
|
|
38
|
+
}`}
|
|
39
|
+
>
|
|
40
|
+
{label}
|
|
41
|
+
</span>
|
|
42
|
+
)}
|
|
43
|
+
<div className="relative flex items-center">
|
|
44
|
+
<input
|
|
45
|
+
type="text"
|
|
46
|
+
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}`}
|
|
47
|
+
value={show ? value : value ? value.slice(0, 3) + ".." : ""}
|
|
48
|
+
disabled
|
|
49
|
+
{...rest}
|
|
50
|
+
/>
|
|
51
|
+
<div className="absolute right-4 flex">
|
|
52
|
+
<div
|
|
53
|
+
className="p-1 rounded-full text-xl text-slate-400 cursor-pointer hover:bg-secondary-light"
|
|
54
|
+
onClick={(e) => {
|
|
55
|
+
e.preventDefault();
|
|
56
|
+
setShow(!show);
|
|
57
|
+
}}
|
|
58
|
+
>
|
|
59
|
+
<Icon icon={`flowbite:eye${show ? "" : "-slash"}-outline`} />
|
|
60
|
+
</div>
|
|
61
|
+
<div
|
|
62
|
+
className="p-1 rounded-full text-xl text-slate-400 cursor-pointer hover:bg-secondary-light"
|
|
63
|
+
onClick={(e) => {
|
|
64
|
+
e.preventDefault();
|
|
65
|
+
onClipboardClick && onClipboardClick(value!);
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
<Icon icon="fluent:clipboard-text-ltr-32-regular" />
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</label>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
@@ -0,0 +1,187 @@
|
|
|
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 SelectProps
|
|
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 Select: React.FC<SelectProps> = ({
|
|
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]);
|
|
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 cursor-pointer caret-transparent 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 disabled:cursor-default ${height}`}
|
|
129
|
+
placeholder={placeholder}
|
|
130
|
+
disabled={rest.disabled}
|
|
131
|
+
value={tempValue}
|
|
132
|
+
onClick={() => setIsOpen(true)}
|
|
133
|
+
/>
|
|
134
|
+
<div className="absolute right-4 text-xl text-slate-400 pointer-events-none">
|
|
135
|
+
<Icon icon={`gravity-ui:chevron-${isOpen ? "up" : "down"}`} />
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
{isOpen &&
|
|
139
|
+
position &&
|
|
140
|
+
createPortal(
|
|
141
|
+
<div
|
|
142
|
+
ref={dropdownRef}
|
|
143
|
+
className="absolute max-h-40 p-1 z-50 pointer-events-auto bg-secondary-bg shadow border rounded-md overflow-auto"
|
|
144
|
+
style={{
|
|
145
|
+
top: position.top,
|
|
146
|
+
left: position.left,
|
|
147
|
+
width: dropdownWidth,
|
|
148
|
+
}}
|
|
149
|
+
>
|
|
150
|
+
{menus.length === 0 ? (
|
|
151
|
+
<div className="flex justify-center">
|
|
152
|
+
<span className="px-4 py-1">No data found</span>
|
|
153
|
+
</div>
|
|
154
|
+
) : (
|
|
155
|
+
menus.map((item, index) => (
|
|
156
|
+
<button
|
|
157
|
+
key={index}
|
|
158
|
+
type="button"
|
|
159
|
+
className={`min-w-40 w-full my-0.5 px-4 py-2 rounded-md text-sm text-left text-default ${
|
|
160
|
+
(menus.find((item) => item.value === rest.value)?.label ||
|
|
161
|
+
tempValue) === item.label
|
|
162
|
+
? "bg-primary-transparent cursor-default"
|
|
163
|
+
: "hover:bg-secondary-light "
|
|
164
|
+
}`}
|
|
165
|
+
onMouseDown={() => {
|
|
166
|
+
setTempValue(item.label);
|
|
167
|
+
setIsOpen(false);
|
|
168
|
+
}}
|
|
169
|
+
>
|
|
170
|
+
{item.label}
|
|
171
|
+
</button>
|
|
172
|
+
))
|
|
173
|
+
)}
|
|
174
|
+
</div>,
|
|
175
|
+
document.body
|
|
176
|
+
)}
|
|
177
|
+
</div>
|
|
178
|
+
<select className="hidden" {...rest}>
|
|
179
|
+
{menus.map((item, index) => (
|
|
180
|
+
<option key={index} value={item.value}>
|
|
181
|
+
{item.label}
|
|
182
|
+
</option>
|
|
183
|
+
))}
|
|
184
|
+
</select>
|
|
185
|
+
</label>
|
|
186
|
+
);
|
|
187
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
export interface TextareaProps
|
|
5
|
+
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
6
|
+
options?: {
|
|
7
|
+
width?: "full" | "fit";
|
|
8
|
+
height?: "short" | "medium" | "high";
|
|
9
|
+
};
|
|
10
|
+
label?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const Textarea: React.FC<TextareaProps> = ({
|
|
14
|
+
options,
|
|
15
|
+
label,
|
|
16
|
+
...rest
|
|
17
|
+
}) => {
|
|
18
|
+
const width = options?.width === "fit" ? "w-fit" : "w-full";
|
|
19
|
+
const height =
|
|
20
|
+
options?.height === "short"
|
|
21
|
+
? "py-1"
|
|
22
|
+
: options?.height === "high"
|
|
23
|
+
? "py-2"
|
|
24
|
+
: "py-1.5";
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<label className={`grid gap-2 ${width}`}>
|
|
28
|
+
{label && (
|
|
29
|
+
<span
|
|
30
|
+
className={`text-sm select-none ${
|
|
31
|
+
rest.required && "after:content-['*'] after:ml-1 after:text-danger"
|
|
32
|
+
}`}
|
|
33
|
+
>
|
|
34
|
+
{label}
|
|
35
|
+
</span>
|
|
36
|
+
)}
|
|
37
|
+
<textarea
|
|
38
|
+
rows={rest.rows || 10}
|
|
39
|
+
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}`}
|
|
40
|
+
{...rest}
|
|
41
|
+
/>
|
|
42
|
+
</label>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// export { Sidebar } from "./main-layout/sidebar";
|
|
2
|
+
// export { Header } from "./main-layout/header";
|
|
3
|
+
// export { Body } from "./main-layout/body";
|
|
4
|
+
// export { Footer } from "./main-layout/footer";
|
|
5
|
+
// export { Chat } from "./chat";
|
|
6
|
+
// export { Logo } from "./other-component/logo";
|
|
7
|
+
// export { Avatar } from "./other-component/avatar";
|
|
8
|
+
// export { Mfa } from "./security/mfa";
|
|
9
|
+
// export { Recaptcha } from "./security/recaptcha";
|
|
10
|
+
export { Tab } from "./content-container/tab";
|
|
11
|
+
export { Dialog } from "./dialog";
|
|
12
|
+
export { Modal } from "./content-container/modal";
|
|
13
|
+
export { Drawer } from "./content-container/drawer";
|
|
14
|
+
export { Carousel } from "./content-container/carousel";
|
|
15
|
+
export { Accordion } from "./content-container/accordion";
|
|
16
|
+
export { Sortable } from "./content-container/sortable";
|
|
17
|
+
export { Card } from "./content-container/card";
|
|
18
|
+
export { Dropdown } from "./dropdown";
|
|
19
|
+
export { Chip } from "./chip";
|
|
20
|
+
export { Form } from "./form";
|
|
21
|
+
export { Button } from "./button";
|
|
22
|
+
export { Table } from "./table";
|
|
23
|
+
export { Chart } from "./chart";
|
|
24
|
+
export { Calendar } from "./calendar/calendar";
|
|
25
|
+
export { BigCalendar } from "./calendar/big-calendar";
|
|
26
|
+
// export { Map } from "./map";
|
|
27
|
+
export { Timeline } from "./timeline";
|
|
28
|
+
export { DataTree } from "./data-tree";
|
|
29
|
+
export { SyntaxHighlighter } from "./syntax-highlighter";
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { useRef } from "react";
|
|
3
|
+
import dynamic from "next/dynamic";
|
|
4
|
+
const MapContainer = dynamic(
|
|
5
|
+
() => import("react-leaflet").then((mod) => mod.MapContainer),
|
|
6
|
+
{ ssr: false }
|
|
7
|
+
);
|
|
8
|
+
const TileLayer = dynamic(
|
|
9
|
+
() => import("react-leaflet").then((mod) => mod.TileLayer),
|
|
10
|
+
{ ssr: false }
|
|
11
|
+
);
|
|
12
|
+
import { useMap, useMapEvent } from "react-leaflet";
|
|
13
|
+
import("leaflet-defaulticon-compatibility")
|
|
14
|
+
.then((module) => {})
|
|
15
|
+
.catch((error) => {
|
|
16
|
+
console.error("Failed to import leaflet-defaulticon-compatibility:", error);
|
|
17
|
+
});
|
|
18
|
+
import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.webpack.css";
|
|
19
|
+
import "leaflet/dist/leaflet.css";
|
|
20
|
+
import { Marker, type MarkerProps } from "./marker";
|
|
21
|
+
|
|
22
|
+
const ChangeView = ({ center, zoom }: any) => {
|
|
23
|
+
const map = useMap();
|
|
24
|
+
map.setView(center, zoom);
|
|
25
|
+
return null;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const SetViewOnClick = ({ animateRef }: any) => {
|
|
29
|
+
const map = useMapEvent("click", (e) => {
|
|
30
|
+
map.setView(e.latlng, map.getZoom(), {
|
|
31
|
+
animate: animateRef.current || false,
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return null;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
interface MapProps {
|
|
39
|
+
children: React.ReactNode;
|
|
40
|
+
currentPosition: any[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface MapComponentProps extends React.FC<MapProps> {
|
|
44
|
+
Marker: React.FC<MarkerProps>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const Map: MapComponentProps = ({ children, currentPosition }) => {
|
|
48
|
+
const animateRef = useRef(true);
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div className="flex-1 w-full h-full">
|
|
52
|
+
<MapContainer
|
|
53
|
+
// center={currentPosition}
|
|
54
|
+
// zoom={10}
|
|
55
|
+
scrollWheelZoom={true}
|
|
56
|
+
zoomControl={false}
|
|
57
|
+
// attributionControl={false}
|
|
58
|
+
style={{ width: "100%", height: "100%", zIndex: "10" }}
|
|
59
|
+
>
|
|
60
|
+
<TileLayer
|
|
61
|
+
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
|
62
|
+
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
63
|
+
/>
|
|
64
|
+
{children}
|
|
65
|
+
<ChangeView center={currentPosition} zoom={15} />
|
|
66
|
+
<SetViewOnClick animateRef={animateRef} />
|
|
67
|
+
</MapContainer>
|
|
68
|
+
</div>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
Map.Marker = Marker;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import dynamic from "next/dynamic";
|
|
4
|
+
const Mk = dynamic(() => import("react-leaflet").then((mod) => mod.Marker), {
|
|
5
|
+
ssr: false,
|
|
6
|
+
});
|
|
7
|
+
const Tooltip = dynamic(
|
|
8
|
+
() => import("react-leaflet").then((mod) => mod.Tooltip),
|
|
9
|
+
{ ssr: false }
|
|
10
|
+
);
|
|
11
|
+
const Popup = dynamic(() => import("react-leaflet").then((mod) => mod.Popup), {
|
|
12
|
+
ssr: false,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export interface MarkerProps {
|
|
16
|
+
position: any;
|
|
17
|
+
label: string;
|
|
18
|
+
desc?: React.ReactNode;
|
|
19
|
+
onClick: (position: any) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const Marker: React.FC<MarkerProps> = ({
|
|
23
|
+
position,
|
|
24
|
+
label,
|
|
25
|
+
desc,
|
|
26
|
+
onClick,
|
|
27
|
+
}) => {
|
|
28
|
+
return (
|
|
29
|
+
<Mk
|
|
30
|
+
position={position}
|
|
31
|
+
eventHandlers={{
|
|
32
|
+
click: onClick,
|
|
33
|
+
}}
|
|
34
|
+
alt={label}
|
|
35
|
+
>
|
|
36
|
+
<Tooltip permanent>{label}</Tooltip>
|
|
37
|
+
{desc && <Popup autoClose>{desc}</Popup>}
|
|
38
|
+
</Mk>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import SH from "react-syntax-highlighter";
|
|
4
|
+
import {
|
|
5
|
+
atomOneLight,
|
|
6
|
+
atomOneDark,
|
|
7
|
+
} from "react-syntax-highlighter/dist/esm/styles/hljs";
|
|
8
|
+
import { Icon } from "@iconify/react";
|
|
9
|
+
|
|
10
|
+
interface SyntaxHighlighterProps {
|
|
11
|
+
theme?: "light" | "dark" | "system";
|
|
12
|
+
codeString: string;
|
|
13
|
+
language?: string;
|
|
14
|
+
onClipboardClick?: (value: string) => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const SyntaxHighlighter: React.FC<SyntaxHighlighterProps> = ({
|
|
18
|
+
theme,
|
|
19
|
+
codeString,
|
|
20
|
+
language,
|
|
21
|
+
onClipboardClick,
|
|
22
|
+
}) => {
|
|
23
|
+
return (
|
|
24
|
+
<div className="relative w-full border rounded-md overflow-hidden">
|
|
25
|
+
<SH
|
|
26
|
+
language={language}
|
|
27
|
+
style={theme === "light" ? atomOneLight : atomOneDark}
|
|
28
|
+
showLineNumbers
|
|
29
|
+
wrapLongLines
|
|
30
|
+
>
|
|
31
|
+
{codeString}
|
|
32
|
+
</SH>
|
|
33
|
+
<div
|
|
34
|
+
className="absolute top-4 right-4 p-1 rounded-full text-xl text-slate-400 cursor-pointer hover:bg-secondary-light"
|
|
35
|
+
onClick={(e) => {
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
navigator.clipboard.writeText(codeString);
|
|
38
|
+
onClipboardClick && onClipboardClick(codeString);
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
<Icon icon="fluent:clipboard-text-ltr-32-regular" />
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
export interface ActionProps {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const Action: React.FC<ActionProps> = ({ children }) => {
|
|
9
|
+
const childrenList = React.Children.toArray(children);
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<div className="flex justify-center items-center gap-4">
|
|
13
|
+
{childrenList?.map((item, index) => {
|
|
14
|
+
return (
|
|
15
|
+
<div key={index}>
|
|
16
|
+
{item}
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
19
|
+
})}
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
};
|