@skalfa/skalfa-component 1.0.8 → 1.0.10
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/accordion/Accordion.component.js +2 -3
- package/dist/breadcrumb/Breadcrumb.component.js +2 -3
- package/dist/button/Button.component.d.ts +2 -1
- package/dist/button/Button.component.js +2 -2
- package/dist/carousel/Carousel.component.js +2 -3
- package/dist/chip/Chip.component.js +2 -3
- package/dist/contexts-mock.d.ts +2 -0
- package/dist/contexts-mock.js +10 -0
- package/dist/input/Checkbox.component.js +2 -3
- package/dist/input/Input.component.d.ts +3 -2
- package/dist/input/Input.component.js +3 -3
- package/dist/input/InputCheckbox.component.js +1 -1
- package/dist/input/InputCurrency.component.d.ts +3 -2
- package/dist/input/InputCurrency.component.js +3 -3
- package/dist/input/InputDate.component.js +4 -5
- package/dist/input/InputDatetime.component.d.ts +3 -2
- package/dist/input/InputDatetime.component.js +3 -3
- package/dist/input/InputDocument.component.js +7 -8
- package/dist/input/InputImage.component.js +3 -4
- package/dist/input/InputNumber.component.js +3 -4
- package/dist/input/InputPassword.component.js +3 -3
- package/dist/input/InputRadio.component.js +1 -1
- package/dist/input/InputTime.component.js +3 -3
- package/dist/input/InputValues.component.js +3 -4
- package/dist/input/Select.component.js +6 -7
- package/dist/modal/FloatingPage.component.d.ts +3 -1
- package/dist/modal/FloatingPage.component.js +7 -3
- package/dist/modal/Modal.component.js +1 -2
- package/dist/modal/ModalConfirm.component.d.ts +2 -2
- package/dist/modal/ModalConfirm.component.js +14 -12
- package/dist/modal/Toast.component.js +1 -2
- package/dist/nav/Bottombar.component.d.ts +2 -2
- package/dist/nav/Bottombar.component.js +7 -8
- package/dist/nav/Footer.component.d.ts +2 -2
- package/dist/nav/Footer.component.js +6 -7
- package/dist/nav/Headbar.component.js +2 -3
- package/dist/nav/Navbar.component.d.ts +2 -2
- package/dist/nav/Navbar.component.js +3 -4
- package/dist/nav/Sidebar.component.d.ts +3 -7
- package/dist/nav/Sidebar.component.js +14 -17
- package/dist/supervision/FormSupervision.component.d.ts +4 -29
- package/dist/supervision/FormSupervision.component.js +84 -136
- package/dist/supervision/TableSupervision.component.d.ts +17 -26
- package/dist/supervision/TableSupervision.component.js +207 -193
- package/dist/table/ControlBar.component.js +15 -16
- package/dist/table/FilterComponent.js +4 -6
- package/dist/table/Pagination.component.js +2 -3
- package/dist/table/Table.component.js +3 -4
- package/dist/wrap/Swipe.component.js +2 -2
- package/package.json +18 -10
- package/src/accordion/Accordion.component.tsx +3 -3
- package/src/breadcrumb/Breadcrumb.component.tsx +4 -4
- package/src/button/Button.component.tsx +3 -3
- package/src/carousel/Carousel.component.tsx +4 -4
- package/src/chip/Chip.component.tsx +3 -4
- package/src/contexts-mock.ts +6 -0
- package/src/input/Checkbox.component.tsx +3 -3
- package/src/input/Input.component.tsx +6 -6
- package/src/input/InputCheckbox.component.tsx +1 -1
- package/src/input/InputCurrency.component.tsx +6 -6
- package/src/input/InputDate.component.tsx +6 -7
- package/src/input/InputDatetime.component.tsx +6 -6
- package/src/input/InputDocument.component.tsx +9 -9
- package/src/input/InputImage.component.tsx +4 -5
- package/src/input/InputNumber.component.tsx +7 -8
- package/src/input/InputPassword.component.tsx +4 -4
- package/src/input/InputRadio.component.tsx +1 -1
- package/src/input/InputTime.component.tsx +4 -4
- package/src/input/InputValues.component.tsx +5 -6
- package/src/input/Select.component.tsx +10 -10
- package/src/modal/FloatingPage.component.tsx +33 -3
- package/src/modal/Modal.component.tsx +1 -2
- package/src/modal/ModalConfirm.component.tsx +34 -49
- package/src/modal/Toast.component.tsx +1 -2
- package/src/nav/Bottombar.component.tsx +9 -10
- package/src/nav/Footer.component.tsx +8 -9
- package/src/nav/Headbar.component.tsx +3 -3
- package/src/nav/Navbar.component.tsx +9 -10
- package/src/nav/Sidebar.component.tsx +55 -46
- package/src/supervision/FormSupervision.component.tsx +203 -224
- package/src/supervision/TableSupervision.component.tsx +420 -455
- package/src/table/ControlBar.component.tsx +16 -16
- package/src/table/FilterComponent.tsx +9 -11
- package/src/table/Pagination.component.tsx +6 -6
- package/src/table/Table.component.tsx +5 -5
- package/src/wrap/Swipe.component.tsx +3 -3
- package/src/types.d.ts +0 -7
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
3
|
import { ReactNode, useEffect, useMemo, useState } from "react";
|
|
4
|
-
import { faQuestion } from "@fortawesome/free-solid-svg-icons";
|
|
5
|
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
6
4
|
import { api, ApiType, cn, pcn, registry, shortcut, useResponsive } from "@utils";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { BottomSheetComponent } from "./BottomSheet.component";
|
|
5
|
+
import { ButtonComponent, ButtonProps, BottomSheetComponent } from "@components";
|
|
6
|
+
import { Icon } from "@skalfa/skalfa-icon";
|
|
10
7
|
|
|
11
8
|
|
|
12
9
|
|
|
@@ -37,7 +34,6 @@ export function ModalConfirmComponent({
|
|
|
37
34
|
show,
|
|
38
35
|
title,
|
|
39
36
|
children,
|
|
40
|
-
icon,
|
|
41
37
|
footer,
|
|
42
38
|
|
|
43
39
|
submitControl,
|
|
@@ -66,47 +62,59 @@ export function ModalConfirmComponent({
|
|
|
66
62
|
}, [show]);
|
|
67
63
|
|
|
68
64
|
|
|
69
|
-
const renderChildren =
|
|
65
|
+
const renderChildren = (actionSize: ButtonProps["size"] = 'md') => {
|
|
66
|
+
if (toast == "success") {
|
|
67
|
+
return (
|
|
68
|
+
<div className="flex flex-col items-center justify-center h-full py-6 transition-all duration-300 animate-intro-down">
|
|
69
|
+
<div className="w-12 h-12 rounded-full bg-blue-50 flex items-center justify-center">
|
|
70
|
+
<Icon icon={"solid/check"} className="text-primary text-2xl" />
|
|
71
|
+
</div>
|
|
72
|
+
<p className="text-primary text-lg font-semibold mt-4">{"Berhasil!"}</p>
|
|
73
|
+
</div>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
70
77
|
return (
|
|
71
78
|
<>
|
|
72
79
|
{title && (
|
|
73
80
|
<div
|
|
74
81
|
className={cn(
|
|
75
|
-
"flex flex-col gap-2
|
|
82
|
+
"flex flex-col gap-2 p-6",
|
|
76
83
|
pcn<CT>(className, "header")
|
|
77
84
|
)}
|
|
78
85
|
>
|
|
79
|
-
<div className="mt-6">
|
|
80
|
-
<FontAwesomeIcon
|
|
81
|
-
icon={icon || faQuestion}
|
|
82
|
-
className={`text-xl`}
|
|
83
|
-
/>
|
|
84
|
-
</div>
|
|
85
|
-
|
|
86
86
|
<h6 className="font-semibold text-lg">{title}</h6>
|
|
87
87
|
</div>
|
|
88
88
|
)}
|
|
89
89
|
|
|
90
90
|
{children}
|
|
91
91
|
|
|
92
|
-
{
|
|
93
|
-
<div className=
|
|
94
|
-
|
|
92
|
+
{toast == "failed" && (
|
|
93
|
+
<div className="px-4">
|
|
94
|
+
<div className="mt-4 w-full p-4 rounded-sm border border-danger bg-light-danger flex gap-4 items-center">
|
|
95
|
+
<div>
|
|
96
|
+
<div className="w-10 h-10 rounded-full bg-danger/20 flex items-center justify-center">
|
|
97
|
+
<Icon icon={"solid/exclamation-triangle"} className="text-danger text-lg" />
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
<p className="text-danger text-sm font-semibold">{"Terjadi Masalah, Coba ulangi lagi!"}</p>
|
|
101
|
+
</div>
|
|
95
102
|
</div>
|
|
96
103
|
)}
|
|
104
|
+
|
|
105
|
+
{renderAction(actionSize)}
|
|
97
106
|
</>
|
|
98
107
|
)
|
|
99
|
-
}
|
|
108
|
+
}
|
|
100
109
|
|
|
101
110
|
|
|
102
111
|
const renderAction = (size: ButtonProps["size"] = 'md') => {
|
|
103
112
|
return (
|
|
104
|
-
<div className="flex justify-center pt-
|
|
113
|
+
<div className="flex justify-center gap-4 p-6 pt-2">
|
|
105
114
|
<ButtonComponent
|
|
106
115
|
label="Batal"
|
|
107
|
-
variant="
|
|
116
|
+
variant="outline"
|
|
108
117
|
onClick={() => onClose()}
|
|
109
|
-
className="text-foreground bg-background rounded-none"
|
|
110
118
|
block
|
|
111
119
|
size={size}
|
|
112
120
|
/>
|
|
@@ -138,16 +146,17 @@ export function ModalConfirmComponent({
|
|
|
138
146
|
|
|
139
147
|
if (response?.status == 200 || response?.status == 201) {
|
|
140
148
|
setToast("success");
|
|
149
|
+
setTimeout(() => setToast(false), 1000);
|
|
141
150
|
submitControl?.onSuccess?.();
|
|
142
151
|
setLoading(false);
|
|
143
152
|
} else {
|
|
144
153
|
setToast("failed");
|
|
154
|
+
setTimeout(() => setToast(false), 5000);
|
|
145
155
|
submitControl?.onError?.();
|
|
146
156
|
setLoading(false);
|
|
147
157
|
}
|
|
148
158
|
}
|
|
149
159
|
}}
|
|
150
|
-
className="rounded-none"
|
|
151
160
|
block
|
|
152
161
|
size={size}
|
|
153
162
|
{...submitControl}
|
|
@@ -176,9 +185,7 @@ export function ModalConfirmComponent({
|
|
|
176
185
|
pcn<CT>(className, "base")
|
|
177
186
|
)}
|
|
178
187
|
>
|
|
179
|
-
{renderChildren}
|
|
180
|
-
|
|
181
|
-
{renderAction()}
|
|
188
|
+
{renderChildren()}
|
|
182
189
|
</div>
|
|
183
190
|
</>
|
|
184
191
|
) : (
|
|
@@ -187,33 +194,11 @@ export function ModalConfirmComponent({
|
|
|
187
194
|
show={show}
|
|
188
195
|
onClose={onClose}
|
|
189
196
|
size={220}
|
|
190
|
-
footer={renderAction('lg')}
|
|
191
197
|
>
|
|
192
|
-
{renderChildren}
|
|
198
|
+
{renderChildren('lg')}
|
|
193
199
|
</BottomSheetComponent>
|
|
194
200
|
</>
|
|
195
201
|
)}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
<ToastComponent
|
|
199
|
-
show={toast == "failed"}
|
|
200
|
-
onClose={() => setToast(false)}
|
|
201
|
-
title="Gagal"
|
|
202
|
-
className="!border-danger header::text-danger"
|
|
203
|
-
>
|
|
204
|
-
<p className="px-3 pb-2 text-sm">
|
|
205
|
-
Gagal {title || ""}! cek data dan koneksi internet dan coba kembali!
|
|
206
|
-
</p>
|
|
207
|
-
</ToastComponent>
|
|
208
|
-
|
|
209
|
-
<ToastComponent
|
|
210
|
-
show={toast == "success"}
|
|
211
|
-
onClose={() => setToast(false)}
|
|
212
|
-
title="Berhasil"
|
|
213
|
-
className="!border-success header::text-success"
|
|
214
|
-
>
|
|
215
|
-
<p className="px-3 pb-2 text-sm">Berhasil {title || ""}!</p>
|
|
216
|
-
</ToastComponent>
|
|
217
202
|
</>
|
|
218
203
|
);
|
|
219
204
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
3
|
import { ReactNode, useEffect, useState } from "react";
|
|
4
|
-
import { faTimes } from "@fortawesome/free-solid-svg-icons";
|
|
5
4
|
import { cn, pcn } from "@utils";
|
|
6
5
|
import { ButtonComponent } from "../button/Button.component";
|
|
7
6
|
|
|
@@ -99,7 +98,7 @@ export function ToastComponent({
|
|
|
99
98
|
<div className="flex gap-2 items-center">
|
|
100
99
|
<span className="text-xs text-foreground/50">{countdown}</span>
|
|
101
100
|
<ButtonComponent
|
|
102
|
-
icon=
|
|
101
|
+
icon="solid/times"
|
|
103
102
|
variant="simple"
|
|
104
103
|
paint="danger"
|
|
105
104
|
onClick={() => {
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
"use client"
|
|
2
|
+
import { Icon, type IconName } from "@skalfa/skalfa-icon";
|
|
3
|
+
|
|
2
4
|
|
|
3
5
|
import Link from "next/link";
|
|
4
6
|
import { usePathname } from "next/navigation";
|
|
5
|
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
6
|
-
import { faClipboard, faCrosshairs, faHome, faSackDollar, faUserCircle } from "@fortawesome/free-solid-svg-icons";
|
|
7
7
|
import { cn, pcn, useKeyboardOpen } from "@utils";
|
|
8
|
-
import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
|
|
9
8
|
|
|
10
9
|
export interface BottombarItemProps {
|
|
11
|
-
icon :
|
|
10
|
+
icon : IconName;
|
|
12
11
|
path : string;
|
|
13
12
|
activeKey ?: string;
|
|
14
13
|
}
|
|
@@ -20,11 +19,11 @@ export interface BottombarProps {
|
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
const defaultItems: BottombarItemProps[] = [
|
|
23
|
-
{ icon:
|
|
24
|
-
{ icon:
|
|
25
|
-
{ icon:
|
|
26
|
-
{ icon:
|
|
27
|
-
{ icon:
|
|
22
|
+
{ icon: "solid/home", path: "/_example/bottombar", activeKey: "home" },
|
|
23
|
+
{ icon: "solid/clipboard", path: "/", activeKey: "clipboard" },
|
|
24
|
+
{ icon: "solid/crosshairs", path: "/", activeKey: "crosshairs" },
|
|
25
|
+
{ icon: "solid/sack-dollar", path: "/", activeKey: "sack-dollar" },
|
|
26
|
+
{ icon: "solid/user-circle", path: "/", activeKey: "profile" },
|
|
28
27
|
];
|
|
29
28
|
|
|
30
29
|
export function BottombarComponent({
|
|
@@ -60,7 +59,7 @@ export function BottombarComponent({
|
|
|
60
59
|
isActive && pcn(className, "active"),
|
|
61
60
|
)}
|
|
62
61
|
>
|
|
63
|
-
<
|
|
62
|
+
<Icon icon={item.icon} />
|
|
64
63
|
</div>
|
|
65
64
|
</Link>
|
|
66
65
|
);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use client"
|
|
2
|
+
import { Icon, type IconName } from "@skalfa/skalfa-icon";
|
|
3
|
+
|
|
2
4
|
|
|
3
5
|
import Link from "next/link";
|
|
4
|
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
5
|
-
import { faFacebook, faGithub, faInstagram, faLinkedin } from "@fortawesome/free-brands-svg-icons";
|
|
6
|
-
import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
|
|
7
6
|
|
|
8
7
|
export interface FooterLinkProps {
|
|
9
8
|
label: string;
|
|
@@ -16,7 +15,7 @@ export interface FooterColumnProps {
|
|
|
16
15
|
}
|
|
17
16
|
|
|
18
17
|
export interface FooterSocialProps {
|
|
19
|
-
icon:
|
|
18
|
+
icon: IconName;
|
|
20
19
|
path: string;
|
|
21
20
|
}
|
|
22
21
|
|
|
@@ -33,10 +32,10 @@ export interface FooterProps {
|
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
const defaultSocials: FooterSocialProps[] = [
|
|
36
|
-
{ icon:
|
|
37
|
-
{ icon:
|
|
38
|
-
{ icon:
|
|
39
|
-
{ icon:
|
|
35
|
+
{ icon: "brands/facebook" as any, path: "" },
|
|
36
|
+
{ icon: "brands/linkedin" as any, path: "" },
|
|
37
|
+
{ icon: "brands/github" as any, path: "https://github.com/SE-JE" },
|
|
38
|
+
{ icon: "brands/instagram" as any, path: "https://www.instagram.com/seje.digital/" },
|
|
40
39
|
];
|
|
41
40
|
|
|
42
41
|
const defaultColumns: FooterColumnProps[] = [
|
|
@@ -131,7 +130,7 @@ export function FooterComponent({
|
|
|
131
130
|
<div className="footer-socials-container">
|
|
132
131
|
{socials.map((social, key) => (
|
|
133
132
|
<a href={social.path} key={key} target="_blank" rel="noopener noreferrer">
|
|
134
|
-
<
|
|
133
|
+
<Icon
|
|
135
134
|
icon={social.icon}
|
|
136
135
|
className="footer-social-icon"
|
|
137
136
|
/>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client"
|
|
2
|
+
import { Icon, type IconName } from "@skalfa/skalfa-icon";
|
|
3
|
+
|
|
2
4
|
|
|
3
5
|
import { useRouter } from "next/navigation";
|
|
4
|
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
5
|
-
import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
|
|
6
6
|
import { ReactNode } from "react";
|
|
7
7
|
|
|
8
8
|
|
|
@@ -22,7 +22,7 @@ export function HeadbarComponent({ title, backHref, rightContent }: HeadbarProps
|
|
|
22
22
|
<div className="flex items-center">
|
|
23
23
|
{backHref && (
|
|
24
24
|
<div className="w-8 aspect-square flex justify-center items-center cursor-pointer" onClick={() => typeof backHref != "boolean" ? router.push(backHref) : router.back()}>
|
|
25
|
-
<
|
|
25
|
+
<Icon icon="solid/chevron-left" className="text-secondary text-xl" />
|
|
26
26
|
</div>
|
|
27
27
|
)}
|
|
28
28
|
<p className="text-lg font-bold px-2">{title}</p>
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"use client"
|
|
2
|
+
import { Icon, type IconName } from "@skalfa/skalfa-icon";
|
|
3
|
+
|
|
2
4
|
|
|
3
5
|
import Link from "next/link";
|
|
4
|
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
5
|
-
import { faBell, faHistory, faStore, faUser } from "@fortawesome/free-solid-svg-icons";
|
|
6
6
|
import { ButtonComponent } from "../button/Button.component";
|
|
7
|
-
import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
|
|
8
7
|
import { cn } from "@utils";
|
|
9
8
|
|
|
10
9
|
export interface NavbarItemProps {
|
|
@@ -16,7 +15,7 @@ export interface NavbarProps {
|
|
|
16
15
|
logoTitle ?: string;
|
|
17
16
|
logoSubtitle ?: string;
|
|
18
17
|
logoPath ?: string;
|
|
19
|
-
specialLink ?: { label: string; path: string; icon?:
|
|
18
|
+
specialLink ?: { label: string; path: string; icon?: IconName };
|
|
20
19
|
items ?: NavbarItemProps[];
|
|
21
20
|
isLoggedIn ?: boolean;
|
|
22
21
|
onLogin ?: () => void;
|
|
@@ -34,8 +33,8 @@ const defaultItems: NavbarItemProps[] = [
|
|
|
34
33
|
const defaultSpecialLink = {
|
|
35
34
|
label: "Special Link",
|
|
36
35
|
path: "",
|
|
37
|
-
icon:
|
|
38
|
-
};
|
|
36
|
+
icon: "solid/store",
|
|
37
|
+
} as const;
|
|
39
38
|
|
|
40
39
|
export function NavbarComponent({
|
|
41
40
|
logoTitle = "Next Light v.3",
|
|
@@ -56,7 +55,7 @@ export function NavbarComponent({
|
|
|
56
55
|
<h2 className="text-base">
|
|
57
56
|
Ini untuk
|
|
58
57
|
<Link href={specialLink.path} className="navbar-special-link">
|
|
59
|
-
{specialLink.icon && <
|
|
58
|
+
{specialLink.icon && <Icon icon={specialLink.icon} className="mr-1" />}
|
|
60
59
|
{specialLink.label}
|
|
61
60
|
</Link>
|
|
62
61
|
</h2>
|
|
@@ -113,10 +112,10 @@ export function NavbarComponent({
|
|
|
113
112
|
) : (
|
|
114
113
|
<div className="flex gap-2 w-max items-center">
|
|
115
114
|
<div className="p-2 text-light-foreground hover:text-foreground cursor-pointer">
|
|
116
|
-
<
|
|
115
|
+
<Icon icon="solid/history" />
|
|
117
116
|
</div>
|
|
118
117
|
<div className="p-2 text-light-foreground hover:text-foreground cursor-pointer">
|
|
119
|
-
<
|
|
118
|
+
<Icon icon="solid/bell" />
|
|
120
119
|
</div>
|
|
121
120
|
<div className="h-5 w-[1px] bg-foreground mx-2.5"></div>
|
|
122
121
|
<div
|
|
@@ -124,7 +123,7 @@ export function NavbarComponent({
|
|
|
124
123
|
onClick={onProfile}
|
|
125
124
|
>
|
|
126
125
|
<div className="h-10 bg-background rounded-full aspect-square overflow-hidden flex justify-center items-center">
|
|
127
|
-
<
|
|
126
|
+
<Icon icon="solid/user" />
|
|
128
127
|
</div>
|
|
129
128
|
</div>
|
|
130
129
|
</div>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
|
-
import { Fragment, ReactNode, useEffect, useState } from "react";
|
|
3
|
+
import { Fragment, ReactNode, useEffect, useState, } from "react";
|
|
4
4
|
import { usePathname } from "next/navigation";
|
|
5
5
|
import Link from "next/link";
|
|
6
|
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
7
|
-
import { faChevronDown, faChevronUp } from "@fortawesome/free-solid-svg-icons";
|
|
8
6
|
import { cn, pcn } from "@utils";
|
|
7
|
+
import { useToggleContext } from "@contexts";
|
|
8
|
+
import { Icon } from "@skalfa/skalfa-icon";
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
|
|
@@ -29,15 +29,11 @@ export interface SidebarHeadItemProps {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export interface sidebarProps {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
onToggleChange ?: () => void;
|
|
38
|
-
children ?: any;
|
|
39
|
-
hasAccess ?: number[];
|
|
40
|
-
onChange ?: () => void;
|
|
32
|
+
id ?: string;
|
|
33
|
+
head ?: any;
|
|
34
|
+
footer ?: any;
|
|
35
|
+
items ?: SidebarHeadItemProps[];
|
|
36
|
+
basePath ?: string;
|
|
41
37
|
|
|
42
38
|
/** Use custom class with: "backdrop::", "head-item::", "item::", "child-item::". */
|
|
43
39
|
className?: string;
|
|
@@ -67,25 +63,20 @@ function SidebarWrapper({
|
|
|
67
63
|
|
|
68
64
|
|
|
69
65
|
export function SidebarComponent({
|
|
66
|
+
id,
|
|
70
67
|
head,
|
|
68
|
+
footer,
|
|
71
69
|
items,
|
|
72
70
|
basePath,
|
|
73
|
-
toggle,
|
|
74
|
-
onToggleChange,
|
|
75
|
-
// onChange,
|
|
76
|
-
// hasAccess,
|
|
77
71
|
className = "",
|
|
78
72
|
} : sidebarProps) {
|
|
79
|
-
const pathName
|
|
73
|
+
const pathName = usePathname();
|
|
74
|
+
const { toggle, setToggle } = useToggleContext()
|
|
80
75
|
|
|
81
76
|
const [shows, setShows] = useState<string[]>([]);
|
|
82
77
|
|
|
83
78
|
const setShow = (key: string) => {
|
|
84
|
-
setShows((prevShows) =>
|
|
85
|
-
prevShows?.find((pk) => pk === key)
|
|
86
|
-
? prevShows.filter((pk) => pk !== key)
|
|
87
|
-
: [...prevShows, key],
|
|
88
|
-
);
|
|
79
|
+
setShows((prevShows) => prevShows?.find((pk) => pk === key) ? prevShows.filter((pk) => pk !== key) : [...prevShows, key]);
|
|
89
80
|
};
|
|
90
81
|
|
|
91
82
|
const checkShow = (key: string): boolean => {
|
|
@@ -130,29 +121,46 @@ export function SidebarComponent({
|
|
|
130
121
|
});
|
|
131
122
|
}, []);
|
|
132
123
|
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
setToggle(`SIDEBAR${id ? "" : "_" + id?.toUpperCase()}`, false)
|
|
126
|
+
}, [pathName]);
|
|
127
|
+
|
|
133
128
|
return (
|
|
134
129
|
<>
|
|
135
|
-
<div
|
|
130
|
+
<div
|
|
136
131
|
className={cn(
|
|
137
132
|
"sidebar-backdrop",
|
|
138
|
-
toggle ? "scale-100
|
|
133
|
+
toggle[`SIDEBAR${id ? "" : "_" + id?.toUpperCase()}`] ? "scale-100 lg:scale-0" : "scale-0",
|
|
139
134
|
pcn<CT>(className, "backdrop"),
|
|
140
|
-
)}
|
|
141
|
-
onClick={() =>
|
|
135
|
+
)}
|
|
136
|
+
onClick={() => setToggle(`SIDEBAR${id ? "" : "_" + id?.toUpperCase()}`)}
|
|
142
137
|
></div>
|
|
143
|
-
<aside
|
|
138
|
+
<aside
|
|
144
139
|
className={cn(
|
|
145
140
|
"sidebar-base scroll-sm",
|
|
146
|
-
toggle ? "
|
|
141
|
+
toggle[`SIDEBAR${id ? "" : "_" + id?.toUpperCase()}`] ? "w-full sm:w-[280px]" : "w-0 sm:w-14 lg:w-[280px]",
|
|
147
142
|
pcn<CT>(className, "base"),
|
|
148
143
|
)}
|
|
149
144
|
>
|
|
150
|
-
{
|
|
151
|
-
|
|
145
|
+
<div className={toggle[`SIDEBAR${id ? "" : "_" + id?.toUpperCase()}`] ? "block" : "hidden lg:block"}>
|
|
146
|
+
{head}
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
<div
|
|
150
|
+
className={toggle[`SIDEBAR${id ? "" : "_" + id?.toUpperCase()}`] ? "hidden" : "flex justify-center pt-4 h-full lg:hidden"}
|
|
151
|
+
onClick={() => setToggle(`SIDEBAR${id ? "" : "_" + id?.toUpperCase()}`)}
|
|
152
|
+
>
|
|
153
|
+
<Icon icon={"solid/bars"} />
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<nav className={cn(
|
|
157
|
+
"flex flex-col flex-1 overflow-hidden",
|
|
158
|
+
toggle[`SIDEBAR${id ? "" : "_" + id?.toUpperCase()}`] ? "w-full" : "w-0 lg:w-full",
|
|
159
|
+
)}>
|
|
152
160
|
{items?.map((menu_head, menu_head_key) => {
|
|
153
161
|
return (
|
|
154
162
|
<Fragment key={menu_head_key}>
|
|
155
|
-
<div className="
|
|
163
|
+
<div className="">
|
|
156
164
|
<div
|
|
157
165
|
className={cn(
|
|
158
166
|
"sidebar-head-item",
|
|
@@ -164,10 +172,9 @@ export function SidebarComponent({
|
|
|
164
172
|
>
|
|
165
173
|
{menu_head?.label}
|
|
166
174
|
{menu_head.collapse && (
|
|
167
|
-
<
|
|
168
|
-
icon={
|
|
175
|
+
<Icon
|
|
176
|
+
icon={"solid/chevron-down"}
|
|
169
177
|
className={cn(
|
|
170
|
-
"text-xs",
|
|
171
178
|
checkShow(String(menu_head_key)) && "rotate-180",
|
|
172
179
|
)}
|
|
173
180
|
/>
|
|
@@ -189,16 +196,14 @@ export function SidebarComponent({
|
|
|
189
196
|
<div
|
|
190
197
|
className={cn(
|
|
191
198
|
"sidebar-item",
|
|
192
|
-
menu?.path &&
|
|
193
|
-
cekActive(menu?.path || "") &&
|
|
194
|
-
"sidebar-item-active",
|
|
199
|
+
menu?.path && cekActive(menu?.path || "") && "sidebar-item-active",
|
|
195
200
|
pcn<CT>(className, "item"),
|
|
196
201
|
menu?.className,
|
|
197
202
|
)}
|
|
198
203
|
>
|
|
199
204
|
<div className="flex gap-2 items-center">
|
|
200
205
|
{menu?.leftContent}
|
|
201
|
-
<span className="
|
|
206
|
+
<span className="font-medium">
|
|
202
207
|
{menu?.label}
|
|
203
208
|
</span>
|
|
204
209
|
</div>
|
|
@@ -206,9 +211,9 @@ export function SidebarComponent({
|
|
|
206
211
|
{menu?.rightContent}
|
|
207
212
|
|
|
208
213
|
{menu?.items?.length && (
|
|
209
|
-
<
|
|
210
|
-
icon={
|
|
211
|
-
className={`text-
|
|
214
|
+
<Icon
|
|
215
|
+
icon={"solid/chevron-up"}
|
|
216
|
+
className={`text-[10px] ${
|
|
212
217
|
checkShow(
|
|
213
218
|
`${menu_head_key}.${menu_key}`,
|
|
214
219
|
) || "rotate-180"
|
|
@@ -251,7 +256,7 @@ export function SidebarComponent({
|
|
|
251
256
|
>
|
|
252
257
|
<div className="flex gap-2 items-center">
|
|
253
258
|
{child?.leftContent}
|
|
254
|
-
<span className="text-
|
|
259
|
+
<span className="text-[10px] font-medium">
|
|
255
260
|
{child?.label}
|
|
256
261
|
</span>
|
|
257
262
|
</div>
|
|
@@ -259,9 +264,9 @@ export function SidebarComponent({
|
|
|
259
264
|
{child?.rightContent}
|
|
260
265
|
|
|
261
266
|
{child?.items?.length && (
|
|
262
|
-
<
|
|
263
|
-
icon={
|
|
264
|
-
className={`block text-
|
|
267
|
+
<Icon
|
|
268
|
+
icon={"solid/chevron-up"}
|
|
269
|
+
className={`block text-[10px] ${
|
|
265
270
|
checkShow(
|
|
266
271
|
`${menu_head_key}.${menu_key}`,
|
|
267
272
|
) || "rotate-180"
|
|
@@ -284,6 +289,10 @@ export function SidebarComponent({
|
|
|
284
289
|
);
|
|
285
290
|
})}
|
|
286
291
|
</nav>
|
|
292
|
+
|
|
293
|
+
<div className={toggle[`SIDEBAR${id ? "" : "_" + id?.toUpperCase()}`] ? "block" : "hidden lg:block"}>
|
|
294
|
+
{footer}
|
|
295
|
+
</div>
|
|
287
296
|
</aside>
|
|
288
297
|
</>
|
|
289
298
|
);
|
|
@@ -291,7 +300,7 @@ export function SidebarComponent({
|
|
|
291
300
|
|
|
292
301
|
export function SidebarContentComponent({ children }: { children: ReactNode }) {
|
|
293
302
|
return (
|
|
294
|
-
<main className="
|
|
303
|
+
<main className="w-full sm:ml-14 sm:w-[calc(100vw-56px)] lg:ml-[280px] lg:w-[calc(100vw-280px)] min-h-screen overflow-x-hidden">
|
|
295
304
|
{children}
|
|
296
305
|
</main>
|
|
297
306
|
);
|