From 288f0ff29faa95ee3882daaa9b200dc78e89527c Mon Sep 17 00:00:00 2001 From: Nils <104727469+nilskroe@users.noreply.github.com> Date: Fri, 16 Jan 2026 17:48:57 +0100 Subject: [PATCH] feat(sidebar): add grid loader indicator for active sessions (#158) Replace the subtle pulse animation with a visible 3x3 grid loader that appears before the session name when a session is actively processing. This provides clearer visual feedback of session activity. - Add new GridLoader component (pure CSS, no dependencies) - Show loader in sidebar when session phase is 'busy' or 'cooldown' --- .../src/components/session/SessionSidebar.tsx | 11 +++--- packages/ui/src/components/ui/grid-loader.tsx | 35 +++++++++++++++++++ packages/ui/src/index.css | 15 ++++++++ 3 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 packages/ui/src/components/ui/grid-loader.tsx diff --git a/packages/ui/src/components/session/SessionSidebar.tsx b/packages/ui/src/components/session/SessionSidebar.tsx index 72fbead4..e6f69e52 100644 --- a/packages/ui/src/components/session/SessionSidebar.tsx +++ b/packages/ui/src/components/session/SessionSidebar.tsx @@ -27,6 +27,7 @@ import { import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay'; import { Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip'; +import { GridLoader } from '@/components/ui/grid-loader'; import { RiAddLine, RiArrowDownSLine, @@ -1117,12 +1118,10 @@ export const SessionSidebar: React.FC = ({ > {}
- + {isStreaming ? ( + + ) : null} + {sessionTitle} diff --git a/packages/ui/src/components/ui/grid-loader.tsx b/packages/ui/src/components/ui/grid-loader.tsx new file mode 100644 index 00000000..7dd7d58e --- /dev/null +++ b/packages/ui/src/components/ui/grid-loader.tsx @@ -0,0 +1,35 @@ +import * as React from 'react'; +import { cn } from '@/lib/utils'; + +interface GridLoaderProps { + className?: string; + size?: 'xs' | 'sm' | 'md' | 'lg'; +} + +const sizeConfig = { + xs: { container: 'gap-[1px]', dot: 'h-[3px] w-[3px]' }, + sm: { container: 'gap-0.5', dot: 'h-1 w-1' }, + md: { container: 'gap-1', dot: 'h-1.5 w-1.5' }, + lg: { container: 'gap-1.5', dot: 'h-2 w-2' }, +}; + +const GridLoader: React.FC = ({ className, size = 'md' }) => { + const config = sizeConfig[size]; + + return ( +
+ {Array.from({ length: 9 }, (_, i) => ( +
+ ))} +
+ ); +}; + +export { GridLoader }; diff --git a/packages/ui/src/index.css b/packages/ui/src/index.css index 2088b40d..13be3d63 100644 --- a/packages/ui/src/index.css +++ b/packages/ui/src/index.css @@ -1546,3 +1546,18 @@ html:not(.dark) .chat-scroll { .fonts-loaded .terminal-viewport-container { font-family: "JetBrainsMono Nerd Font", "FiraCode Nerd Font", "Fira Code", "JetBrains Mono", "SFMono-Regular", Menlo, Consolas, "Liberation Mono", "Courier New", monospace; } + +@keyframes grid-pulse { + 0%, 100% { + opacity: 0.2; + transform: scale(0.8); + } + 50% { + opacity: 1; + transform: scale(1); + } +} + +.animate-grid-pulse { + animation: grid-pulse 1.2s ease-in-out infinite; +}