mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-06 02:48:13 +00:00
fix(ui): render the sidebar scrollbar with shadcn ScrollArea (#33124)
* fix(ui): render the sidebar scrollbar with shadcn ScrollArea The sidebar navigation scrolled through a native overflow-y-auto container, so the browser drew its default scrollbar. It now scrolls through the shadcn ScrollArea primitive so the thumb matches the rest of the dashboard Switching to ScrollArea surfaced a latent styling gap. The Base UI scroll-area, tabs, and separator primitives rely on data-horizontal and data-vertical Tailwind variants that resolve to [data-orientation="horizontal"] and [data-orientation="vertical"], and those variants ship in shadcn's shared stylesheet. The project never imported it, so the classes matched nothing and the scrollbar collapsed to zero width. This adds shadcn as a devDependency and imports shadcn/tailwind.css, which also repairs the vertical tabs and separator styling. See shadcn-ui/ui#9196 for the upstream tracking issue * refactor(ui): inline the Base UI data-* variants, drop the shadcn dep The earlier fix imported shadcn/tailwind.css through the shadcn devDependency, which pulled 219 packages and tied the CSS build to shadcn's package exports (an open Turbopack-breaking bug, shadcn-ui/ui#10931). shadcn's model is that we own the components, so the custom variants those components depend on belong in our own stylesheet rather than a runtime dependency. This inlines the nine data-* custom variants and the no-scrollbar utility that the Base UI primitives reference into globals.css, and removes the shadcn package.
This commit is contained in:
parent
39e0efa11d
commit
07d2a03dbf
2 changed files with 31 additions and 10 deletions
|
|
@ -11,6 +11,25 @@
|
|||
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
/* shadcn Base UI primitives reference these variants; upstream omits them (shadcn-ui/ui#9196) */
|
||||
@custom-variant data-open (&:where([data-state="open"], [data-open]:not([data-open="false"])));
|
||||
@custom-variant data-closed (&:where([data-state="closed"], [data-closed]:not([data-closed="false"])));
|
||||
@custom-variant data-checked (&:where([data-state="checked"], [data-checked]:not([data-checked="false"])));
|
||||
@custom-variant data-unchecked (&:where([data-state="unchecked"], [data-unchecked]:not([data-unchecked="false"])));
|
||||
@custom-variant data-selected (&:where([data-selected="true"]));
|
||||
@custom-variant data-disabled (&:where([data-disabled="true"], [data-disabled]:not([data-disabled="false"])));
|
||||
@custom-variant data-active (&:where([data-state="active"], [data-active]:not([data-active="false"])));
|
||||
@custom-variant data-horizontal (&:where([data-orientation="horizontal"]));
|
||||
@custom-variant data-vertical (&:where([data-orientation="vertical"]));
|
||||
|
||||
@utility no-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
--radius: 0.5rem;
|
||||
--background: oklch(1 0 0);
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import { getProxyBaseUrl } from "@/components/networking";
|
|||
import { useTheme } from "@/contexts/ThemeContext";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarContent,
|
||||
SidebarFooter,
|
||||
SidebarGroup,
|
||||
SidebarGroupLabel,
|
||||
|
|
@ -608,15 +608,17 @@ const Sidebar_: React.FC<SidebarProps> = ({
|
|||
</div>
|
||||
</SidebarHeader>
|
||||
|
||||
<SidebarContent>
|
||||
{visibleGroups.map((group, gi) => (
|
||||
<SidebarGroup key={group.groupLabel}>
|
||||
{gi > 0 && <SidebarSeparator className="hidden group-data-[collapsed=true]/sidebar:block" />}
|
||||
<SidebarGroupLabel>{group.groupLabel}</SidebarGroupLabel>
|
||||
<SidebarMenu>{group.items.map((item) => renderItem(item))}</SidebarMenu>
|
||||
</SidebarGroup>
|
||||
))}
|
||||
</SidebarContent>
|
||||
<ScrollArea className="min-h-0 flex-1">
|
||||
<nav className="flex flex-col gap-0.5 px-3 pb-3">
|
||||
{visibleGroups.map((group, gi) => (
|
||||
<SidebarGroup key={group.groupLabel}>
|
||||
{gi > 0 && <SidebarSeparator className="hidden group-data-[collapsed=true]/sidebar:block" />}
|
||||
<SidebarGroupLabel>{group.groupLabel}</SidebarGroupLabel>
|
||||
<SidebarMenu>{group.items.map((item) => renderItem(item))}</SidebarMenu>
|
||||
</SidebarGroup>
|
||||
))}
|
||||
</nav>
|
||||
</ScrollArea>
|
||||
|
||||
<SidebarFooter>
|
||||
{isAdminRole(userRole) && (
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue