@akira-io/ui 1.3.1 → 2.1.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/README.md +2 -2
- package/dist/blocks.d.ts +100 -10
- package/dist/blocks.js +547 -270
- package/dist/blocks.js.map +1 -1
- package/dist/{chunk-3Z2VGVPI.js → chunk-53V4J7MC.js} +17 -7
- package/dist/chunk-53V4J7MC.js.map +1 -0
- package/dist/chunk-BH3B26DK.js +394 -0
- package/dist/chunk-BH3B26DK.js.map +1 -0
- package/dist/chunk-BP2YDMMI.js +29 -0
- package/dist/chunk-BP2YDMMI.js.map +1 -0
- package/dist/chunk-BR3JI3KN.js +458 -0
- package/dist/chunk-BR3JI3KN.js.map +1 -0
- package/dist/{chunk-YBXRJSR3.js → chunk-CAUTXZ4U.js} +15 -7
- package/dist/chunk-CAUTXZ4U.js.map +1 -0
- package/dist/{chunk-I6VVCFZ2.js → chunk-DPLCEU34.js} +342 -238
- package/dist/chunk-DPLCEU34.js.map +1 -0
- package/dist/chunk-IQMRJXEO.js +5 -4
- package/dist/chunk-IQMRJXEO.js.map +1 -1
- package/dist/chunk-L2H5GIF7.js +5 -4
- package/dist/chunk-L2H5GIF7.js.map +1 -1
- package/dist/{chunk-2V6HUWST.js → chunk-NKPFIA32.js} +19 -6
- package/dist/chunk-NKPFIA32.js.map +1 -0
- package/dist/{chunk-QNF4LJVT.js → chunk-OS7YY5R4.js} +8 -6
- package/dist/chunk-OS7YY5R4.js.map +1 -0
- package/dist/{chunk-IDNOI4OK.js → chunk-PCYYU332.js} +15 -8
- package/dist/chunk-PCYYU332.js.map +1 -0
- package/dist/{chunk-KHOA4TEI.js → chunk-PPWJK5T3.js} +60 -25
- package/dist/chunk-PPWJK5T3.js.map +1 -0
- package/dist/{chunk-N2KIFFI7.js → chunk-QZRSQVCN.js} +30 -34
- package/dist/chunk-QZRSQVCN.js.map +1 -0
- package/dist/{chunk-SZUXATOF.js → chunk-XLAOE5MV.js} +170 -76
- package/dist/chunk-XLAOE5MV.js.map +1 -0
- package/dist/{chunk-B3L6PRLX.js → chunk-ZQXZ4UGE.js} +208 -100
- package/dist/chunk-ZQXZ4UGE.js.map +1 -0
- package/dist/code.d.ts +2 -2
- package/dist/code.js +96 -52
- package/dist/code.js.map +1 -1
- package/dist/{context-OwSoVEri.d.ts → context-2wTOwxCk.d.ts} +13 -5
- package/dist/editor.d.ts +1 -1
- package/dist/editor.js +135 -52
- package/dist/editor.js.map +1 -1
- package/dist/{field-DWm5NXeV.d.ts → field-C1TdmC2t.d.ts} +1 -1
- package/dist/index.d.ts +15 -12
- package/dist/index.js +1105 -633
- package/dist/index.js.map +1 -1
- package/dist/inertia.d.ts +11 -3
- package/dist/inertia.js +66 -12
- package/dist/inertia.js.map +1 -1
- package/dist/{input-Dxnsxi-f.d.ts → input-B4uEClxB.d.ts} +1 -1
- package/dist/{json-viewer-BARA2RCW.d.ts → json-viewer-Bssv9mTD.d.ts} +1 -1
- package/dist/locales/fr.d.ts +44 -0
- package/dist/locales/fr.js +248 -0
- package/dist/locales/fr.js.map +1 -0
- package/dist/locales/pt.d.ts +10 -9
- package/dist/locales/pt.js +40 -3
- package/dist/locales/pt.js.map +1 -1
- package/dist/shells.d.ts +46 -5
- package/dist/shells.js +211 -71
- package/dist/shells.js.map +1 -1
- package/dist/{sidebar-Bp6Q46j-.d.ts → sidebar-BLL2tgTt.d.ts} +2 -2
- package/dist/types-1LUmNJf_.d.ts +41 -0
- package/dist/{types-cmBL8zOc.d.ts → types-CMZRvMV5.d.ts} +1 -1
- package/dist/{types-B-eGPoFD.d.ts → types-CfAUvz--.d.ts} +1 -1
- package/package.json +8 -2
- package/theme.css +11 -0
- package/dist/chunk-2V6HUWST.js.map +0 -1
- package/dist/chunk-3Z2VGVPI.js.map +0 -1
- package/dist/chunk-B3L6PRLX.js.map +0 -1
- package/dist/chunk-I6VVCFZ2.js.map +0 -1
- package/dist/chunk-IDNOI4OK.js.map +0 -1
- package/dist/chunk-KHOA4TEI.js.map +0 -1
- package/dist/chunk-N2KIFFI7.js.map +0 -1
- package/dist/chunk-NGMG2UWX.js +0 -172
- package/dist/chunk-NGMG2UWX.js.map +0 -1
- package/dist/chunk-QNF4LJVT.js.map +0 -1
- package/dist/chunk-SZUXATOF.js.map +0 -1
- package/dist/chunk-YBXRJSR3.js.map +0 -1
- package/dist/types-u1qfmJQi.d.ts +0 -28
|
@@ -1,11 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import {
|
|
2
|
+
Avatar,
|
|
3
|
+
AvatarFallback,
|
|
4
|
+
AvatarImage,
|
|
5
|
+
Breadcrumb,
|
|
6
|
+
BreadcrumbItem,
|
|
7
|
+
BreadcrumbLink,
|
|
8
|
+
BreadcrumbList,
|
|
9
|
+
BreadcrumbPage,
|
|
10
|
+
BreadcrumbSeparator,
|
|
11
|
+
Collapsible,
|
|
12
|
+
CollapsibleContent,
|
|
13
|
+
CollapsibleTrigger,
|
|
14
|
+
DropdownMenu,
|
|
15
|
+
DropdownMenuContent,
|
|
16
|
+
DropdownMenuGroup,
|
|
17
|
+
DropdownMenuItem,
|
|
18
|
+
DropdownMenuLabel,
|
|
19
|
+
DropdownMenuSeparator,
|
|
20
|
+
DropdownMenuTrigger,
|
|
21
|
+
Icon,
|
|
22
|
+
Sidebar,
|
|
23
|
+
SidebarContent,
|
|
24
|
+
SidebarFooter,
|
|
25
|
+
SidebarGroup,
|
|
26
|
+
SidebarGroupContent,
|
|
27
|
+
SidebarGroupLabel,
|
|
28
|
+
SidebarHeader,
|
|
29
|
+
SidebarMenu,
|
|
30
|
+
SidebarMenuButton,
|
|
31
|
+
SidebarMenuItem,
|
|
32
|
+
SidebarTrigger,
|
|
33
|
+
useIsMobile,
|
|
34
|
+
useSidebar
|
|
35
|
+
} from "./chunk-ZQXZ4UGE.js";
|
|
36
|
+
import {
|
|
37
|
+
hrefToString,
|
|
38
|
+
resolveLink
|
|
39
|
+
} from "./chunk-L2H5GIF7.js";
|
|
40
|
+
import {
|
|
41
|
+
Separator
|
|
42
|
+
} from "./chunk-53V4J7MC.js";
|
|
43
|
+
import {
|
|
44
|
+
Button,
|
|
45
|
+
cn,
|
|
46
|
+
compactRadius
|
|
47
|
+
} from "./chunk-PPWJK5T3.js";
|
|
8
48
|
|
|
49
|
+
// src/hooks/use-collapsed-groups.tsx
|
|
50
|
+
import { useCallback, useState } from "react";
|
|
9
51
|
var SIDEBAR_COLLAPSED_GROUPS_KEY = "akira-ui:collapsed-nav-groups";
|
|
10
52
|
function readCollapsedGroups() {
|
|
11
53
|
if (typeof window === "undefined") {
|
|
@@ -72,8 +114,11 @@ function useCollapsedGroup({
|
|
|
72
114
|
const source = isControlled ? collapsedGroups : storedGroups;
|
|
73
115
|
return { open: !source.includes(group), setOpen };
|
|
74
116
|
}
|
|
117
|
+
|
|
118
|
+
// src/hooks/use-initials.tsx
|
|
119
|
+
import { useCallback as useCallback2 } from "react";
|
|
75
120
|
function useInitials() {
|
|
76
|
-
return
|
|
121
|
+
return useCallback2((fullName) => {
|
|
77
122
|
const names = fullName.trim().split(" ");
|
|
78
123
|
if (names.length === 0) return "";
|
|
79
124
|
if (names.length === 1) return names[0].charAt(0).toUpperCase();
|
|
@@ -82,6 +127,9 @@ function useInitials() {
|
|
|
82
127
|
return `${firstInitial}${lastInitial}`.toUpperCase();
|
|
83
128
|
}, []);
|
|
84
129
|
}
|
|
130
|
+
|
|
131
|
+
// src/shells/nav-footer.tsx
|
|
132
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
85
133
|
function NavFooter({
|
|
86
134
|
items,
|
|
87
135
|
className,
|
|
@@ -120,6 +168,10 @@ function NavFooter({
|
|
|
120
168
|
}
|
|
121
169
|
);
|
|
122
170
|
}
|
|
171
|
+
|
|
172
|
+
// src/shells/nav-main.tsx
|
|
173
|
+
import { ChevronDown } from "lucide-react";
|
|
174
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
123
175
|
function isItemActive(item, currentUrl) {
|
|
124
176
|
if (item.isActive !== void 0) {
|
|
125
177
|
return item.isActive;
|
|
@@ -150,28 +202,28 @@ function NavMain({
|
|
|
150
202
|
onCollapsedChange
|
|
151
203
|
});
|
|
152
204
|
const expanded = open || holdsCurrentRoute;
|
|
153
|
-
const menu = /* @__PURE__ */
|
|
205
|
+
const menu = /* @__PURE__ */ jsx2(SidebarMenu, { children: items.map((item) => /* @__PURE__ */ jsx2(SidebarMenuItem, { children: /* @__PURE__ */ jsx2(
|
|
154
206
|
SidebarMenuButton,
|
|
155
207
|
{
|
|
156
208
|
asChild: true,
|
|
157
209
|
isActive: isItemActive(item, currentUrl),
|
|
158
210
|
tooltip: { children: item.title },
|
|
159
|
-
children: /* @__PURE__ */
|
|
160
|
-
item.icon && /* @__PURE__ */
|
|
161
|
-
/* @__PURE__ */
|
|
211
|
+
children: /* @__PURE__ */ jsxs2(Link, { href: item.href, prefetch: true, children: [
|
|
212
|
+
item.icon && /* @__PURE__ */ jsx2(item.icon, {}),
|
|
213
|
+
/* @__PURE__ */ jsx2("span", { children: item.title })
|
|
162
214
|
] })
|
|
163
215
|
}
|
|
164
216
|
) }, item.title)) });
|
|
165
217
|
if (!collapsible || !label) {
|
|
166
|
-
return /* @__PURE__ */
|
|
167
|
-
label && /* @__PURE__ */
|
|
218
|
+
return /* @__PURE__ */ jsxs2(SidebarGroup, { className: "px-2 py-0", children: [
|
|
219
|
+
label && /* @__PURE__ */ jsx2(SidebarGroupLabel, { children: label }),
|
|
168
220
|
menu
|
|
169
221
|
] });
|
|
170
222
|
}
|
|
171
|
-
return /* @__PURE__ */
|
|
172
|
-
/* @__PURE__ */
|
|
223
|
+
return /* @__PURE__ */ jsx2(SidebarGroup, { className: "px-2 py-0", children: /* @__PURE__ */ jsxs2(Collapsible, { open: expanded, onOpenChange: setOpen, children: [
|
|
224
|
+
/* @__PURE__ */ jsx2(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsxs2(SidebarGroupLabel, { className: "w-full cursor-pointer justify-between", children: [
|
|
173
225
|
label,
|
|
174
|
-
/* @__PURE__ */
|
|
226
|
+
/* @__PURE__ */ jsx2(
|
|
175
227
|
ChevronDown,
|
|
176
228
|
{
|
|
177
229
|
className: cn(
|
|
@@ -181,16 +233,19 @@ function NavMain({
|
|
|
181
233
|
}
|
|
182
234
|
)
|
|
183
235
|
] }) }),
|
|
184
|
-
/* @__PURE__ */
|
|
236
|
+
/* @__PURE__ */ jsx2(CollapsibleContent, { children: menu })
|
|
185
237
|
] }) });
|
|
186
238
|
}
|
|
239
|
+
|
|
240
|
+
// src/shells/user-info.tsx
|
|
241
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
187
242
|
function UserInfo({
|
|
188
243
|
user,
|
|
189
244
|
showEmail = false
|
|
190
245
|
}) {
|
|
191
246
|
const getInitials = useInitials();
|
|
192
|
-
return /* @__PURE__ */
|
|
193
|
-
/* @__PURE__ */
|
|
247
|
+
return /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
248
|
+
/* @__PURE__ */ jsxs3(
|
|
194
249
|
Avatar,
|
|
195
250
|
{
|
|
196
251
|
className: cn(
|
|
@@ -198,8 +253,8 @@ function UserInfo({
|
|
|
198
253
|
"group-data-[collapsible=icon]:size-10"
|
|
199
254
|
),
|
|
200
255
|
children: [
|
|
201
|
-
/* @__PURE__ */
|
|
202
|
-
/* @__PURE__ */
|
|
256
|
+
/* @__PURE__ */ jsx3(AvatarImage, { src: user.avatar, alt: user.name }),
|
|
257
|
+
/* @__PURE__ */ jsx3(
|
|
203
258
|
AvatarFallback,
|
|
204
259
|
{
|
|
205
260
|
className: cn(compactRadius, "bg-muted text-foreground"),
|
|
@@ -209,19 +264,23 @@ function UserInfo({
|
|
|
209
264
|
]
|
|
210
265
|
}
|
|
211
266
|
),
|
|
212
|
-
/* @__PURE__ */
|
|
267
|
+
/* @__PURE__ */ jsxs3(
|
|
213
268
|
"div",
|
|
214
269
|
{
|
|
215
270
|
"data-slot": "user-info-identity",
|
|
216
271
|
className: "text-sm leading-tight grid flex-1 text-left group-data-[collapsible=icon]:hidden",
|
|
217
272
|
children: [
|
|
218
|
-
/* @__PURE__ */
|
|
219
|
-
showEmail && /* @__PURE__ */
|
|
273
|
+
/* @__PURE__ */ jsx3("span", { className: "font-medium truncate", children: user.name }),
|
|
274
|
+
showEmail && /* @__PURE__ */ jsx3("span", { className: "text-xs truncate text-muted-foreground", children: user.email })
|
|
220
275
|
]
|
|
221
276
|
}
|
|
222
277
|
)
|
|
223
278
|
] });
|
|
224
279
|
}
|
|
280
|
+
|
|
281
|
+
// src/shells/user-menu-content.tsx
|
|
282
|
+
import { LogOut, Settings } from "lucide-react";
|
|
283
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
225
284
|
function UserMenuContent({
|
|
226
285
|
user,
|
|
227
286
|
settingsHref,
|
|
@@ -233,10 +292,10 @@ function UserMenuContent({
|
|
|
233
292
|
logoutLabel = "Log out"
|
|
234
293
|
}) {
|
|
235
294
|
const Link = resolveLink(linkComponent);
|
|
236
|
-
return /* @__PURE__ */
|
|
237
|
-
/* @__PURE__ */
|
|
238
|
-
/* @__PURE__ */
|
|
239
|
-
/* @__PURE__ */
|
|
295
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
296
|
+
/* @__PURE__ */ jsx4(DropdownMenuLabel, { className: "p-0 font-normal", children: /* @__PURE__ */ jsx4("div", { className: "gap-2 px-1 py-1.5 text-sm flex items-center text-left", children: /* @__PURE__ */ jsx4(UserInfo, { user, showEmail: true }) }) }),
|
|
297
|
+
/* @__PURE__ */ jsx4(DropdownMenuSeparator, {}),
|
|
298
|
+
/* @__PURE__ */ jsx4(DropdownMenuGroup, { children: /* @__PURE__ */ jsx4(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs4(
|
|
240
299
|
Link,
|
|
241
300
|
{
|
|
242
301
|
className: "block w-full",
|
|
@@ -245,13 +304,13 @@ function UserMenuContent({
|
|
|
245
304
|
prefetch: true,
|
|
246
305
|
onClick: onSettingsClick,
|
|
247
306
|
children: [
|
|
248
|
-
/* @__PURE__ */
|
|
307
|
+
/* @__PURE__ */ jsx4(Settings, { className: "mr-2" }),
|
|
249
308
|
settingsLabel
|
|
250
309
|
]
|
|
251
310
|
}
|
|
252
311
|
) }) }),
|
|
253
|
-
/* @__PURE__ */
|
|
254
|
-
/* @__PURE__ */
|
|
312
|
+
/* @__PURE__ */ jsx4(DropdownMenuSeparator, {}),
|
|
313
|
+
/* @__PURE__ */ jsx4(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs4(
|
|
255
314
|
Link,
|
|
256
315
|
{
|
|
257
316
|
className: "block w-full",
|
|
@@ -260,13 +319,17 @@ function UserMenuContent({
|
|
|
260
319
|
onClick: onLogout,
|
|
261
320
|
"data-test": "logout-button",
|
|
262
321
|
children: [
|
|
263
|
-
/* @__PURE__ */
|
|
322
|
+
/* @__PURE__ */ jsx4(LogOut, { className: "mr-2" }),
|
|
264
323
|
logoutLabel
|
|
265
324
|
]
|
|
266
325
|
}
|
|
267
326
|
) })
|
|
268
327
|
] });
|
|
269
328
|
}
|
|
329
|
+
|
|
330
|
+
// src/shells/nav-user.tsx
|
|
331
|
+
import { ChevronsUpDown } from "lucide-react";
|
|
332
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
270
333
|
function NavUser({
|
|
271
334
|
user,
|
|
272
335
|
settingsHref,
|
|
@@ -277,15 +340,15 @@ function NavUser({
|
|
|
277
340
|
}) {
|
|
278
341
|
const { state } = useSidebar();
|
|
279
342
|
const isMobile = useIsMobile();
|
|
280
|
-
return /* @__PURE__ */
|
|
281
|
-
/* @__PURE__ */
|
|
343
|
+
return /* @__PURE__ */ jsx5(SidebarMenu, { children: /* @__PURE__ */ jsx5(SidebarMenuItem, { children: /* @__PURE__ */ jsxs5(DropdownMenu, { children: [
|
|
344
|
+
/* @__PURE__ */ jsx5(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs5(
|
|
282
345
|
SidebarMenuButton,
|
|
283
346
|
{
|
|
284
347
|
className: "group group-data-[collapsible=icon]:p-0! cursor-pointer bg-sidebar-accent text-sidebar-accent-foreground hover:bg-sidebar-accent-hover data-[state=open]:bg-sidebar-accent-hover",
|
|
285
348
|
"data-test": "sidebar-menu-button",
|
|
286
349
|
children: [
|
|
287
|
-
/* @__PURE__ */
|
|
288
|
-
/* @__PURE__ */
|
|
350
|
+
/* @__PURE__ */ jsx5(UserInfo, { user }),
|
|
351
|
+
/* @__PURE__ */ jsx5(
|
|
289
352
|
ChevronsUpDown,
|
|
290
353
|
{
|
|
291
354
|
"data-slot": "nav-user-chevron",
|
|
@@ -295,13 +358,13 @@ function NavUser({
|
|
|
295
358
|
]
|
|
296
359
|
}
|
|
297
360
|
) }),
|
|
298
|
-
/* @__PURE__ */
|
|
361
|
+
/* @__PURE__ */ jsx5(
|
|
299
362
|
DropdownMenuContent,
|
|
300
363
|
{
|
|
301
364
|
className: "min-w-56 rounded-xl w-(--radix-dropdown-menu-trigger-width)",
|
|
302
365
|
align: "end",
|
|
303
366
|
side: isMobile ? "bottom" : state === "collapsed" ? "left" : "bottom",
|
|
304
|
-
children: /* @__PURE__ */
|
|
367
|
+
children: /* @__PURE__ */ jsx5(
|
|
305
368
|
UserMenuContent,
|
|
306
369
|
{
|
|
307
370
|
user,
|
|
@@ -316,6 +379,9 @@ function NavUser({
|
|
|
316
379
|
)
|
|
317
380
|
] }) }) });
|
|
318
381
|
}
|
|
382
|
+
|
|
383
|
+
// src/shells/app-sidebar.tsx
|
|
384
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
319
385
|
function mostSpecificActiveHref(groups, currentUrl) {
|
|
320
386
|
let best = "";
|
|
321
387
|
for (const group of groups) {
|
|
@@ -354,9 +420,9 @@ function AppSidebar({
|
|
|
354
420
|
isActive: hrefToString(item.href) === activeHref
|
|
355
421
|
}))
|
|
356
422
|
}));
|
|
357
|
-
return /* @__PURE__ */
|
|
358
|
-
/* @__PURE__ */
|
|
359
|
-
/* @__PURE__ */
|
|
423
|
+
return /* @__PURE__ */ jsxs6(Sidebar, { collapsible: "icon", variant: "inset", children: [
|
|
424
|
+
/* @__PURE__ */ jsx6(SidebarHeader, { children: /* @__PURE__ */ jsx6(SidebarMenu, { children: /* @__PURE__ */ jsx6(SidebarMenuItem, { children: /* @__PURE__ */ jsx6(SidebarMenuButton, { asChild: true, children: /* @__PURE__ */ jsx6(Link, { href: logoHref, prefetch: true, children: logo }) }) }) }) }),
|
|
425
|
+
/* @__PURE__ */ jsx6(SidebarContent, { children: resolvedGroups.map((group, index) => /* @__PURE__ */ jsx6(
|
|
360
426
|
NavMain,
|
|
361
427
|
{
|
|
362
428
|
items: group.items,
|
|
@@ -369,9 +435,9 @@ function AppSidebar({
|
|
|
369
435
|
},
|
|
370
436
|
group.label ?? index
|
|
371
437
|
)) }),
|
|
372
|
-
/* @__PURE__ */
|
|
373
|
-
footerItems.length > 0 && /* @__PURE__ */
|
|
374
|
-
/* @__PURE__ */
|
|
438
|
+
/* @__PURE__ */ jsxs6(SidebarFooter, { children: [
|
|
439
|
+
footerItems.length > 0 && /* @__PURE__ */ jsx6(NavFooter, { items: footerItems, className: "mt-auto" }),
|
|
440
|
+
/* @__PURE__ */ jsx6(
|
|
375
441
|
NavUser,
|
|
376
442
|
{
|
|
377
443
|
user,
|
|
@@ -385,6 +451,10 @@ function AppSidebar({
|
|
|
385
451
|
] })
|
|
386
452
|
] });
|
|
387
453
|
}
|
|
454
|
+
|
|
455
|
+
// src/shells/breadcrumbs.tsx
|
|
456
|
+
import { Fragment as Fragment3 } from "react";
|
|
457
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
388
458
|
function Breadcrumbs({
|
|
389
459
|
breadcrumbs,
|
|
390
460
|
linkComponent
|
|
@@ -393,29 +463,34 @@ function Breadcrumbs({
|
|
|
393
463
|
if (breadcrumbs.length === 0) {
|
|
394
464
|
return null;
|
|
395
465
|
}
|
|
396
|
-
return /* @__PURE__ */
|
|
466
|
+
return /* @__PURE__ */ jsx7(Breadcrumb, { children: /* @__PURE__ */ jsx7(BreadcrumbList, { children: breadcrumbs.map((item, index) => {
|
|
397
467
|
const isLast = index === breadcrumbs.length - 1;
|
|
398
|
-
return /* @__PURE__ */
|
|
399
|
-
/* @__PURE__ */
|
|
400
|
-
!isLast && /* @__PURE__ */
|
|
468
|
+
return /* @__PURE__ */ jsxs7(Fragment3, { children: [
|
|
469
|
+
/* @__PURE__ */ jsx7(BreadcrumbItem, { children: isLast ? /* @__PURE__ */ jsx7(BreadcrumbPage, { children: item.title }) : /* @__PURE__ */ jsx7(BreadcrumbLink, { asChild: true, children: /* @__PURE__ */ jsx7(Link, { href: item.href, children: item.title }) }) }),
|
|
470
|
+
!isLast && /* @__PURE__ */ jsx7(BreadcrumbSeparator, {})
|
|
401
471
|
] }, index);
|
|
402
472
|
}) }) });
|
|
403
473
|
}
|
|
474
|
+
|
|
475
|
+
// src/shells/app-sidebar-header.tsx
|
|
476
|
+
import { Search } from "lucide-react";
|
|
477
|
+
import { useEffect, useState as useState2 } from "react";
|
|
478
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
404
479
|
function AppSidebarHeader({
|
|
405
480
|
breadcrumbs = [],
|
|
406
481
|
linkComponent,
|
|
407
482
|
onSearchClick,
|
|
408
483
|
searchLabel = "Search..."
|
|
409
484
|
}) {
|
|
410
|
-
const [modifier, setModifier] =
|
|
485
|
+
const [modifier, setModifier] = useState2("Ctrl");
|
|
411
486
|
useEffect(() => {
|
|
412
487
|
const platform = navigator.userAgent;
|
|
413
488
|
setModifier(/Mac|iPhone|iPad|iPod/.test(platform) ? "\u2318" : "Ctrl");
|
|
414
489
|
}, []);
|
|
415
|
-
return /* @__PURE__ */
|
|
416
|
-
/* @__PURE__ */
|
|
417
|
-
/* @__PURE__ */
|
|
418
|
-
/* @__PURE__ */
|
|
490
|
+
return /* @__PURE__ */ jsxs8("header", { className: "h-16 gap-2 px-6 group-has-data-[collapsible=icon]/sidebar-wrapper:h-12 md:px-4 flex shrink-0 items-center border-b border-sidebar-border/50 transition-[width,height] ease-linear", children: [
|
|
491
|
+
/* @__PURE__ */ jsxs8("div", { className: "gap-2 flex items-center", children: [
|
|
492
|
+
/* @__PURE__ */ jsx8(SidebarTrigger, { className: "-ml-1" }),
|
|
493
|
+
/* @__PURE__ */ jsx8(
|
|
419
494
|
Breadcrumbs,
|
|
420
495
|
{
|
|
421
496
|
breadcrumbs,
|
|
@@ -423,33 +498,39 @@ function AppSidebarHeader({
|
|
|
423
498
|
}
|
|
424
499
|
)
|
|
425
500
|
] }),
|
|
426
|
-
onSearchClick && /* @__PURE__ */
|
|
501
|
+
onSearchClick && /* @__PURE__ */ jsxs8(
|
|
427
502
|
"button",
|
|
428
503
|
{
|
|
429
504
|
type: "button",
|
|
430
505
|
onClick: onSearchClick,
|
|
431
506
|
className: "h-9 w-56 gap-2 rounded-xl px-3 text-sm ml-auto flex items-center border border-border/60 bg-muted/30 text-muted-foreground transition-colors hover:bg-muted/50",
|
|
432
507
|
children: [
|
|
433
|
-
/* @__PURE__ */
|
|
434
|
-
/* @__PURE__ */
|
|
435
|
-
/* @__PURE__ */
|
|
436
|
-
/* @__PURE__ */
|
|
437
|
-
/* @__PURE__ */
|
|
508
|
+
/* @__PURE__ */ jsx8(Search, { className: "size-4" }),
|
|
509
|
+
/* @__PURE__ */ jsx8("span", { children: searchLabel }),
|
|
510
|
+
/* @__PURE__ */ jsxs8("kbd", { className: "gap-0.5 px-1.5 py-0.5 font-semibold rounded-xl ml-auto inline-flex items-center border border-border/60 bg-background font-sans text-[10px] text-muted-foreground", children: [
|
|
511
|
+
/* @__PURE__ */ jsx8("span", { children: modifier }),
|
|
512
|
+
/* @__PURE__ */ jsx8("span", { children: "K" })
|
|
438
513
|
] })
|
|
439
514
|
]
|
|
440
515
|
}
|
|
441
516
|
)
|
|
442
517
|
] });
|
|
443
518
|
}
|
|
519
|
+
|
|
520
|
+
// src/shells/heading.tsx
|
|
521
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
444
522
|
function Heading({
|
|
445
523
|
title,
|
|
446
524
|
description
|
|
447
525
|
}) {
|
|
448
|
-
return /* @__PURE__ */
|
|
449
|
-
/* @__PURE__ */
|
|
450
|
-
description && /* @__PURE__ */
|
|
526
|
+
return /* @__PURE__ */ jsxs9("div", { className: "mb-8 space-y-0.5", children: [
|
|
527
|
+
/* @__PURE__ */ jsx9("h2", { className: "text-xl font-semibold tracking-tight", children: title }),
|
|
528
|
+
description && /* @__PURE__ */ jsx9("p", { className: "text-sm text-muted-foreground", children: description })
|
|
451
529
|
] });
|
|
452
530
|
}
|
|
531
|
+
|
|
532
|
+
// src/shells/settings-layout.tsx
|
|
533
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
453
534
|
function SettingsLayout({
|
|
454
535
|
items,
|
|
455
536
|
linkComponent,
|
|
@@ -461,12 +542,12 @@ function SettingsLayout({
|
|
|
461
542
|
}) {
|
|
462
543
|
const Link = resolveLink(linkComponent);
|
|
463
544
|
const activePath = currentPath ?? (typeof window === "undefined" ? "" : window.location.pathname);
|
|
464
|
-
return /* @__PURE__ */
|
|
465
|
-
/* @__PURE__ */
|
|
466
|
-
/* @__PURE__ */
|
|
467
|
-
/* @__PURE__ */
|
|
545
|
+
return /* @__PURE__ */ jsxs10("div", { className: "px-4 py-6", children: [
|
|
546
|
+
/* @__PURE__ */ jsx10(Heading, { title, description }),
|
|
547
|
+
/* @__PURE__ */ jsxs10("div", { className: "lg:flex-row lg:space-x-12 flex flex-col", children: [
|
|
548
|
+
/* @__PURE__ */ jsx10("aside", { className: "max-w-xl lg:w-48 w-full", children: /* @__PURE__ */ jsx10("nav", { className: "space-y-1 space-x-0 flex flex-col", children: items.map((item, index) => {
|
|
468
549
|
const href = hrefToString(item.href);
|
|
469
|
-
return /* @__PURE__ */
|
|
550
|
+
return /* @__PURE__ */ jsx10(
|
|
470
551
|
Button,
|
|
471
552
|
{
|
|
472
553
|
size: "sm",
|
|
@@ -475,22 +556,22 @@ function SettingsLayout({
|
|
|
475
556
|
className: cn("w-full justify-start", {
|
|
476
557
|
"bg-muted": activePath === href
|
|
477
558
|
}),
|
|
478
|
-
children: /* @__PURE__ */
|
|
479
|
-
item.icon && /* @__PURE__ */
|
|
559
|
+
children: /* @__PURE__ */ jsxs10(Link, { href: item.href, children: [
|
|
560
|
+
item.icon && /* @__PURE__ */ jsx10(item.icon, { className: "h-4 w-4" }),
|
|
480
561
|
item.title
|
|
481
562
|
] })
|
|
482
563
|
},
|
|
483
564
|
`${href}-${index}`
|
|
484
565
|
);
|
|
485
566
|
}) }) }),
|
|
486
|
-
/* @__PURE__ */
|
|
487
|
-
/* @__PURE__ */
|
|
567
|
+
/* @__PURE__ */ jsx10(Separator, { className: "my-6 lg:hidden" }),
|
|
568
|
+
/* @__PURE__ */ jsx10(
|
|
488
569
|
"div",
|
|
489
570
|
{
|
|
490
571
|
className: cn(
|
|
491
572
|
wide ? "min-w-0 flex-1" : "md:max-w-2xl flex-1"
|
|
492
573
|
),
|
|
493
|
-
children: /* @__PURE__ */
|
|
574
|
+
children: /* @__PURE__ */ jsx10(
|
|
494
575
|
"section",
|
|
495
576
|
{
|
|
496
577
|
className: cn(
|
|
@@ -506,6 +587,19 @@ function SettingsLayout({
|
|
|
506
587
|
] });
|
|
507
588
|
}
|
|
508
589
|
|
|
509
|
-
export {
|
|
510
|
-
|
|
511
|
-
|
|
590
|
+
export {
|
|
591
|
+
SIDEBAR_COLLAPSED_GROUPS_KEY,
|
|
592
|
+
useCollapsedGroup,
|
|
593
|
+
useInitials,
|
|
594
|
+
NavFooter,
|
|
595
|
+
NavMain,
|
|
596
|
+
UserInfo,
|
|
597
|
+
UserMenuContent,
|
|
598
|
+
NavUser,
|
|
599
|
+
AppSidebar,
|
|
600
|
+
Breadcrumbs,
|
|
601
|
+
AppSidebarHeader,
|
|
602
|
+
Heading,
|
|
603
|
+
SettingsLayout
|
|
604
|
+
};
|
|
605
|
+
//# sourceMappingURL=chunk-XLAOE5MV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-collapsed-groups.tsx","../src/hooks/use-initials.tsx","../src/shells/nav-footer.tsx","../src/shells/nav-main.tsx","../src/shells/user-info.tsx","../src/shells/user-menu-content.tsx","../src/shells/nav-user.tsx","../src/shells/app-sidebar.tsx","../src/shells/breadcrumbs.tsx","../src/shells/app-sidebar-header.tsx","../src/shells/heading.tsx","../src/shells/settings-layout.tsx"],"sourcesContent":["import { useCallback, useState } from 'react';\n\nexport const SIDEBAR_COLLAPSED_GROUPS_KEY = 'akira-ui:collapsed-nav-groups';\n\nfunction readCollapsedGroups(): string[] | null {\n if (typeof window === 'undefined') {\n return null;\n }\n\n try {\n const raw = window.localStorage.getItem(SIDEBAR_COLLAPSED_GROUPS_KEY);\n\n if (raw === null) {\n return null;\n }\n\n const parsed: unknown = JSON.parse(raw);\n\n return Array.isArray(parsed)\n ? parsed.filter(\n (entry): entry is string => typeof entry === 'string',\n )\n : null;\n } catch {\n return null;\n }\n}\n\nfunction writeCollapsedGroups(groups: string[]): void {\n if (typeof window === 'undefined') {\n return;\n }\n\n try {\n window.localStorage.setItem(\n SIDEBAR_COLLAPSED_GROUPS_KEY,\n JSON.stringify(groups),\n );\n } catch {\n return;\n }\n}\n\nfunction withGroup(groups: string[], group: string, collapsed: boolean) {\n if (!collapsed) {\n return groups.filter((entry) => entry !== group);\n }\n\n return groups.includes(group) ? groups : [...groups, group];\n}\n\nexport interface CollapsedGroupsOptions {\n group: string;\n defaultOpen?: boolean;\n collapsedGroups?: string[];\n onCollapsedChange?: (collapsedGroups: string[]) => void;\n}\n\nexport function useCollapsedGroup({\n group,\n defaultOpen = true,\n collapsedGroups,\n onCollapsedChange,\n}: CollapsedGroupsOptions) {\n const isControlled =\n collapsedGroups !== undefined && onCollapsedChange !== undefined;\n\n const [storedGroups, setStoredGroups] = useState<string[]>(\n () => readCollapsedGroups() ?? (defaultOpen ? [] : [group]),\n );\n\n const setOpen = useCallback(\n (open: boolean) => {\n if (isControlled) {\n onCollapsedChange(withGroup(collapsedGroups, group, !open));\n\n return;\n }\n\n const next = withGroup(\n readCollapsedGroups() ?? storedGroups,\n group,\n !open,\n );\n\n setStoredGroups(next);\n writeCollapsedGroups(next);\n },\n [collapsedGroups, group, isControlled, onCollapsedChange, storedGroups],\n );\n\n const source = isControlled ? collapsedGroups : storedGroups;\n\n return { open: !source.includes(group), setOpen };\n}\n","import { useCallback } from 'react';\n\nexport function useInitials() {\n return useCallback((fullName: string): string => {\n const names = fullName.trim().split(' ');\n\n if (names.length === 0) return '';\n if (names.length === 1) return names[0].charAt(0).toUpperCase();\n\n const firstInitial = names[0].charAt(0);\n const lastInitial = names[names.length - 1].charAt(0);\n\n return `${firstInitial}${lastInitial}`.toUpperCase();\n }, []);\n}\n","import { type ComponentPropsWithoutRef } from 'react';\n\nimport { Icon } from '@/components/ui/icon';\nimport {\n SidebarGroup,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/components/ui/sidebar';\nimport { hrefToString } from '@/lib/href';\nimport type { NavItem } from '@/types';\n\nexport function NavFooter({\n items,\n className,\n ...props\n}: ComponentPropsWithoutRef<typeof SidebarGroup> & {\n items: NavItem[];\n}) {\n return (\n <SidebarGroup\n {...props}\n className={`group-data-[collapsible=icon]:p-0 ${className || ''}`}\n >\n <SidebarGroupContent>\n <SidebarMenu>\n {items.map((item) => (\n <SidebarMenuItem key={item.title}>\n <SidebarMenuButton\n asChild\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <a\n href={hrefToString(item.href)}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {item.icon && (\n <Icon\n iconNode={item.icon}\n className=\"h-5 w-5\"\n />\n )}\n <span>{item.title}</span>\n </a>\n </SidebarMenuButton>\n </SidebarMenuItem>\n ))}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n );\n}\n","import { ChevronDown } from 'lucide-react';\n\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '@/components/ui/collapsible';\nimport {\n SidebarGroup,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/components/ui/sidebar';\nimport { useCollapsedGroup } from '@/hooks/use-collapsed-groups';\nimport { hrefToString, resolveLink } from '@/lib/href';\nimport { cn } from '@/lib/utils';\nimport type { LinkComponent, NavItem } from '@/types';\n\nfunction isItemActive(item: NavItem, currentUrl: string): boolean {\n if (item.isActive !== undefined) {\n return item.isActive;\n }\n\n if (!currentUrl) {\n return false;\n }\n\n return currentUrl.startsWith(hrefToString(item.href));\n}\n\nexport interface NavMainProps {\n items: NavItem[];\n label?: string;\n currentUrl?: string;\n linkComponent?: LinkComponent;\n collapsible?: boolean;\n defaultOpen?: boolean;\n collapsedGroups?: string[];\n onCollapsedChange?: (collapsedGroups: string[]) => void;\n}\n\nexport function NavMain({\n items = [],\n label = 'Platform',\n currentUrl = '',\n linkComponent,\n collapsible = false,\n defaultOpen = true,\n collapsedGroups,\n onCollapsedChange,\n}: NavMainProps) {\n const Link = resolveLink(linkComponent);\n const holdsCurrentRoute = items.some((item) =>\n isItemActive(item, currentUrl),\n );\n const { open, setOpen } = useCollapsedGroup({\n group: label,\n defaultOpen,\n collapsedGroups,\n onCollapsedChange,\n });\n const expanded = open || holdsCurrentRoute;\n\n const menu = (\n <SidebarMenu>\n {items.map((item) => (\n <SidebarMenuItem key={item.title}>\n <SidebarMenuButton\n asChild\n isActive={isItemActive(item, currentUrl)}\n tooltip={{ children: item.title }}\n >\n <Link href={item.href} prefetch>\n {item.icon && <item.icon />}\n <span>{item.title}</span>\n </Link>\n </SidebarMenuButton>\n </SidebarMenuItem>\n ))}\n </SidebarMenu>\n );\n\n if (!collapsible || !label) {\n return (\n <SidebarGroup className=\"px-2 py-0\">\n {label && <SidebarGroupLabel>{label}</SidebarGroupLabel>}\n {menu}\n </SidebarGroup>\n );\n }\n\n return (\n <SidebarGroup className=\"px-2 py-0\">\n <Collapsible open={expanded} onOpenChange={setOpen}>\n <CollapsibleTrigger asChild>\n <SidebarGroupLabel className=\"w-full cursor-pointer justify-between\">\n {label}\n <ChevronDown\n className={cn(\n 'size-4 transition-transform',\n !expanded && '-rotate-90',\n )}\n />\n </SidebarGroupLabel>\n </CollapsibleTrigger>\n <CollapsibleContent>{menu}</CollapsibleContent>\n </Collapsible>\n </SidebarGroup>\n );\n}\n","import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';\nimport { useInitials } from '@/hooks/use-initials';\nimport { compactRadius } from '@/lib/language';\nimport { cn } from '@/lib/utils';\nimport type { SharedUser } from '@/types';\n\nexport function UserInfo({\n user,\n showEmail = false,\n}: {\n user: SharedUser;\n showEmail?: boolean;\n}) {\n const getInitials = useInitials();\n\n return (\n <>\n <Avatar\n className={cn(\n compactRadius,\n 'group-data-[collapsible=icon]:size-10',\n )}\n >\n <AvatarImage src={user.avatar} alt={user.name} />\n <AvatarFallback\n className={cn(compactRadius, 'bg-muted text-foreground')}\n >\n {getInitials(user.name)}\n </AvatarFallback>\n </Avatar>\n <div\n data-slot=\"user-info-identity\"\n className=\"text-sm leading-tight grid flex-1 text-left group-data-[collapsible=icon]:hidden\"\n >\n <span className=\"font-medium truncate\">{user.name}</span>\n {showEmail && (\n <span className=\"text-xs truncate text-muted-foreground\">\n {user.email}\n </span>\n )}\n </div>\n </>\n );\n}\n","import { LogOut, Settings } from 'lucide-react';\n\nimport {\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n} from '@/components/ui/dropdown-menu';\nimport { resolveLink } from '@/lib/href';\nimport type { LinkComponent, SharedUser, UrlLike } from '@/types';\nimport { UserInfo } from './user-info';\n\ninterface UserMenuContentProps {\n user: SharedUser;\n settingsHref: UrlLike;\n logoutHref: UrlLike;\n linkComponent?: LinkComponent;\n onSettingsClick?: () => void;\n onLogout?: () => void;\n settingsLabel?: string;\n logoutLabel?: string;\n}\n\nexport function UserMenuContent({\n user,\n settingsHref,\n logoutHref,\n linkComponent,\n onSettingsClick,\n onLogout,\n settingsLabel = 'Settings',\n logoutLabel = 'Log out',\n}: UserMenuContentProps) {\n const Link = resolveLink(linkComponent);\n\n return (\n <>\n <DropdownMenuLabel className=\"p-0 font-normal\">\n <div className=\"gap-2 px-1 py-1.5 text-sm flex items-center text-left\">\n <UserInfo user={user} showEmail={true} />\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuGroup>\n <DropdownMenuItem asChild>\n <Link\n className=\"block w-full\"\n href={settingsHref}\n as=\"button\"\n prefetch\n onClick={onSettingsClick}\n >\n <Settings className=\"mr-2\" />\n {settingsLabel}\n </Link>\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem asChild>\n <Link\n className=\"block w-full\"\n href={logoutHref}\n as=\"button\"\n onClick={onLogout}\n data-test=\"logout-button\"\n >\n <LogOut className=\"mr-2\" />\n {logoutLabel}\n </Link>\n </DropdownMenuItem>\n </>\n );\n}\n","import { ChevronsUpDown } from 'lucide-react';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport {\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n useSidebar,\n} from '@/components/ui/sidebar';\nimport { useIsMobile } from '@/hooks/use-mobile';\nimport type { LinkComponent, SharedUser, UrlLike } from '@/types';\nimport { UserInfo } from './user-info';\nimport { UserMenuContent } from './user-menu-content';\n\ninterface NavUserProps {\n user: SharedUser;\n settingsHref: UrlLike;\n logoutHref: UrlLike;\n linkComponent?: LinkComponent;\n onSettingsClick?: () => void;\n onLogout?: () => void;\n}\n\nexport function NavUser({\n user,\n settingsHref,\n logoutHref,\n linkComponent,\n onSettingsClick,\n onLogout,\n}: NavUserProps) {\n const { state } = useSidebar();\n const isMobile = useIsMobile();\n\n return (\n <SidebarMenu>\n <SidebarMenuItem>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <SidebarMenuButton\n className=\"group group-data-[collapsible=icon]:p-0! cursor-pointer bg-sidebar-accent text-sidebar-accent-foreground hover:bg-sidebar-accent-hover data-[state=open]:bg-sidebar-accent-hover\"\n data-test=\"sidebar-menu-button\"\n >\n <UserInfo user={user} />\n <ChevronsUpDown\n data-slot=\"nav-user-chevron\"\n className=\"size-4 ml-auto group-data-[collapsible=icon]:hidden\"\n />\n </SidebarMenuButton>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"min-w-56 rounded-xl w-(--radix-dropdown-menu-trigger-width)\"\n align=\"end\"\n side={\n isMobile\n ? 'bottom'\n : state === 'collapsed'\n ? 'left'\n : 'bottom'\n }\n >\n <UserMenuContent\n user={user}\n settingsHref={settingsHref}\n logoutHref={logoutHref}\n linkComponent={linkComponent}\n onSettingsClick={onSettingsClick}\n onLogout={onLogout}\n />\n </DropdownMenuContent>\n </DropdownMenu>\n </SidebarMenuItem>\n </SidebarMenu>\n );\n}\n","import { type ReactNode } from 'react';\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '@/components/ui/sidebar';\nimport { hrefToString, resolveLink } from '@/lib/href';\nimport type {\n LinkComponent,\n NavGroup,\n NavItem,\n SharedUser,\n UrlLike,\n} from '@/types';\nimport { NavFooter } from './nav-footer';\nimport { NavMain } from './nav-main';\nimport { NavUser } from './nav-user';\n\nfunction mostSpecificActiveHref(\n groups: NavGroup[],\n currentUrl: string,\n): string {\n let best = '';\n for (const group of groups) {\n for (const item of group.items) {\n const href = hrefToString(item.href);\n const matches =\n currentUrl === href || currentUrl.startsWith(`${href}/`);\n if (matches && href.length > best.length) {\n best = href;\n }\n }\n }\n return best;\n}\n\ninterface AppSidebarProps {\n logo: ReactNode;\n logoHref: UrlLike;\n groups: NavGroup[];\n footerItems?: NavItem[];\n user: SharedUser;\n settingsHref: UrlLike;\n logoutHref: UrlLike;\n currentUrl?: string;\n linkComponent?: LinkComponent;\n collapsibleGroups?: boolean;\n collapsedGroups?: string[];\n onCollapsedChange?: (collapsedGroups: string[]) => void;\n onSettingsClick?: () => void;\n onLogout?: () => void;\n}\n\nexport function AppSidebar({\n logo,\n logoHref,\n groups,\n footerItems = [],\n user,\n settingsHref,\n logoutHref,\n currentUrl = '',\n linkComponent,\n collapsibleGroups = false,\n collapsedGroups,\n onCollapsedChange,\n onSettingsClick,\n onLogout,\n}: AppSidebarProps) {\n const Link = resolveLink(linkComponent);\n const activeHref = mostSpecificActiveHref(groups, currentUrl);\n const resolvedGroups = groups.map((group) => ({\n ...group,\n items: group.items.map((item) => ({\n ...item,\n isActive: hrefToString(item.href) === activeHref,\n })),\n }));\n\n return (\n <Sidebar collapsible=\"icon\" variant=\"inset\">\n <SidebarHeader>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton asChild>\n <Link href={logoHref} prefetch>\n {logo}\n </Link>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarHeader>\n\n <SidebarContent>\n {resolvedGroups.map((group, index) => (\n <NavMain\n key={group.label ?? index}\n items={group.items}\n label={group.label ?? ''}\n currentUrl={currentUrl}\n linkComponent={linkComponent}\n collapsible={collapsibleGroups}\n collapsedGroups={collapsedGroups}\n onCollapsedChange={onCollapsedChange}\n />\n ))}\n </SidebarContent>\n\n <SidebarFooter>\n {footerItems.length > 0 && (\n <NavFooter items={footerItems} className=\"mt-auto\" />\n )}\n <NavUser\n user={user}\n settingsHref={settingsHref}\n logoutHref={logoutHref}\n linkComponent={linkComponent}\n onSettingsClick={onSettingsClick}\n onLogout={onLogout}\n />\n </SidebarFooter>\n </Sidebar>\n );\n}\n","import { Fragment } from 'react';\n\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/components/ui/breadcrumb';\nimport { resolveLink } from '@/lib/href';\nimport type {\n BreadcrumbItem as BreadcrumbItemType,\n LinkComponent,\n} from '@/types';\n\nexport function Breadcrumbs({\n breadcrumbs,\n linkComponent,\n}: {\n breadcrumbs: BreadcrumbItemType[];\n linkComponent?: LinkComponent;\n}) {\n const Link = resolveLink(linkComponent);\n\n if (breadcrumbs.length === 0) {\n return null;\n }\n\n return (\n <Breadcrumb>\n <BreadcrumbList>\n {breadcrumbs.map((item, index) => {\n const isLast = index === breadcrumbs.length - 1;\n return (\n <Fragment key={index}>\n <BreadcrumbItem>\n {isLast ? (\n <BreadcrumbPage>\n {item.title}\n </BreadcrumbPage>\n ) : (\n <BreadcrumbLink asChild>\n <Link href={item.href}>\n {item.title}\n </Link>\n </BreadcrumbLink>\n )}\n </BreadcrumbItem>\n {!isLast && <BreadcrumbSeparator />}\n </Fragment>\n );\n })}\n </BreadcrumbList>\n </Breadcrumb>\n );\n}\n","import { Search } from 'lucide-react';\nimport { useEffect, useState } from 'react';\n\nimport { SidebarTrigger } from '@/components/ui/sidebar';\nimport type {\n BreadcrumbItem as BreadcrumbItemType,\n LinkComponent,\n} from '@/types';\nimport { Breadcrumbs } from './breadcrumbs';\n\ninterface AppSidebarHeaderProps {\n breadcrumbs?: BreadcrumbItemType[];\n linkComponent?: LinkComponent;\n onSearchClick?: () => void;\n searchLabel?: string;\n}\n\nexport function AppSidebarHeader({\n breadcrumbs = [],\n linkComponent,\n onSearchClick,\n searchLabel = 'Search...',\n}: AppSidebarHeaderProps) {\n const [modifier, setModifier] = useState('Ctrl');\n\n useEffect(() => {\n const platform = navigator.userAgent;\n setModifier(/Mac|iPhone|iPad|iPod/.test(platform) ? '⌘' : 'Ctrl');\n }, []);\n\n return (\n <header className=\"h-16 gap-2 px-6 group-has-data-[collapsible=icon]/sidebar-wrapper:h-12 md:px-4 flex shrink-0 items-center border-b border-sidebar-border/50 transition-[width,height] ease-linear\">\n <div className=\"gap-2 flex items-center\">\n <SidebarTrigger className=\"-ml-1\" />\n <Breadcrumbs\n breadcrumbs={breadcrumbs}\n linkComponent={linkComponent}\n />\n </div>\n\n {onSearchClick && (\n <button\n type=\"button\"\n onClick={onSearchClick}\n className=\"h-9 w-56 gap-2 rounded-xl px-3 text-sm ml-auto flex items-center border border-border/60 bg-muted/30 text-muted-foreground transition-colors hover:bg-muted/50\"\n >\n <Search className=\"size-4\" />\n <span>{searchLabel}</span>\n <kbd className=\"gap-0.5 px-1.5 py-0.5 font-semibold rounded-xl ml-auto inline-flex items-center border border-border/60 bg-background font-sans text-[10px] text-muted-foreground\">\n <span>{modifier}</span>\n <span>K</span>\n </kbd>\n </button>\n )}\n </header>\n );\n}\n","export function Heading({\n title,\n description,\n}: {\n title: string;\n description?: string;\n}) {\n return (\n <div className=\"mb-8 space-y-0.5\">\n <h2 className=\"text-xl font-semibold tracking-tight\">{title}</h2>\n {description && (\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n )}\n </div>\n );\n}\n","import { type PropsWithChildren } from 'react';\n\nimport { Button } from '@/components/ui/button';\nimport { Separator } from '@/components/ui/separator';\nimport { hrefToString, resolveLink } from '@/lib/href';\nimport { cn } from '@/lib/utils';\nimport type { LinkComponent, NavItem } from '@/types';\nimport { Heading } from './heading';\n\nexport interface SettingsLayoutProps {\n items: NavItem[];\n linkComponent?: LinkComponent;\n currentPath?: string;\n title?: string;\n description?: string;\n wide?: boolean;\n}\n\nexport function SettingsLayout({\n items,\n linkComponent,\n currentPath,\n title = 'Settings',\n description = 'Manage your profile and account settings',\n wide = false,\n children,\n}: PropsWithChildren<SettingsLayoutProps>) {\n const Link = resolveLink(linkComponent);\n const activePath =\n currentPath ??\n (typeof window === 'undefined' ? '' : window.location.pathname);\n\n return (\n <div className=\"px-4 py-6\">\n <Heading title={title} description={description} />\n\n <div className=\"lg:flex-row lg:space-x-12 flex flex-col\">\n <aside className=\"max-w-xl lg:w-48 w-full\">\n <nav className=\"space-y-1 space-x-0 flex flex-col\">\n {items.map((item, index) => {\n const href = hrefToString(item.href);\n return (\n <Button\n key={`${href}-${index}`}\n size=\"sm\"\n variant=\"ghost\"\n asChild\n className={cn('w-full justify-start', {\n 'bg-muted': activePath === href,\n })}\n >\n <Link href={item.href}>\n {item.icon && (\n <item.icon className=\"h-4 w-4\" />\n )}\n {item.title}\n </Link>\n </Button>\n );\n })}\n </nav>\n </aside>\n\n <Separator className=\"my-6 lg:hidden\" />\n\n <div\n className={cn(\n wide ? 'min-w-0 flex-1' : 'md:max-w-2xl flex-1',\n )}\n >\n <section\n className={cn(\n 'space-y-12',\n wide ? 'max-w-5xl' : 'max-w-xl',\n )}\n >\n {children}\n </section>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":["useCallback","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs","Fragment","useState","jsx","jsxs","useState","jsx","jsxs","jsx","jsxs"]}
|