Conversation
When working on UI elements it is a lot easier to iterate and test in storybook where you can put up the interesting cases as stories and browse through them instead of having construct scenarios in a live running app.
There was a problem hiding this comment.
Pull request overview
Adds Storybook to the ui/ package to make UI component development and verification easier outside of the running Next.js app.
Changes:
- Adds Storybook configuration (
ui/.storybook/*) and npm scripts to run/build Storybook. - Introduces initial Storybook stories for sidebar and chat/components.
- Adds Vitest + Storybook addon-vitest setup for running story-based tests in a browser (Playwright).
Reviewed changes
Copilot reviewed 26 out of 28 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/vitest.shims.d.ts | Adds Vitest browser Playwright types reference. |
| ui/vitest.config.ts | Adds Vitest config for Storybook addon-vitest + Playwright browser runner. |
| ui/.storybook/main.ts | Storybook framework/addons/stories configuration. |
| ui/.storybook/preview.ts | Global preview parameters, global CSS import, decorator setup. |
| ui/.storybook/vitest.setup.ts | Applies Storybook project annotations for Vitest story tests (incl. a11y). |
| ui/src/components/sidebars/SessionGroup.stories.tsx | Adds Storybook stories for SessionGroup sidebar grouping UI. |
| ui/src/components/sidebars/GroupedChats.stories.tsx | Adds stories for grouped chats rendering across timeframes. |
| ui/src/components/sidebars/EmptyState.stories.tsx | Adds EmptyState sidebar story. |
| ui/src/components/sidebars/ChatItem.stories.tsx | Adds stories for chat item rendering/overflow cases. |
| ui/src/components/sidebars/AgentSwitcher.stories.tsx | Adds AgentSwitcher stories for single/multi agent lists. |
| ui/src/components/sidebars/AgentDetailsSidebar.stories.tsx | Adds AgentDetailsSidebar stories covering tools/no-tools/BYO. |
| ui/src/components/chat/TruncatableText.stories.tsx | Adds TruncatableText stories for various markdown/text cases. |
| ui/src/components/chat/TokenStats.stories.tsx | Adds TokenStats stories for multiple usage sizes. |
| ui/src/components/chat/StreamingMessage.stories.tsx | Adds StreamingMessage stories incl. empty-content behavior. |
| ui/src/components/chat/StatusDisplay.stories.tsx | Adds StatusDisplay stories for all statuses and messages. |
| ui/src/components/chat/CodeBlock.stories.tsx | Adds CodeBlock stories for multiple languages and lengths. |
| ui/src/components/chat/ChatMessage.stories.tsx | Adds ChatMessage stories for multiple message variants. |
| ui/src/components/chat/AgentCallDisplay.stories.tsx | Adds AgentCallDisplay stories for call lifecycle variants. |
| ui/src/components/ToolDisplay.stories.tsx | Adds ToolDisplay stories including “chat layout” decorator variants. |
| ui/src/components/LoadingState.stories.tsx | Adds LoadingState story. |
| ui/src/components/Header.stories.tsx | Adds Header stories incl. mobile viewport. |
| ui/src/components/Footer.stories.tsx | Adds Footer story. |
| ui/src/components/ErrorState.stories.tsx | Adds ErrorState stories for message-length and button variants. |
| ui/src/components/AgentCard.stories.tsx | Adds AgentCard stories for readiness/acceptance/BYO/long text cases. |
| ui/package.json | Adds Storybook scripts + Storybook/Vitest/Playwright dev dependencies. |
| ui/eslint.config.mjs | Enables eslint-plugin-storybook recommended flat config. |
| ui/.gitignore | Ignores Storybook static build output. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| (Story) => { | ||
| document.documentElement.classList.add('dark'); | ||
| return Story(); | ||
| }, |
There was a problem hiding this comment.
The decorator returns Story() (invoking the story function directly). In Storybook/React this can bypass React’s component lifecycle and will break stories that use hooks. Render it as a component instead (e.g., return <Story />).
| const ChatLayoutDecorator = (Story: React.ComponentType) => ( | ||
| <div className="flex h-screen"> |
There was a problem hiding this comment.
React.ComponentType is referenced but React isn’t imported in this module, which will typically fail TypeScript compilation (other files that use React.ComponentType import React). Import the needed type from react (e.g., ComponentType) or import React before using the React.* namespace.
| const result = StreamingMessage(args); | ||
| return result === null ? <div className="text-gray-500">Component returns null for empty content</div> : result; |
There was a problem hiding this comment.
This story calls the StreamingMessage component as a plain function (StreamingMessage(args)). That bypasses React rendering semantics and will break if the component ever starts using hooks/context. Prefer rendering <StreamingMessage {...args} /> and branching on args.content (or wrap it in a small helper component) instead of calling it directly.
| const result = StreamingMessage(args); | |
| return result === null ? <div className="text-gray-500">Component returns null for empty content</div> : result; | |
| if (!args.content) { | |
| return <div className="text-gray-500">Component returns null for empty content</div>; | |
| } | |
| return <StreamingMessage {...args} />; |
When working on UI elements it is a lot easier to iterate and test in storybook where you can put up the interesting cases as stories and browse through them instead of having construct scenarios in a live running app.