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