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; +}