xertica-ui 2.5.2 → 2.5.3

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.
@@ -0,0 +1,1147 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import React__default, { createContext, useState, useEffect, useRef, useMemo, useContext } from 'react';
3
+ import { Menu, Settings, User, LogOut, ArrowLeft, Search, Filter, MoreVertical, ChevronRight } from 'lucide-react';
4
+ import { B as Button, c as cn } from './button-DZHzN1Gd.js';
5
+ import { L as LanguageSelector, T as ThemeToggle, X as XerticaLogo, a as XerticaXLogo } from './XerticaXLogo-BX3ueACh.js';
6
+ import { B as Breadcrumb, d as BreadcrumbList, b as BreadcrumbItem, c as BreadcrumbLink, e as BreadcrumbPage, f as BreadcrumbSeparator } from './breadcrumb-ifNsA7Zl.js';
7
+ import { D as DropdownMenu, n as DropdownMenuTrigger, b as DropdownMenuContent, e as DropdownMenuLabel, i as DropdownMenuSeparator, d as DropdownMenuItem, k as DropdownMenuSub, m as DropdownMenuSubTrigger, f as DropdownMenuPortal, l as DropdownMenuSubContent } from './dropdown-menu-Dn_eV2Xb.js';
8
+ import { A as Avatar, b as AvatarImage, a as AvatarFallback } from './avatar-3kO2Anrp.js';
9
+ import { a as useOptionalLayout } from './LayoutContext-DNl1xSoX.js';
10
+ import { AnimatePresence, motion } from 'framer-motion';
11
+ import { useTranslation } from 'react-i18next';
12
+ import { I as Input, P as Popover, c as PopoverTrigger, b as PopoverContent } from './input-B0_vbA3g.js';
13
+ import { b as TooltipProvider, T as Tooltip, c as TooltipTrigger } from './tooltip-RtbSmPYJ.js';
14
+ import { C as CustomTooltipContent } from './CustomTooltipContent-CNbVB2NS.js';
15
+
16
+ function Header({
17
+ title,
18
+ breadcrumbs,
19
+ showLanguageSelector = true,
20
+ showThemeToggle = true,
21
+ className,
22
+ user,
23
+ actions,
24
+ showSettings,
25
+ onSettingsClick,
26
+ showLogout,
27
+ onLogoutClick,
28
+ renderLink,
29
+ breadcrumbSlot
30
+ }) {
31
+ const layout = useOptionalLayout();
32
+ const toggleSidebar = layout?.toggleSidebar ?? (() => {
33
+ });
34
+ return /* @__PURE__ */ jsx(
35
+ "header",
36
+ {
37
+ className: `bg-card text-foreground shadow-sm border-b border-border px-[24px] h-[64px] flex-shrink-0 flex items-center ${className || ""}`,
38
+ children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between w-full p-[0px]", children: [
39
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground w-full overflow-x-auto", children: [
40
+ /* @__PURE__ */ jsx(
41
+ Button,
42
+ {
43
+ variant: "ghost",
44
+ size: "sm",
45
+ onClick: toggleSidebar,
46
+ className: "md:hidden mr-2 p-2 shrink-0",
47
+ "aria-label": "Abrir menu lateral",
48
+ children: /* @__PURE__ */ jsx(Menu, { className: "w-5 h-5" })
49
+ }
50
+ ),
51
+ breadcrumbs && breadcrumbs.length > 0 ? /* @__PURE__ */ jsx(Breadcrumb, { children: /* @__PURE__ */ jsx(BreadcrumbList, { className: "flex-nowrap whitespace-nowrap", children: breadcrumbs.map((item, index) => /* @__PURE__ */ jsxs(React__default.Fragment, { children: [
52
+ /* @__PURE__ */ jsx(BreadcrumbItem, { children: item.href ? renderLink ? /* @__PURE__ */ jsx(BreadcrumbLink, { asChild: true, className: "flex items-center gap-1.5", children: renderLink(item.href, {
53
+ className: "flex items-center gap-1.5",
54
+ children: /* @__PURE__ */ jsxs(Fragment, { children: [
55
+ item.icon,
56
+ item.label
57
+ ] })
58
+ }) }) : /* @__PURE__ */ jsxs(BreadcrumbLink, { href: item.href, className: "flex items-center gap-1.5", children: [
59
+ item.icon,
60
+ item.label
61
+ ] }) : /* @__PURE__ */ jsxs(BreadcrumbPage, { className: "flex items-center gap-1.5", children: [
62
+ item.icon,
63
+ item.label
64
+ ] }) }),
65
+ index < breadcrumbs.length - 1 && /* @__PURE__ */ jsx(BreadcrumbSeparator, {})
66
+ ] }, index)) }) }) : title ? /* @__PURE__ */ jsx("span", { className: "text-foreground font-medium shrink-0", children: title }) : /* @__PURE__ */ jsx(Breadcrumb, { children: /* @__PURE__ */ jsx(BreadcrumbList, { className: "flex-nowrap whitespace-nowrap", children: /* @__PURE__ */ jsx(BreadcrumbItem, { children: /* @__PURE__ */ jsx(BreadcrumbPage, { className: "text-foreground font-medium shrink-0", children: "Xertica.ai" }) }) }) }),
67
+ breadcrumbSlot && /* @__PURE__ */ jsx("div", { className: "flex items-center shrink-0", children: breadcrumbSlot })
68
+ ] }),
69
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 shrink-0 ml-4", children: [
70
+ showLanguageSelector && /* @__PURE__ */ jsx(LanguageSelector, { variant: "minimal", showIcon: false, className: "hidden sm:flex" }),
71
+ showThemeToggle && /* @__PURE__ */ jsx(ThemeToggle, { className: "hover:bg-accent" }),
72
+ actions?.map((action) => /* @__PURE__ */ jsxs(
73
+ Button,
74
+ {
75
+ variant: "ghost",
76
+ size: action.label ? "sm" : "icon",
77
+ onClick: action.onClick,
78
+ className: `hover:bg-accent ${action.className || ""}`,
79
+ "aria-label": action.label || action.id,
80
+ children: [
81
+ action.icon,
82
+ action.label && /* @__PURE__ */ jsx("span", { className: "ml-2 hidden md:inline", children: action.label })
83
+ ]
84
+ },
85
+ action.id
86
+ )),
87
+ showSettings && /* @__PURE__ */ jsx(
88
+ Button,
89
+ {
90
+ variant: "ghost",
91
+ size: "icon",
92
+ onClick: onSettingsClick,
93
+ className: "hover:bg-accent",
94
+ "aria-label": "Configurações",
95
+ children: /* @__PURE__ */ jsx(Settings, { className: "w-5 h-5" })
96
+ }
97
+ ),
98
+ user && /* @__PURE__ */ jsxs(DropdownMenu, { children: [
99
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
100
+ Button,
101
+ {
102
+ variant: "ghost",
103
+ className: "relative h-8 w-8 rounded-full p-0 overflow-hidden border border-border/50 hover:border-primary/30 transition-colors",
104
+ "aria-label": "Menu do usuário",
105
+ children: /* @__PURE__ */ jsxs(Avatar, { className: "h-8 w-8", children: [
106
+ /* @__PURE__ */ jsx(AvatarImage, { src: user.avatar, alt: user.name || "User" }),
107
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-primary/10 text-primary text-xs font-medium", children: user.name ? user.name.charAt(0).toUpperCase() : /* @__PURE__ */ jsx(User, { className: "w-4 h-4" }) })
108
+ ] })
109
+ }
110
+ ) }),
111
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { className: "w-56", align: "end", forceMount: true, children: [
112
+ /* @__PURE__ */ jsx(DropdownMenuLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col space-y-1", children: [
113
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium leading-none", children: user.name || "User" }),
114
+ /* @__PURE__ */ jsx("p", { className: "text-xs leading-none text-muted-foreground", children: user.email || "user@example.com" })
115
+ ] }) }),
116
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
117
+ user.menuItems?.map((item) => /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: item.onClick, className: item.className, children: [
118
+ item.icon && /* @__PURE__ */ jsx("span", { className: "mr-2", children: item.icon }),
119
+ item.label
120
+ ] }, item.id)),
121
+ !user.menuItems && /* @__PURE__ */ jsxs(Fragment, { children: [
122
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: onSettingsClick, children: [
123
+ /* @__PURE__ */ jsx(Settings, { className: "mr-2 h-4 w-4" }),
124
+ /* @__PURE__ */ jsx("span", { children: "Settings" })
125
+ ] }),
126
+ /* @__PURE__ */ jsxs(
127
+ DropdownMenuItem,
128
+ {
129
+ onClick: onLogoutClick,
130
+ className: "text-destructive focus:text-destructive",
131
+ children: [
132
+ /* @__PURE__ */ jsx(LogOut, { className: "mr-2 h-4 w-4" }),
133
+ /* @__PURE__ */ jsx("span", { children: "Logout" })
134
+ ]
135
+ }
136
+ )
137
+ ] })
138
+ ] })
139
+ ] }),
140
+ showLogout && /* @__PURE__ */ jsx(
141
+ Button,
142
+ {
143
+ variant: "ghost",
144
+ size: "icon",
145
+ onClick: onLogoutClick,
146
+ className: "hover:bg-accent text-muted-foreground hover:text-foreground",
147
+ "aria-label": "Sair",
148
+ children: /* @__PURE__ */ jsx(LogOut, { className: "w-5 h-5" })
149
+ }
150
+ )
151
+ ] })
152
+ ] })
153
+ }
154
+ );
155
+ }
156
+
157
+ const SidebarContext = createContext(null);
158
+ function useSidebarContext() {
159
+ const ctx = useContext(SidebarContext);
160
+ if (!ctx) {
161
+ throw new Error("Sidebar compound components must be used within <Sidebar.Root>");
162
+ }
163
+ return ctx;
164
+ }
165
+ function SidebarRoot({
166
+ expanded: expandedProp,
167
+ onToggle: onToggleProp,
168
+ navigate: navigateProp,
169
+ location: locationProp,
170
+ width: widthProp,
171
+ children,
172
+ className
173
+ }) {
174
+ const layoutContext = useOptionalLayout();
175
+ const [localExpanded, setLocalExpanded] = useState(false);
176
+ const [isMobileViewport, setIsMobileViewport] = useState(false);
177
+ const expanded = expandedProp !== void 0 ? expandedProp : layoutContext?.sidebarExpanded ?? localExpanded;
178
+ const onToggle = onToggleProp || layoutContext?.toggleSidebar || (() => setLocalExpanded((prev) => !prev));
179
+ const width = widthProp !== void 0 ? widthProp : layoutContext?.sidebarWidth ?? 280;
180
+ const navigate = navigateProp || ((path) => {
181
+ if (typeof window !== "undefined") window.location.href = path;
182
+ });
183
+ const location = locationProp || (typeof window !== "undefined" ? window.location : { pathname: "/" });
184
+ useEffect(() => {
185
+ const checkViewport = () => setIsMobileViewport(window.innerWidth < 768);
186
+ checkViewport();
187
+ window.addEventListener("resize", checkViewport);
188
+ return () => window.removeEventListener("resize", checkViewport);
189
+ }, []);
190
+ return /* @__PURE__ */ jsx(
191
+ SidebarContext.Provider,
192
+ {
193
+ value: { expanded, isMobileViewport, onToggle, navigate, location, width },
194
+ children: /* @__PURE__ */ jsxs(TooltipProvider, { delayDuration: 300, children: [
195
+ /* @__PURE__ */ jsx("style", { children: `
196
+ @media (max-width: 767px) {
197
+ [style*="padding-left"].flex-1,
198
+ [style*="paddingLeft"].flex-1 {
199
+ padding-left: 0 !important;
200
+ }
201
+ }
202
+ ` }),
203
+ /* @__PURE__ */ jsx(
204
+ "div",
205
+ {
206
+ className: cn(
207
+ "bg-sidebar text-sidebar-foreground transition-all duration-300 ease-in-out flex flex-col z-50",
208
+ expanded ? "fixed inset-0 md:fixed md:inset-y-0 md:left-0" : "fixed inset-y-0 left-0 w-20 -translate-x-full md:translate-x-0",
209
+ className
210
+ ),
211
+ style: expanded && !isMobileViewport ? { width: `${width}px` } : void 0,
212
+ children
213
+ }
214
+ )
215
+ ] })
216
+ }
217
+ );
218
+ }
219
+ function SidebarHeader({
220
+ logo,
221
+ logoCollapsed
222
+ }) {
223
+ const { expanded, onToggle } = useSidebarContext();
224
+ const { t } = useTranslation();
225
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
226
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 p-[14px] pt-[13px] pr-[14px] pb-[12px] pl-[14px]", children: /* @__PURE__ */ jsx(
227
+ "button",
228
+ {
229
+ onClick: onToggle,
230
+ className: "w-full h-10 flex items-center gap-3 px-3 justify-center rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground",
231
+ "aria-label": expanded ? t("sidebar.collapse") : t("sidebar.expand"),
232
+ "aria-expanded": expanded,
233
+ "aria-controls": "sidebar-nav",
234
+ children: expanded ? /* @__PURE__ */ jsx(ArrowLeft, { className: "w-5 h-5" }) : /* @__PURE__ */ jsx(Menu, { className: "w-5 h-5" })
235
+ }
236
+ ) }),
237
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 px-4 py-4", children: /* @__PURE__ */ jsx("div", { className: "flex items-center h-10 justify-center", children: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center flex-shrink-0", children: expanded ? logo || /* @__PURE__ */ jsx(XerticaLogo, { className: "h-5 w-auto", variant: "white" }) : logoCollapsed || /* @__PURE__ */ jsx(XerticaXLogo, { className: "h-5 w-auto", variant: "white" }) }) }) })
238
+ ] });
239
+ }
240
+ function OverflowGroupsAccordion({
241
+ expanded,
242
+ overflowGroups,
243
+ location,
244
+ handleNavigate,
245
+ moreOptionsLabel,
246
+ onOpenChange
247
+ }) {
248
+ const [isOpen, setIsOpen] = useState(false);
249
+ const toggle = () => {
250
+ const next = !isOpen;
251
+ setIsOpen(next);
252
+ onOpenChange?.(next);
253
+ };
254
+ return /* @__PURE__ */ jsxs("div", { children: [
255
+ /* @__PURE__ */ jsxs(
256
+ "button",
257
+ {
258
+ onClick: toggle,
259
+ className: cn(
260
+ "w-full h-10 flex items-center rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground",
261
+ expanded ? "gap-3 px-3 justify-start" : "justify-center px-0"
262
+ ),
263
+ "aria-expanded": isOpen,
264
+ "aria-label": moreOptionsLabel,
265
+ children: [
266
+ /* @__PURE__ */ jsx(MoreVertical, { className: "w-5 h-5 flex-shrink-0" }),
267
+ expanded && /* @__PURE__ */ jsxs(Fragment, { children: [
268
+ /* @__PURE__ */ jsx("span", { className: "truncate flex-1 text-sidebar-foreground text-left", children: moreOptionsLabel }),
269
+ /* @__PURE__ */ jsx(
270
+ ChevronRight,
271
+ {
272
+ className: cn("w-4 h-4 flex-shrink-0 transition-transform duration-200", isOpen && "rotate-90")
273
+ }
274
+ )
275
+ ] })
276
+ ]
277
+ }
278
+ ),
279
+ /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: isOpen && /* @__PURE__ */ jsx(
280
+ motion.div,
281
+ {
282
+ initial: { height: 0, opacity: 0 },
283
+ animate: { height: "auto", opacity: 1 },
284
+ exit: { height: 0, opacity: 0 },
285
+ transition: { duration: 0.2 },
286
+ className: "overflow-hidden",
287
+ children: /* @__PURE__ */ jsx("div", { className: "mt-1 space-y-3", children: overflowGroups.map((group) => {
288
+ const GroupIcon = group.icon;
289
+ return /* @__PURE__ */ jsxs("div", { children: [
290
+ (group.label || GroupIcon) && expanded && /* @__PURE__ */ jsxs("div", { className: "px-3 mb-1 flex items-center gap-2", children: [
291
+ GroupIcon && (React__default.isValidElement(GroupIcon) ? GroupIcon : /* @__PURE__ */ jsx(GroupIcon, { className: "h-3 w-3 text-sidebar-foreground/60" })),
292
+ group.label && /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-wider text-sidebar-foreground/60", children: group.label })
293
+ ] }),
294
+ /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: group.items.map((item) => {
295
+ const Icon = item.icon;
296
+ const isActive = location.pathname === item.path || location.pathname.startsWith(item.path + "/");
297
+ return /* @__PURE__ */ jsxs(
298
+ "button",
299
+ {
300
+ onClick: () => handleNavigate(item.path),
301
+ className: cn(
302
+ "w-full h-9 flex items-center gap-2.5 rounded-[var(--radius-button)] transition-all duration-200 text-left text-sm",
303
+ expanded ? "px-3" : "justify-center px-0",
304
+ isActive ? "bg-sidebar-foreground/15 text-sidebar-foreground" : "text-sidebar-foreground/70 hover:bg-sidebar-foreground/10 hover:text-sidebar-foreground"
305
+ ),
306
+ children: [
307
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "w-4 h-4 flex-shrink-0" }),
308
+ expanded && /* @__PURE__ */ jsx("span", { className: "truncate", children: item.label })
309
+ ]
310
+ },
311
+ item.path
312
+ );
313
+ }) })
314
+ ] }, group.id);
315
+ }) })
316
+ }
317
+ ) })
318
+ ] });
319
+ }
320
+ function SidebarNav({
321
+ navigationGroups = [],
322
+ routes = [],
323
+ variant = "default"
324
+ }) {
325
+ const { expanded, isMobileViewport, navigate, location, onToggle } = useSidebarContext();
326
+ const { t } = useTranslation();
327
+ const navRef = useRef(null);
328
+ const [localActiveItem, setLocalActiveItem] = useState(null);
329
+ const [hasOverflow, setHasOverflow] = useState(false);
330
+ const [visibleItems, setVisibleItems] = useState([]);
331
+ const [overflowItems, setOverflowItems] = useState([]);
332
+ const [openSubmenus, setOpenSubmenus] = useState(/* @__PURE__ */ new Set());
333
+ const [hasGroupOverflow, setHasGroupOverflow] = useState(false);
334
+ const [visibleGroups, setVisibleGroups] = useState([]);
335
+ const [overflowGroups, setOverflowGroups] = useState([]);
336
+ const [isOverflowAccordionOpen, setIsOverflowAccordionOpen] = useState(false);
337
+ const toggleSubmenu = (path) => {
338
+ setOpenSubmenus((prev) => {
339
+ const next = new Set(prev);
340
+ if (next.has(path)) {
341
+ next.delete(path);
342
+ } else {
343
+ next.add(path);
344
+ }
345
+ return next;
346
+ });
347
+ };
348
+ const labelTranslations = useMemo(
349
+ () => ({
350
+ home: "Início",
351
+ dashboard: "Painel",
352
+ components: "Componentes"
353
+ }),
354
+ []
355
+ );
356
+ const navigationItems = useMemo(
357
+ () => (routes || []).map((route) => ({
358
+ ...route,
359
+ label: labelTranslations[route.label.toLowerCase()] || route.label,
360
+ active: location.pathname === route.path || location.pathname.startsWith(route.path + "/"),
361
+ children: route.children
362
+ })),
363
+ [routes, location.pathname, labelTranslations]
364
+ );
365
+ useEffect(() => {
366
+ if (typeof window === "undefined") return;
367
+ const checkOverflow = () => {
368
+ if (!navRef.current) return;
369
+ if (variant === "assistant") return;
370
+ const navHeight = navRef.current.clientHeight;
371
+ const itemHeight = 44;
372
+ const maxVisibleItems = Math.floor(navHeight / itemHeight);
373
+ if (navigationItems.length > maxVisibleItems) {
374
+ setHasOverflow(true);
375
+ setVisibleItems(navigationItems.slice(0, maxVisibleItems - 1));
376
+ setOverflowItems(navigationItems.slice(maxVisibleItems - 1));
377
+ } else {
378
+ setHasOverflow(false);
379
+ setVisibleItems(navigationItems);
380
+ setOverflowItems([]);
381
+ }
382
+ };
383
+ checkOverflow();
384
+ window.addEventListener("resize", checkOverflow);
385
+ return () => window.removeEventListener("resize", checkOverflow);
386
+ }, [navigationItems.length, variant]);
387
+ useEffect(() => {
388
+ if (typeof window === "undefined") return;
389
+ if (variant === "assistant") return;
390
+ if (!navigationGroups || navigationGroups.length === 0) return;
391
+ const checkGroupOverflow = () => {
392
+ if (!navRef.current) return;
393
+ const containerHeight = navRef.current.clientHeight;
394
+ const itemHeight = 40;
395
+ const groupHeaderHeight = 32;
396
+ const groupSpacing = 12;
397
+ const moreButtonHeight = 44;
398
+ const padding = 32;
399
+ let currentHeight = padding;
400
+ let visibleCount = 0;
401
+ for (let i = 0; i < navigationGroups.length; i++) {
402
+ const group = navigationGroups[i];
403
+ let groupHeight = 0;
404
+ if (group.label) groupHeight += groupHeaderHeight;
405
+ groupHeight += group.items.length * itemHeight;
406
+ if (i > 0) groupHeight += groupSpacing;
407
+ const wouldExceed = currentHeight + groupHeight + (visibleCount < navigationGroups.length - 1 ? moreButtonHeight : 0) > containerHeight;
408
+ if (wouldExceed && visibleCount > 0) break;
409
+ currentHeight += groupHeight;
410
+ visibleCount++;
411
+ }
412
+ if (visibleCount < navigationGroups.length) {
413
+ setHasGroupOverflow(true);
414
+ setVisibleGroups(navigationGroups.slice(0, visibleCount));
415
+ setOverflowGroups(navigationGroups.slice(visibleCount));
416
+ } else {
417
+ setHasGroupOverflow(false);
418
+ setVisibleGroups(navigationGroups);
419
+ setOverflowGroups([]);
420
+ }
421
+ };
422
+ checkGroupOverflow();
423
+ window.addEventListener("resize", checkGroupOverflow);
424
+ return () => window.removeEventListener("resize", checkGroupOverflow);
425
+ }, [navigationGroups, expanded, variant]);
426
+ const handleNavigate = (path) => {
427
+ setLocalActiveItem(path);
428
+ navigate(path);
429
+ if (typeof window !== "undefined" && window.innerWidth < 768) {
430
+ onToggle();
431
+ }
432
+ };
433
+ const toNavItem = (route) => ({
434
+ path: route.path,
435
+ label: labelTranslations[route.label.toLowerCase()] || route.label,
436
+ icon: route.icon,
437
+ active: location.pathname === route.path || location.pathname.startsWith(route.path + "/"),
438
+ children: route.children,
439
+ actions: route.actions
440
+ });
441
+ const renderActionItems = (actions) => {
442
+ return actions.map((action, idx) => {
443
+ const Icon = action.icon;
444
+ if (action.children && action.children.length > 0) {
445
+ return /* @__PURE__ */ jsxs(DropdownMenuSub, { children: [
446
+ /* @__PURE__ */ jsxs(DropdownMenuSubTrigger, { children: [
447
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "mr-2 h-4 w-4" }),
448
+ /* @__PURE__ */ jsx("span", { children: action.label })
449
+ ] }),
450
+ /* @__PURE__ */ jsx(DropdownMenuPortal, { children: /* @__PURE__ */ jsx(DropdownMenuSubContent, { className: "w-48 bg-popover border-border", children: renderActionItems(action.children) }) })
451
+ ] }, idx);
452
+ }
453
+ return /* @__PURE__ */ jsxs(
454
+ DropdownMenuItem,
455
+ {
456
+ className: cn(
457
+ "flex items-center gap-2",
458
+ action.variant === "destructive" ? "text-destructive focus:text-destructive" : ""
459
+ ),
460
+ onClick: (e) => {
461
+ e.stopPropagation();
462
+ action.onClick?.(null);
463
+ },
464
+ children: [
465
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 flex-shrink-0" }),
466
+ /* @__PURE__ */ jsx("span", { children: action.label })
467
+ ]
468
+ },
469
+ idx
470
+ );
471
+ });
472
+ };
473
+ const renderAssistantActionMenu = (actions, isHeader = false) => {
474
+ if (!actions || actions.length === 0) return null;
475
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
476
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
477
+ Button,
478
+ {
479
+ variant: "ghost",
480
+ size: "icon",
481
+ className: cn(
482
+ "h-8 w-8 text-sidebar-foreground/80 hover:bg-sidebar-foreground/20 hover:text-sidebar-foreground rounded-full transition-all",
483
+ !isHeader && "opacity-0 group-hover/item:opacity-100"
484
+ ),
485
+ "aria-label": t("sidebar.moreOptions"),
486
+ children: /* @__PURE__ */ jsx(MoreVertical, { className: "h-4 w-4" })
487
+ }
488
+ ) }),
489
+ /* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", className: "w-48 bg-popover border-border p-1", children: renderActionItems(actions) })
490
+ ] });
491
+ };
492
+ const renderDefaultItem = (item) => {
493
+ const Icon = item.icon;
494
+ const hasChildren = item.children && item.children.length > 0;
495
+ const activeClass = item.active ? "bg-sidebar-foreground/15 text-sidebar-foreground shadow-sm" : "text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground";
496
+ if (!expanded) {
497
+ return /* @__PURE__ */ jsxs(Tooltip, { children: [
498
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
499
+ "button",
500
+ {
501
+ onClick: () => handleNavigate(item.path),
502
+ className: cn(
503
+ "w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200",
504
+ activeClass
505
+ ),
506
+ "aria-label": item.label,
507
+ children: Icon && /* @__PURE__ */ jsx(Icon, { className: "w-5 h-5 flex-shrink-0" })
508
+ }
509
+ ) }),
510
+ /* @__PURE__ */ jsx(CustomTooltipContent, { side: "right", sideOffset: 0, children: /* @__PURE__ */ jsx("p", { children: item.label }) })
511
+ ] }, item.path);
512
+ }
513
+ if (isMobileViewport && hasChildren) {
514
+ const isOpen = openSubmenus.has(item.path);
515
+ return /* @__PURE__ */ jsxs("div", { children: [
516
+ /* @__PURE__ */ jsxs(
517
+ "div",
518
+ {
519
+ className: cn(
520
+ "group/item flex items-center w-full h-10 rounded-[var(--radius-button)] transition-all duration-200",
521
+ activeClass
522
+ ),
523
+ children: [
524
+ /* @__PURE__ */ jsxs(
525
+ "button",
526
+ {
527
+ onClick: () => handleNavigate(item.path),
528
+ className: "flex items-center gap-3 px-3 flex-1 h-full min-w-0 text-left",
529
+ children: [
530
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "w-5 h-5 flex-shrink-0" }),
531
+ /* @__PURE__ */ jsx("span", { className: "truncate flex-1", children: item.label })
532
+ ]
533
+ }
534
+ ),
535
+ /* @__PURE__ */ jsx(
536
+ "button",
537
+ {
538
+ onClick: (e) => {
539
+ e.stopPropagation();
540
+ toggleSubmenu(item.path);
541
+ },
542
+ className: "h-full px-2 pr-2.5 flex items-center justify-center text-sidebar-foreground/40 hover:text-sidebar-foreground transition-colors",
543
+ "aria-label": t("sidebar.submenu", { label: item.label }),
544
+ "aria-expanded": isOpen,
545
+ children: /* @__PURE__ */ jsx(
546
+ ChevronRight,
547
+ {
548
+ className: cn("w-4 h-4 transition-transform duration-200", isOpen && "rotate-90")
549
+ }
550
+ )
551
+ }
552
+ )
553
+ ]
554
+ }
555
+ ),
556
+ /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: isOpen && /* @__PURE__ */ jsx(
557
+ motion.div,
558
+ {
559
+ initial: { height: 0, opacity: 0 },
560
+ animate: { height: "auto", opacity: 1 },
561
+ exit: { height: 0, opacity: 0 },
562
+ transition: { duration: 0.2 },
563
+ className: "overflow-hidden",
564
+ children: /* @__PURE__ */ jsx("div", { className: "ml-4 mt-0.5 mb-0.5 space-y-0.5", children: item.children.map((child) => {
565
+ const ChildIcon = child.icon;
566
+ const isChildActive = location.pathname === child.path || location.pathname.startsWith(child.path + "/");
567
+ return /* @__PURE__ */ jsxs(
568
+ "button",
569
+ {
570
+ onClick: () => handleNavigate(child.path),
571
+ className: cn(
572
+ "w-full h-9 flex items-center gap-2.5 px-3 rounded-[var(--radius-button)] transition-all duration-200 text-left",
573
+ isChildActive ? "bg-sidebar-foreground/15 text-sidebar-foreground" : "text-sidebar-foreground/70 hover:bg-sidebar-foreground/10 hover:text-sidebar-foreground"
574
+ ),
575
+ children: [
576
+ ChildIcon && /* @__PURE__ */ jsx(ChildIcon, { className: "h-4 w-4 flex-shrink-0" }),
577
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sm", children: child.label })
578
+ ]
579
+ },
580
+ child.path
581
+ );
582
+ }) })
583
+ }
584
+ ) })
585
+ ] }, item.path);
586
+ }
587
+ return /* @__PURE__ */ jsxs(
588
+ "div",
589
+ {
590
+ className: cn(
591
+ "group/item flex items-center w-full h-10 rounded-[var(--radius-button)] transition-all duration-200",
592
+ activeClass
593
+ ),
594
+ children: [
595
+ /* @__PURE__ */ jsxs(
596
+ "button",
597
+ {
598
+ onClick: () => handleNavigate(item.path),
599
+ className: "flex items-center gap-3 px-3 flex-1 h-full min-w-0 text-left",
600
+ children: [
601
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "w-5 h-5 flex-shrink-0" }),
602
+ /* @__PURE__ */ jsx("span", { className: "truncate flex-1", children: item.label })
603
+ ]
604
+ }
605
+ ),
606
+ hasChildren && /* @__PURE__ */ jsxs(DropdownMenu, { children: [
607
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
608
+ "button",
609
+ {
610
+ onClick: (e) => e.stopPropagation(),
611
+ className: "h-full px-2 pr-2.5 flex items-center justify-center text-sidebar-foreground/40 hover:text-sidebar-foreground transition-colors",
612
+ "aria-label": t("sidebar.submenu", { label: item.label }),
613
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "w-4 h-4" })
614
+ }
615
+ ) }),
616
+ /* @__PURE__ */ jsx(
617
+ DropdownMenuContent,
618
+ {
619
+ side: "right",
620
+ align: "start",
621
+ className: "w-48 bg-popover border-border p-1",
622
+ children: item.children.map((child) => {
623
+ const ChildIcon = child.icon;
624
+ const isChildActive = location.pathname === child.path || location.pathname.startsWith(child.path + "/");
625
+ return /* @__PURE__ */ jsxs(
626
+ DropdownMenuItem,
627
+ {
628
+ onClick: () => handleNavigate(child.path),
629
+ className: cn(
630
+ "flex items-center gap-2 cursor-pointer",
631
+ isChildActive && "bg-accent text-accent-foreground"
632
+ ),
633
+ children: [
634
+ ChildIcon && /* @__PURE__ */ jsx(ChildIcon, { className: "h-4 w-4 flex-shrink-0" }),
635
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: child.label })
636
+ ]
637
+ },
638
+ child.path
639
+ );
640
+ })
641
+ }
642
+ )
643
+ ] })
644
+ ]
645
+ },
646
+ item.path
647
+ );
648
+ };
649
+ const renderDefaultGroup = (group) => {
650
+ const GroupIcon = group.icon;
651
+ if (!expanded) {
652
+ return /* @__PURE__ */ jsx("div", { className: "space-y-1", children: group.items.map((item) => renderDefaultItem(toNavItem(item))) }, group.id);
653
+ }
654
+ return /* @__PURE__ */ jsxs("div", { children: [
655
+ (group.label || GroupIcon) && /* @__PURE__ */ jsxs("div", { className: "px-3 mb-1 flex items-center gap-2", children: [
656
+ GroupIcon && (React__default.isValidElement(GroupIcon) ? GroupIcon : /* @__PURE__ */ jsx(GroupIcon, { className: "h-3 w-3 text-sidebar-foreground/80" })),
657
+ group.label && /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-wider text-sidebar-foreground/80", children: group.label })
658
+ ] }),
659
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: group.items.map((item) => renderDefaultItem(toNavItem(item))) })
660
+ ] }, group.id);
661
+ };
662
+ const renderAssistantGroup = (group) => {
663
+ const isAnyItemActive = group.items.some(
664
+ (item) => location.pathname === item.path || location.pathname.startsWith(item.path + "/")
665
+ );
666
+ const GroupIcon = group.icon;
667
+ if (!expanded) {
668
+ if (!GroupIcon) return null;
669
+ return /* @__PURE__ */ jsx("div", { className: "py-2 flex justify-center", children: /* @__PURE__ */ jsxs(Tooltip, { children: [
670
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
671
+ "button",
672
+ {
673
+ onClick: () => onToggle(),
674
+ "aria-label": group.label,
675
+ className: cn(
676
+ "h-10 w-10 flex items-center justify-center rounded-[var(--radius-button)] transition-all duration-200",
677
+ isAnyItemActive ? "bg-sidebar-foreground/15 text-sidebar-foreground shadow-sm" : "text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
678
+ ),
679
+ children: React__default.isValidElement(GroupIcon) ? GroupIcon : /* @__PURE__ */ jsx(GroupIcon, { className: "h-5 w-5" })
680
+ }
681
+ ) }),
682
+ /* @__PURE__ */ jsx(CustomTooltipContent, { side: "right", children: /* @__PURE__ */ jsx("p", { children: group.label }) })
683
+ ] }) }, group.id);
684
+ }
685
+ return /* @__PURE__ */ jsxs("div", { className: "py-2 group", children: [
686
+ (group.label || group.icon) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-3 mb-1", children: [
687
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sidebar-foreground/80 text-xs font-semibold uppercase tracking-wider", children: [
688
+ GroupIcon && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: React__default.isValidElement(GroupIcon) ? GroupIcon : /* @__PURE__ */ jsx(GroupIcon, { className: "h-4 w-4" }) }),
689
+ group.label && /* @__PURE__ */ jsx("span", { children: group.label })
690
+ ] }),
691
+ renderAssistantActionMenu(group.actions, true)
692
+ ] }),
693
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: group.items.map((item) => {
694
+ const isRouteActive = location.pathname === item.path || location.pathname.startsWith(item.path + "/");
695
+ const isActive = isRouteActive || localActiveItem === item.path;
696
+ const Icon = item.icon;
697
+ return /* @__PURE__ */ jsxs(
698
+ "div",
699
+ {
700
+ className: `group/item flex items-start justify-between px-3 min-h-[36px] py-2.5 rounded-[var(--radius-button)] cursor-pointer transition-all duration-200 ${isActive ? "bg-sidebar-foreground/15 text-sidebar-foreground" : "text-sidebar-foreground/80 hover:bg-sidebar-foreground/10 hover:text-sidebar-foreground"}`,
701
+ onClick: () => handleNavigate(item.path),
702
+ children: [
703
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
704
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 overflow-hidden h-5", children: [
705
+ Icon && /* @__PURE__ */ jsx("div", { className: "w-4 h-4 flex-shrink-0 flex items-center justify-center", children: React__default.isValidElement(Icon) ? Icon : /* @__PURE__ */ jsx(Icon, { className: "w-4 h-4" }) }),
706
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sm font-medium leading-none", children: item.label })
707
+ ] }),
708
+ isActive && item.description && /* @__PURE__ */ jsx("div", { className: "text-[11px] text-sidebar-foreground/60 mt-1.5 animate-in fade-in slide-in-from-top-1 duration-200", children: item.description })
709
+ ] }),
710
+ /* @__PURE__ */ jsx("div", { className: "h-5 flex items-center ml-1", children: renderAssistantActionMenu(item.actions) })
711
+ ]
712
+ },
713
+ item.path
714
+ );
715
+ }) })
716
+ ] }, group.id);
717
+ };
718
+ if (variant === "assistant") {
719
+ return /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx(
720
+ "div",
721
+ {
722
+ className: "h-full px-4",
723
+ style: { overflowY: "auto", overflowX: "hidden" },
724
+ children: navigationGroups.map((group) => renderAssistantGroup(group))
725
+ }
726
+ ) });
727
+ }
728
+ if (isMobileViewport && isOverflowAccordionOpen) {
729
+ return /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx(
730
+ "div",
731
+ {
732
+ className: "h-full",
733
+ style: { overflowY: "auto", overflowX: "hidden" },
734
+ children: /* @__PURE__ */ jsx(
735
+ "nav",
736
+ {
737
+ id: "sidebar-nav",
738
+ "aria-label": t("sidebar.mainNavigation"),
739
+ className: "px-4 py-4",
740
+ ref: navRef,
741
+ children: navigationGroups && navigationGroups.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
742
+ (hasGroupOverflow ? visibleGroups : navigationGroups).map((group) => /* @__PURE__ */ jsx(React__default.Fragment, { children: renderDefaultGroup(group) }, group.id)),
743
+ hasGroupOverflow && /* @__PURE__ */ jsx(
744
+ OverflowGroupsAccordion,
745
+ {
746
+ expanded,
747
+ overflowGroups,
748
+ location,
749
+ handleNavigate,
750
+ moreOptionsLabel: t("sidebar.moreOptions"),
751
+ onOpenChange: setIsOverflowAccordionOpen
752
+ }
753
+ )
754
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
755
+ (hasOverflow ? visibleItems : navigationItems).map((item) => renderDefaultItem(item)),
756
+ hasOverflow && /* @__PURE__ */ jsxs(Popover, { children: [
757
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
758
+ "button",
759
+ {
760
+ className: expanded ? "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground" : "w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground",
761
+ "aria-label": t("sidebar.moreOptions"),
762
+ children: [
763
+ /* @__PURE__ */ jsx(MoreVertical, { className: "w-5 h-5 flex-shrink-0" }),
764
+ expanded && /* @__PURE__ */ jsx("span", { className: "truncate text-sidebar-foreground", children: t("sidebar.moreOptions") })
765
+ ]
766
+ }
767
+ ) }),
768
+ /* @__PURE__ */ jsx(
769
+ PopoverContent,
770
+ {
771
+ side: "right",
772
+ align: "start",
773
+ className: "w-56 p-2 bg-popover border border-border rounded-[var(--radius-card)] shadow-lg",
774
+ sideOffset: 8,
775
+ children: /* @__PURE__ */ jsx("div", { className: "space-y-1", children: overflowItems.map((item) => {
776
+ const Icon = item.icon;
777
+ return /* @__PURE__ */ jsxs(
778
+ "button",
779
+ {
780
+ onClick: () => handleNavigate(item.path),
781
+ className: "w-full h-9 flex items-center gap-2 px-3 rounded-[var(--radius-button)] transition-all duration-200 text-popover-foreground/80 hover:bg-accent hover:text-accent-foreground text-left",
782
+ children: [
783
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "w-4 h-4 flex-shrink-0" }),
784
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: item.label })
785
+ ]
786
+ },
787
+ item.path
788
+ );
789
+ }) })
790
+ }
791
+ )
792
+ ] })
793
+ ] })
794
+ }
795
+ )
796
+ }
797
+ ) });
798
+ }
799
+ return /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx(
800
+ "nav",
801
+ {
802
+ id: "sidebar-nav",
803
+ "aria-label": t("sidebar.mainNavigation"),
804
+ className: "h-full px-4 py-4 overflow-hidden",
805
+ ref: navRef,
806
+ children: navigationGroups && navigationGroups.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
807
+ (hasGroupOverflow ? visibleGroups : navigationGroups).map((group) => /* @__PURE__ */ jsx(React__default.Fragment, { children: renderDefaultGroup(group) }, group.id)),
808
+ hasGroupOverflow && (isMobileViewport ? (
809
+ // Mobile: accordion inline abre abaixo, igual aos subitens
810
+ /* @__PURE__ */ jsx(
811
+ OverflowGroupsAccordion,
812
+ {
813
+ expanded,
814
+ overflowGroups,
815
+ location,
816
+ handleNavigate,
817
+ moreOptionsLabel: t("sidebar.moreOptions"),
818
+ onOpenChange: setIsOverflowAccordionOpen
819
+ }
820
+ )
821
+ ) : (
822
+ // Desktop: popover lateral direito
823
+ /* @__PURE__ */ jsxs(Popover, { children: [
824
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
825
+ "button",
826
+ {
827
+ className: expanded ? "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground" : "w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground",
828
+ "aria-label": t("sidebar.moreOptions"),
829
+ children: [
830
+ /* @__PURE__ */ jsx(MoreVertical, { className: "w-5 h-5 flex-shrink-0" }),
831
+ expanded && /* @__PURE__ */ jsx("span", { className: "truncate text-sidebar-foreground", children: t("sidebar.moreOptions") })
832
+ ]
833
+ }
834
+ ) }),
835
+ /* @__PURE__ */ jsx(
836
+ PopoverContent,
837
+ {
838
+ side: "right",
839
+ align: "start",
840
+ className: "w-56 p-2 bg-popover border border-border rounded-[var(--radius-card)] shadow-lg",
841
+ sideOffset: 8,
842
+ children: /* @__PURE__ */ jsx("div", { className: "space-y-3", children: overflowGroups.map((group) => {
843
+ const GroupIcon = group.icon;
844
+ return /* @__PURE__ */ jsxs("div", { children: [
845
+ (group.label || GroupIcon) && /* @__PURE__ */ jsxs("div", { className: "px-2 mb-1 flex items-center gap-2", children: [
846
+ GroupIcon && (React__default.isValidElement(GroupIcon) ? GroupIcon : /* @__PURE__ */ jsx(GroupIcon, { className: "h-3 w-3 text-popover-foreground/60" })),
847
+ group.label && /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-wider text-popover-foreground/60", children: group.label })
848
+ ] }),
849
+ /* @__PURE__ */ jsx("div", { className: "space-y-1", children: group.items.map((item) => {
850
+ const Icon = item.icon;
851
+ const isActive = location.pathname === item.path || location.pathname.startsWith(item.path + "/");
852
+ return /* @__PURE__ */ jsxs(
853
+ "button",
854
+ {
855
+ onClick: () => handleNavigate(item.path),
856
+ className: cn(
857
+ "w-full h-9 flex items-center gap-2 px-2 rounded-[var(--radius-button)] transition-all duration-200 text-left text-sm",
858
+ isActive ? "bg-accent text-accent-foreground font-medium" : "text-popover-foreground/80 hover:bg-accent hover:text-accent-foreground"
859
+ ),
860
+ children: [
861
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "w-4 h-4 flex-shrink-0" }),
862
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: item.label })
863
+ ]
864
+ },
865
+ item.path
866
+ );
867
+ }) })
868
+ ] }, group.id);
869
+ }) })
870
+ }
871
+ )
872
+ ] })
873
+ ))
874
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
875
+ (hasOverflow ? visibleItems : navigationItems).map((item) => renderDefaultItem(item)),
876
+ hasOverflow && /* @__PURE__ */ jsxs(Popover, { children: [
877
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
878
+ "button",
879
+ {
880
+ className: expanded ? "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground" : "w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground",
881
+ "aria-label": t("sidebar.moreOptions"),
882
+ children: [
883
+ /* @__PURE__ */ jsx(MoreVertical, { className: "w-5 h-5 flex-shrink-0" }),
884
+ expanded && /* @__PURE__ */ jsx("span", { className: "truncate text-sidebar-foreground", children: t("sidebar.moreOptions") })
885
+ ]
886
+ }
887
+ ) }),
888
+ /* @__PURE__ */ jsx(
889
+ PopoverContent,
890
+ {
891
+ side: "right",
892
+ align: "start",
893
+ className: "w-56 p-2 bg-popover border border-border rounded-[var(--radius-card)] shadow-lg",
894
+ sideOffset: 8,
895
+ children: /* @__PURE__ */ jsx("div", { className: "space-y-1", children: overflowItems.map((item) => {
896
+ const Icon = item.icon;
897
+ return /* @__PURE__ */ jsxs(
898
+ "button",
899
+ {
900
+ onClick: () => handleNavigate(item.path),
901
+ className: "w-full h-9 flex items-center gap-2 px-3 rounded-[var(--radius-button)] transition-all duration-200 text-popover-foreground/80 hover:bg-accent hover:text-accent-foreground text-left",
902
+ children: [
903
+ Icon && /* @__PURE__ */ jsx(Icon, { className: "w-4 h-4 flex-shrink-0" }),
904
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: item.label })
905
+ ]
906
+ },
907
+ item.path
908
+ );
909
+ }) })
910
+ }
911
+ )
912
+ ] })
913
+ ] })
914
+ }
915
+ ) });
916
+ }
917
+ function SidebarSearch({
918
+ fixedArea,
919
+ search
920
+ }) {
921
+ const { expanded } = useSidebarContext();
922
+ const { t } = useTranslation();
923
+ const [isFilterOpen, setIsFilterOpen] = useState(false);
924
+ if (!(fixedArea && fixedArea.show || search && search.show)) return null;
925
+ return /* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 px-4 pb-4 space-y-4 border-b border-sidebar-border/30 mb-2", children: [
926
+ fixedArea?.show && fixedArea.content && expanded && /* @__PURE__ */ jsx("div", { className: "animate-in fade-in slide-in-from-top-1 duration-300", children: fixedArea.content }),
927
+ search?.show && expanded && /* @__PURE__ */ jsxs(Fragment, { children: [
928
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
929
+ /* @__PURE__ */ jsxs("div", { className: "relative flex-1", children: [
930
+ /* @__PURE__ */ jsx(Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-sidebar-foreground/50" }),
931
+ /* @__PURE__ */ jsx(
932
+ Input,
933
+ {
934
+ type: "text",
935
+ placeholder: search.placeholder || t("sidebar.searchPlaceholder"),
936
+ "aria-label": search.placeholder || t("sidebar.searchPlaceholder"),
937
+ value: search.value,
938
+ onChange: (e) => search.onChange?.(e.target.value),
939
+ className: "w-full h-9 bg-sidebar-foreground/10 border-sidebar-border text-sidebar-foreground placeholder:text-sidebar-foreground/50 pl-9 focus-visible:ring-1 focus-visible:ring-sidebar-foreground/30 focus-visible:ring-offset-0"
940
+ }
941
+ )
942
+ ] }),
943
+ search.filter?.show && search.filter.content && /* @__PURE__ */ jsx(
944
+ Button,
945
+ {
946
+ variant: "ghost",
947
+ size: "icon",
948
+ onClick: () => setIsFilterOpen(!isFilterOpen),
949
+ className: cn(
950
+ "h-9 w-9 text-sidebar-foreground transition-all duration-200",
951
+ isFilterOpen ? "bg-sidebar-foreground/20" : "hover:bg-sidebar-foreground/15"
952
+ ),
953
+ "aria-label": isFilterOpen ? t("sidebar.closeFilters") : t("sidebar.openFilters"),
954
+ children: search.filter.icon || /* @__PURE__ */ jsx(Filter, { className: "h-4 w-4" })
955
+ }
956
+ )
957
+ ] }),
958
+ /* @__PURE__ */ jsx(AnimatePresence, { children: isFilterOpen && search.filter?.show && search.filter.content && /* @__PURE__ */ jsx(
959
+ motion.div,
960
+ {
961
+ initial: { height: 0, opacity: 0 },
962
+ animate: { height: "auto", opacity: 1 },
963
+ exit: { height: 0, opacity: 0 },
964
+ transition: { duration: 0.2 },
965
+ className: "overflow-hidden",
966
+ children: /* @__PURE__ */ jsx("div", { className: "pt-2 border-t border-sidebar-border/20", children: search.filter.content })
967
+ }
968
+ ) })
969
+ ] }),
970
+ !expanded && (fixedArea?.show || search?.show) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-4 py-2", children: [
971
+ fixedArea?.show && fixedArea.icon && /* @__PURE__ */ jsxs(Tooltip, { children: [
972
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
973
+ "button",
974
+ {
975
+ onClick: () => fixedArea.onClick?.(),
976
+ className: "h-10 w-10 flex items-center justify-center rounded-[var(--radius-button)] bg-primary text-primary-foreground shadow-sm hover:bg-primary/90 transition-all",
977
+ "aria-label": t("assistant.newConversation"),
978
+ children: React__default.isValidElement(fixedArea.icon) ? fixedArea.icon : /* @__PURE__ */ jsx(fixedArea.icon, { className: "h-5 w-5" })
979
+ }
980
+ ) }),
981
+ /* @__PURE__ */ jsx(CustomTooltipContent, { side: "right", children: t("assistant.newConversation") })
982
+ ] }),
983
+ search?.show && /* @__PURE__ */ jsxs(Tooltip, { children: [
984
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
985
+ "button",
986
+ {
987
+ className: "h-10 w-10 flex items-center justify-center rounded-[var(--radius-button)] text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground",
988
+ "aria-label": t("sidebar.search"),
989
+ children: /* @__PURE__ */ jsx(Search, { className: "h-5 w-5" })
990
+ }
991
+ ) }),
992
+ /* @__PURE__ */ jsx(CustomTooltipContent, { side: "right", children: t("sidebar.search") })
993
+ ] })
994
+ ] })
995
+ ] });
996
+ }
997
+ function SidebarFooter({
998
+ user,
999
+ onLogout = () => {
1000
+ },
1001
+ onSettingsClick,
1002
+ showUser = true,
1003
+ showSettings = true,
1004
+ showLogout = true
1005
+ }) {
1006
+ const { expanded, navigate, location, onToggle } = useSidebarContext();
1007
+ const { t } = useTranslation();
1008
+ const isSettingsActive = location.pathname === "/settings";
1009
+ const handleSettingsClick = () => {
1010
+ if (onSettingsClick) {
1011
+ onSettingsClick();
1012
+ } else {
1013
+ navigate("/settings");
1014
+ }
1015
+ if (typeof window !== "undefined" && window.innerWidth < 768) {
1016
+ onToggle();
1017
+ }
1018
+ };
1019
+ return /* @__PURE__ */ jsxs("div", { className: "flex-shrink-0 p-4 space-y-2", children: [
1020
+ showUser && (!expanded ? /* @__PURE__ */ jsxs(Tooltip, { children: [
1021
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1022
+ "button",
1023
+ {
1024
+ className: "w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground",
1025
+ "aria-label": t("sidebar.userProfile"),
1026
+ children: /* @__PURE__ */ jsxs(Avatar, { className: "w-7 h-7 flex-shrink-0", children: [
1027
+ /* @__PURE__ */ jsx(AvatarImage, { src: user?.avatar, alt: user?.name || "User" }),
1028
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-sidebar-foreground/15 text-sidebar-foreground text-xs", children: user?.name ? user.name.charAt(0).toUpperCase() : "U" })
1029
+ ] })
1030
+ }
1031
+ ) }),
1032
+ /* @__PURE__ */ jsx(CustomTooltipContent, { side: "right", sideOffset: 0, children: /* @__PURE__ */ jsx("p", { children: user?.name || t("sidebar.profile") }) })
1033
+ ] }) : /* @__PURE__ */ jsxs("button", { className: "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground", children: [
1034
+ /* @__PURE__ */ jsxs(Avatar, { className: "w-7 h-7 flex-shrink-0", children: [
1035
+ /* @__PURE__ */ jsx(AvatarImage, { src: user?.avatar, alt: user?.name || "User" }),
1036
+ /* @__PURE__ */ jsx(AvatarFallback, { className: "bg-sidebar-foreground/15 text-sidebar-foreground text-xs", children: user?.name ? user.name.charAt(0).toUpperCase() : "U" })
1037
+ ] }),
1038
+ /* @__PURE__ */ jsx("span", { className: "text-sidebar-foreground truncate", children: user?.name || t("sidebar.profile") })
1039
+ ] })),
1040
+ showSettings && (!expanded ? /* @__PURE__ */ jsxs(Tooltip, { children: [
1041
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1042
+ "button",
1043
+ {
1044
+ onClick: handleSettingsClick,
1045
+ className: cn(
1046
+ "w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200",
1047
+ isSettingsActive ? "bg-sidebar-foreground/15 text-sidebar-foreground shadow-sm" : "text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
1048
+ ),
1049
+ "aria-label": t("nav.settings"),
1050
+ children: /* @__PURE__ */ jsx(Settings, { className: "w-5 h-5 flex-shrink-0" })
1051
+ }
1052
+ ) }),
1053
+ /* @__PURE__ */ jsx(CustomTooltipContent, { side: "right", sideOffset: 0, children: /* @__PURE__ */ jsx("p", { children: t("nav.settings") }) })
1054
+ ] }) : /* @__PURE__ */ jsxs(
1055
+ "button",
1056
+ {
1057
+ onClick: handleSettingsClick,
1058
+ className: cn(
1059
+ "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200",
1060
+ isSettingsActive ? "bg-sidebar-foreground/15 text-sidebar-foreground shadow-sm" : "text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground"
1061
+ ),
1062
+ children: [
1063
+ /* @__PURE__ */ jsx(Settings, { className: "w-5 h-5 flex-shrink-0" }),
1064
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sidebar-foreground", children: t("nav.settings") })
1065
+ ]
1066
+ }
1067
+ )),
1068
+ showLogout && (!expanded ? /* @__PURE__ */ jsxs(Tooltip, { children: [
1069
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1070
+ "button",
1071
+ {
1072
+ onClick: onLogout,
1073
+ className: "w-full h-10 flex items-center justify-center px-0 rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground",
1074
+ "aria-label": t("sidebar.logout"),
1075
+ children: /* @__PURE__ */ jsx(LogOut, { className: "w-5 h-5 flex-shrink-0" })
1076
+ }
1077
+ ) }),
1078
+ /* @__PURE__ */ jsx(CustomTooltipContent, { side: "right", sideOffset: 0, children: /* @__PURE__ */ jsx("p", { children: t("sidebar.logout") }) })
1079
+ ] }) : /* @__PURE__ */ jsxs(
1080
+ "button",
1081
+ {
1082
+ onClick: onLogout,
1083
+ className: "w-full h-10 flex items-center gap-3 px-3 justify-start rounded-[var(--radius-button)] transition-all duration-200 text-sidebar-foreground/80 hover:bg-sidebar-foreground/15 hover:text-sidebar-foreground",
1084
+ children: [
1085
+ /* @__PURE__ */ jsx(LogOut, { className: "w-5 h-5 flex-shrink-0" }),
1086
+ /* @__PURE__ */ jsx("span", { className: "truncate text-sidebar-foreground", children: t("sidebar.logout") })
1087
+ ]
1088
+ }
1089
+ ))
1090
+ ] });
1091
+ }
1092
+ function Sidebar({
1093
+ expanded: expandedProp,
1094
+ onToggle: onToggleProp,
1095
+ user,
1096
+ onLogout = () => {
1097
+ },
1098
+ onSettingsClick,
1099
+ location: locationProp,
1100
+ navigate: navigateProp,
1101
+ routes,
1102
+ logo,
1103
+ logoCollapsed,
1104
+ variant = "default",
1105
+ fixedArea,
1106
+ search,
1107
+ navigationGroups = [],
1108
+ footer,
1109
+ showFooter,
1110
+ width: widthProp
1111
+ }) {
1112
+ const { showUser = true, showSettings = true, showLogout = true } = footer || {};
1113
+ const displayFooter = showFooter !== void 0 ? showFooter : variant === "default";
1114
+ return /* @__PURE__ */ jsxs(
1115
+ SidebarRoot,
1116
+ {
1117
+ expanded: expandedProp,
1118
+ onToggle: onToggleProp,
1119
+ navigate: navigateProp,
1120
+ location: locationProp,
1121
+ width: widthProp,
1122
+ children: [
1123
+ /* @__PURE__ */ jsx(SidebarHeader, { logo, logoCollapsed }),
1124
+ variant === "assistant" && /* @__PURE__ */ jsx(SidebarSearch, { fixedArea, search }),
1125
+ /* @__PURE__ */ jsx(SidebarNav, { navigationGroups, routes, variant }),
1126
+ displayFooter && (showUser || showSettings || showLogout) && /* @__PURE__ */ jsx(
1127
+ SidebarFooter,
1128
+ {
1129
+ user,
1130
+ onLogout,
1131
+ onSettingsClick,
1132
+ showUser,
1133
+ showSettings,
1134
+ showLogout
1135
+ }
1136
+ )
1137
+ ]
1138
+ }
1139
+ );
1140
+ }
1141
+ Sidebar.Root = SidebarRoot;
1142
+ Sidebar.Header = SidebarHeader;
1143
+ Sidebar.Search = SidebarSearch;
1144
+ Sidebar.Nav = SidebarNav;
1145
+ Sidebar.Footer = SidebarFooter;
1146
+
1147
+ export { Header as H, Sidebar as S };