@bigtablet/design-system 1.6.7 → 1.7.1
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/next.css +38 -5
- package/dist/next.d.ts +15 -5
- package/dist/next.js +73 -3
- package/package.json +1 -1
package/dist/next.css
CHANGED
|
@@ -29,14 +29,18 @@
|
|
|
29
29
|
gap: 0.25rem;
|
|
30
30
|
padding: 0.5rem 0;
|
|
31
31
|
}
|
|
32
|
+
.sidebar_group {
|
|
33
|
+
display: grid;
|
|
34
|
+
gap: 0.25rem;
|
|
35
|
+
}
|
|
32
36
|
.sidebar_item {
|
|
33
37
|
display: grid;
|
|
34
|
-
grid-template-columns: 24px 1fr;
|
|
38
|
+
grid-template-columns: 24px 1fr auto;
|
|
35
39
|
align-items: center;
|
|
36
40
|
gap: 0.5rem;
|
|
37
41
|
padding: 0.5rem 0.75rem;
|
|
38
42
|
border-radius: 8px;
|
|
39
|
-
color: #
|
|
43
|
+
color: #6b7280;
|
|
40
44
|
background: transparent;
|
|
41
45
|
border: 1px solid transparent;
|
|
42
46
|
cursor: pointer;
|
|
@@ -71,9 +75,6 @@
|
|
|
71
75
|
border-radius: 9999px;
|
|
72
76
|
background: #000000;
|
|
73
77
|
}
|
|
74
|
-
.sidebar_item.is_active .sidebar_icon {
|
|
75
|
-
color: #1f2937;
|
|
76
|
-
}
|
|
77
78
|
.sidebar_icon {
|
|
78
79
|
display: inline-grid;
|
|
79
80
|
place-items: center;
|
|
@@ -83,4 +84,36 @@
|
|
|
83
84
|
.sidebar_label {
|
|
84
85
|
white-space: nowrap;
|
|
85
86
|
text-overflow: ellipsis;
|
|
87
|
+
text-align: left;
|
|
88
|
+
}
|
|
89
|
+
.sidebar_label.is_active {
|
|
90
|
+
color: #000000;
|
|
91
|
+
font-weight: 500;
|
|
92
|
+
}
|
|
93
|
+
.sidebar_chevron {
|
|
94
|
+
display: inline-grid;
|
|
95
|
+
place-items: center;
|
|
96
|
+
color: #6b7280;
|
|
97
|
+
transition: transform 0.2s ease-out;
|
|
98
|
+
}
|
|
99
|
+
.sidebar_chevron.is_open {
|
|
100
|
+
transform: rotate(180deg);
|
|
101
|
+
}
|
|
102
|
+
.sidebar_sub {
|
|
103
|
+
display: grid;
|
|
104
|
+
gap: 0.25rem;
|
|
105
|
+
padding-left: 1rem;
|
|
106
|
+
}
|
|
107
|
+
.sidebar_sub_item {
|
|
108
|
+
padding: 0.25rem 0.75rem;
|
|
109
|
+
border-radius: 6px;
|
|
110
|
+
color: #6b7280;
|
|
111
|
+
}
|
|
112
|
+
.sidebar_sub_item:hover {
|
|
113
|
+
background: #fafafa;
|
|
114
|
+
color: #1f2937;
|
|
115
|
+
}
|
|
116
|
+
.sidebar_sub_item.is_active {
|
|
117
|
+
color: #000000;
|
|
118
|
+
font-weight: 500;
|
|
86
119
|
}
|
package/dist/next.d.ts
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
+
import { LucideIcon } from 'lucide-react';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
type MatchMode = "startsWith" | "exact";
|
|
6
|
+
/** 단일 링크 메뉴 */
|
|
7
|
+
interface SidebarLinkItem {
|
|
8
|
+
type?: "link";
|
|
5
9
|
href: string;
|
|
6
10
|
label: React.ReactNode;
|
|
7
|
-
icon?:
|
|
8
|
-
size?: number;
|
|
9
|
-
}>;
|
|
11
|
+
icon?: LucideIcon;
|
|
10
12
|
}
|
|
11
|
-
|
|
13
|
+
/** 서브 메뉴 그룹 */
|
|
14
|
+
interface SidebarGroupItem {
|
|
15
|
+
type: "group";
|
|
16
|
+
id: string;
|
|
17
|
+
label: React.ReactNode;
|
|
18
|
+
icon?: LucideIcon;
|
|
19
|
+
children: SidebarLinkItem[];
|
|
20
|
+
}
|
|
21
|
+
type SidebarItem = SidebarLinkItem | SidebarGroupItem;
|
|
12
22
|
interface SidebarProps {
|
|
13
23
|
items?: SidebarItem[];
|
|
14
24
|
activePath?: string;
|
package/dist/next.js
CHANGED
|
@@ -3,6 +3,7 @@ import './next.css';
|
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import Link from 'next/link';
|
|
5
5
|
import Image from 'next/image';
|
|
6
|
+
import { ChevronDown } from 'lucide-react';
|
|
6
7
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
8
|
|
|
8
9
|
// src/ui/navigation/sidebar/index.tsx
|
|
@@ -20,6 +21,21 @@ var Sidebar = ({
|
|
|
20
21
|
if (!activePath) return false;
|
|
21
22
|
return match === "exact" ? activePath === href : activePath.startsWith(href);
|
|
22
23
|
};
|
|
24
|
+
const [openGroups, setOpenGroups] = React.useState([]);
|
|
25
|
+
React.useEffect(() => {
|
|
26
|
+
if (!activePath) return;
|
|
27
|
+
const autoOpenIds = items.filter(
|
|
28
|
+
(item) => item.type === "group" && item.children.some((child) => isActive(child.href))
|
|
29
|
+
).map((group) => group.id);
|
|
30
|
+
setOpenGroups(
|
|
31
|
+
(prev) => Array.from(/* @__PURE__ */ new Set([...prev, ...autoOpenIds]))
|
|
32
|
+
);
|
|
33
|
+
}, [activePath, items]);
|
|
34
|
+
const toggleGroup = (id) => {
|
|
35
|
+
setOpenGroups(
|
|
36
|
+
(prev) => prev.includes(id) ? prev.filter((v) => v !== id) : [...prev, id]
|
|
37
|
+
);
|
|
38
|
+
};
|
|
23
39
|
const rootClassName = ["sidebar", className ?? ""].filter(Boolean).join(" ");
|
|
24
40
|
return /* @__PURE__ */ jsxs(
|
|
25
41
|
"aside",
|
|
@@ -48,6 +64,52 @@ var Sidebar = ({
|
|
|
48
64
|
}
|
|
49
65
|
) }),
|
|
50
66
|
/* @__PURE__ */ jsx("nav", { className: "sidebar_nav", children: items.map((item) => {
|
|
67
|
+
if (item.type === "group") {
|
|
68
|
+
const isOpen = openGroups.includes(item.id);
|
|
69
|
+
return /* @__PURE__ */ jsxs("div", { className: "sidebar_group", children: [
|
|
70
|
+
/* @__PURE__ */ jsxs(
|
|
71
|
+
"button",
|
|
72
|
+
{
|
|
73
|
+
type: "button",
|
|
74
|
+
className: [
|
|
75
|
+
"sidebar_item",
|
|
76
|
+
isOpen && "is_open"
|
|
77
|
+
].filter(Boolean).join(" "),
|
|
78
|
+
onClick: () => toggleGroup(item.id),
|
|
79
|
+
children: [
|
|
80
|
+
item.icon && /* @__PURE__ */ jsx("span", { className: "sidebar_icon", children: /* @__PURE__ */ jsx(item.icon, { size: 16 }) }),
|
|
81
|
+
/* @__PURE__ */ jsx("span", { className: "sidebar_label", children: item.label }),
|
|
82
|
+
/* @__PURE__ */ jsx(
|
|
83
|
+
"span",
|
|
84
|
+
{
|
|
85
|
+
className: [
|
|
86
|
+
"sidebar_chevron",
|
|
87
|
+
isOpen && "is_open"
|
|
88
|
+
].filter(Boolean).join(" "),
|
|
89
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { size: 16 })
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
),
|
|
95
|
+
isOpen && /* @__PURE__ */ jsx("div", { className: "sidebar_sub", children: item.children.map((child) => {
|
|
96
|
+
const active2 = isActive(child.href);
|
|
97
|
+
return /* @__PURE__ */ jsx(
|
|
98
|
+
Link,
|
|
99
|
+
{
|
|
100
|
+
href: child.href,
|
|
101
|
+
className: [
|
|
102
|
+
"sidebar_sub_item",
|
|
103
|
+
active2 && "is_active"
|
|
104
|
+
].filter(Boolean).join(" "),
|
|
105
|
+
onClick: () => onItemSelect?.(child.href),
|
|
106
|
+
children: child.label
|
|
107
|
+
},
|
|
108
|
+
child.href
|
|
109
|
+
);
|
|
110
|
+
}) })
|
|
111
|
+
] }, item.id);
|
|
112
|
+
}
|
|
51
113
|
const active = isActive(item.href);
|
|
52
114
|
return /* @__PURE__ */ jsxs(
|
|
53
115
|
Link,
|
|
@@ -58,10 +120,18 @@ var Sidebar = ({
|
|
|
58
120
|
active && "is_active"
|
|
59
121
|
].filter(Boolean).join(" "),
|
|
60
122
|
onClick: () => onItemSelect?.(item.href),
|
|
61
|
-
title: typeof item.label === "string" ? item.label : void 0,
|
|
62
123
|
children: [
|
|
63
|
-
item.icon && /* @__PURE__ */ jsx("span", { className: "sidebar_icon", children:
|
|
64
|
-
/* @__PURE__ */ jsx(
|
|
124
|
+
item.icon && /* @__PURE__ */ jsx("span", { className: "sidebar_icon", children: /* @__PURE__ */ jsx(item.icon, { size: 16 }) }),
|
|
125
|
+
/* @__PURE__ */ jsx(
|
|
126
|
+
"span",
|
|
127
|
+
{
|
|
128
|
+
className: [
|
|
129
|
+
"sidebar_label",
|
|
130
|
+
active && "is_active"
|
|
131
|
+
].filter(Boolean).join(" "),
|
|
132
|
+
children: item.label
|
|
133
|
+
}
|
|
134
|
+
)
|
|
65
135
|
]
|
|
66
136
|
},
|
|
67
137
|
item.href
|