Feature/component loading state#504
Merged
ankit-thesys merged 7 commits intoMay 15, 2026
Merged
Conversation
…d tool latency Remove tools from the runTools() call so the LLM only generates Query() statements instead of executing tools server-side during generation. Replace SSE streaming helper (sseResponseFromRunner) with a manual ReadableStream that pipes plain create() chunks directly as SSE events with an explicit data: [DONE] terminator. Add NEXT_PUBLIC_TOOL_DELAY_MS env var so mock tool execute() functions simulate network latency, surfacing intermediate loading states in the UI.
…t queries Add isQueryLoading field to OpenUIContextValue and export a useIsQueryLoading() hook so data-driven genui components can detect when Query() calls are still fetching data via MCP. Wire isQueryLoading from querySnapshot.__openui_loading in the useOpenUIState hook, moving the variable before contextValue so it is no longer referenced before declaration.
Add Skeleton, SkeletonBar, and TableSkeleton components with a theme-aware opacity-pulse animation driven by CSS variables (--openui-elevated-strong, --openui-border-default, --openui-radius-xs) so the loading state is clearly visible against light and dark backgrounds. Wire the genui-lib Table component to use useIsQueryLoading() and render TableSkeleton when data is loading and no rows are present yet, using deterministic widths for SSR hydration safety.
Add useIsQueryLoading() to the react-lang API reference and the renderer hooks list alongside useIsStreaming. Document Skeleton, TableSkeleton, and how the genui Table component automatically uses them when isQueryLoading is true and no rows exist.
- Fix import ordering and ternary formatting in genui-lib Table - Refactor Skeleton component from inline styles to SCSS classes per repo standards - Add explanatory comment to .env.example for NEXT_PUBLIC_TOOL_DELAY_MS
- Add skeleton.scss with design tokens (cssUtils) and keyframe animation - Add dependencies.ts per component structure rules - Add Storybook stories for Skeleton and TableSkeleton - Regenerate components/index.scss to forward Skeleton styles
…and wire into genui PieChart Replace the narrow DonutChartSkeleton with a proper PieChartSkeleton that mirrors the component library's variant/appearance model: - variant: 'pie' | 'donut' - appearance: 'circular' | 'semiCircular' This ensures skeletons are visually consistent with the actual chart shapes they replace, avoiding layout jumps when data arrives. It also demonstrates WHY per-component loading state is needed (issue thesysdev#503): when multiple queries run in parallel with different durations, each component should show its own skeleton rather than relying on a global spinner. Changes: - Skeleton.tsx: PieChartSkeleton with variant/appearance/size props; use mutually exclusive class composition instead of overlapping modifiers - skeleton.scss: CSS for all 4 shape combos using design tokens (-xl, -full) - PieChart.ts: wire useIsQueryLoading -> PieChartSkeleton; expose 'appearance' in genUI schema; remove unreachable skeleton branch; destructure variant/appearance at top of component - Skeleton.stories.tsx: stories for all 4 variant/appearance combinations - tools.ts: double get_error_breakdown delay for testing staggered loads
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #503
Summary
Genui apps with
Query()calls render before tool data arrives, showing blank/empty UIs in an indeterminate loading state. This PR surfaces that loading state to components and adds skeleton placeholders so users see progress instead of nothing.Changes
fix(openui-dashboard):remove server-side tool calls and add simulated tool latencyRefactors the chat route to use plain streaming (no
runTools) so tool calls happen client-side via MCP rather than during LLM generation. AddsNEXT_PUBLIC_TOOL_DELAY_MSto mock tools for testing intermediate loading states.feat(react-lang):addisQueryLoadingto context for tracking in-flight queriesAdds
isQueryLoadingtoOpenUIContextValueand exports auseIsQueryLoading()hook. Genui components can now distinguish between "waiting on data" and "no data exists."feat(react-ui):add Skeleton component and loading state to TableNew
Skeleton,SkeletonBar, andTableSkeletoncomponents with theme-aware CSS variables. The genuiTablenow renders<TableSkeleton>while queries are in-flight and no rows exist yet.docs:adduseIsQueryLoadingand Skeleton component documentationUpdates the react-lang API reference, renderer hooks list, and react-ui component docs with the new API surface.
Screenshot
Table skeleton during tool call loading state in examples/openui-dashboard:

Checklist
useIsQueryLoading()exported from@openuidev/react-langSkeleton/TableSkeletonexported from@openuidev/react-uiTablegenui component shows loading skeleton while queries fetchreact-ui,openui-dashboard)