Skip to content

feat: artifact system with side-panel support and folder restructure - #364

Merged
ankit-thesys merged 21 commits into
thesysdev:mainfrom
ankit-thesys:feature/Artifact
Mar 24, 2026
Merged

feat: artifact system with side-panel support and folder restructure#364
ankit-thesys merged 21 commits into
thesysdev:mainfrom
ankit-thesys:feature/Artifact

Conversation

@ankit-thesys

Copy link
Copy Markdown
Contributor

Summary

Introduces a complete artifact system that enables chat messages to display rich side-panel content (code previews, generated UIs, charts) alongside conversations. Also restructures react-ui to eliminate dependency tangles between layout variants.

Artifact System (react-headless)

  • Zustand artifact store (createArtifactStore) with subscribeWithSelector middleware — manages artifact registry, active state, and portal target node
  • Types (artifactTypes.ts): ArtifactMeta, ArtifactMetaInput, ArtifactState, ArtifactActions, ArtifactStore
  • Consumer hooks:
    • useArtifact(id) — per-artifact state + actions (isActive, meta, open, close, toggle, triggerProps)
    • useActiveArtifact() — global "is anything open?" state for layout components
    • useArtifactPortalTarget() — public hook for registering/reading the portal target DOM node
    • useArtifactStore() — escape hatch for raw store access
  • Cross-store subscription in ChatProvider: resets artifacts automatically on thread switch
  • createChatStore wrapped with subscribeWithSelector middleware (no logic changes — enables slice-level subscriptions)

Artifact UI Components (react-ui)

  • ArtifactPanel — portals artifact content into ArtifactPortalTarget when active; includes error boundary, theme-scoped class names, configurable header (true/false/custom ReactNode)
  • ArtifactPortalTarget — registers a DOM node as the portal render target (display: contents)
  • ArtifactOverlay — shared overlay wrapper with slide-in/slide-out CSS animations, used by Shell (mobile), BottomTray, and CopilotShell layouts
  • Shell ThreadContainer — desktop: resizable artifact panel with drag separator; mobile: overlay mode
  • All artifact components use only public headless hooks (no @internal field access)

Folder Restructure (react-ui)

Extracted shared infrastructure into components/_shared/ to eliminate dependency tangles:

From To Why
Shell/store.tsx _shared/store/ Used by all 3 layouts, not Shell-specific
Shell/ArtifactPanel.tsx + ArtifactPortalTarget.tsx _shared/artifact/ Shared artifact infra
ArtifactOverlay/ _shared/artifact/ Co-locate with PortalTarget it wraps
OpenUIChat/types.ts (shared types) _shared/types/ Fixes backwards dependency
OpenUIChat/utils/ (isChatEmpty) _shared/utils/ Used by all 3 layouts

Result: All layout variants (Shell, BottomTray, CopilotShell) are now true peers importing from _shared/. No backwards dependencies. Zero public API breaking changes — Shell.* namespace re-exports from _shared/.

JSDoc Documentation

Comprehensive JSDoc across all new public APIs:

  • All hooks: @category, @param, @returns with {@link}, @example blocks
  • All types: top-level + per-field documentation
  • All components: component-level docs explaining portal behavior and prerequisites
  • Internal symbols marked with @internal

Other Changes

  • Removed isArtifactActive and renderArtifact props from ThreadContainer (replaced by hook-based artifact activation)
  • Removed unused OpenUIChat/types.ts prop (SharedChatUIProps no longer duplicates shared types)
  • Updated .gitignore for Claude Code workspace files

Test Coverage (30 tests)

  • createArtifactStore.test.ts (18 tests): open/close/remove/reset, metadata merging, timestamp behavior, DOM node management
  • artifactThreadSwitch.test.ts (5 tests): cross-store subscription — artifacts clear on thread switch, new thread, thread deletion; same-thread re-selection preserves artifacts; rapid switches handled
  • useArtifact.test.ts (7 tests): isActive state, open/close/toggle, multiple artifacts, metadata preservation

Test plan

  • pnpm --filter @openuidev/react-headless build — passes
  • pnpm --filter @openuidev/react-headless test — 71/71 tests pass
  • pnpm --filter @openuidev/react-ui build — passes
  • pnpm --filter @openuidev/react-ui lint:check — 0 errors
  • pnpm -r build — full monorepo build passes (all packages + docs + examples)
  • Storybook: verify Shell, CopilotShell, BottomTray stories render correctly
  • Manual: open artifact panel, close, switch threads (artifacts should clear), reopen

🤖 Generated with Claude Code

ankit-thesys and others added 17 commits March 5, 2026 17:51
…imitive

- Sidebar collapse: reduce width to 52px, remove background/full border,
  add smooth logo transition (36px to 28px), new toggle icons
- NewChatButton: render as IconButton when sidebar is collapsed
- SidebarHeader: accept children prop for flexible layout
- Composer: extract into components/ for Shell, CopilotShell, and BottomTray;
  add attachment prop, action-bar layout, scrollbar styling, isLoadingMessages guard
- DesktopWelcomeComposer: same attachment support and layout improvements
- ThreadHeader: new component for desktop-only header actions
- Portal: new component wrapping @radix-ui/react-portal
- Update all Storybook stories with new patterns

Made-with: Cursor
…to feature/shell-sidebar-composer-redesign
…to feature/shell-sidebar-composer-redesign
…r restructure

Introduce a complete artifact system for displaying rich side-panel content
alongside chat conversations. This includes:

- Zustand artifact store (createArtifactStore) with open/close/remove/reset actions
- Consumer hooks: useArtifact, useActiveArtifact, useArtifactPortalTarget
- Cross-store subscription to reset artifacts on thread switch
- UI components: ArtifactPanel (portal-based), ArtifactPortalTarget, ArtifactOverlay
- Comprehensive JSDoc documentation across all public APIs
- Folder restructure: extract shared infra (store, artifact, types, utils) into
  _shared/ to eliminate dependency tangles between Shell, BottomTray, and CopilotShell
- Refactor ArtifactPanel to use only public headless hooks (no @internal access)
- 30 tests covering store logic, thread-switch cleanup, and hook behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…to feature/shell-sidebar-composer-redesign
- Add `threadHeader` (desktop) and `mobileHeaderActions` props to FullScreen
- Add `headerActions` prop to Copilot and BottomTray layouts
- Fix composer textarea collapsing to 0px height in all layouts
  (use height: 0px instead of auto for scrollHeight measurement)
- Add Storybook stories demonstrating header customization
- Update MDX docs with header customization section and props tables

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ankit-thesys ankit-thesys self-assigned this Mar 20, 2026
@abhithesys abhithesys self-assigned this Mar 20, 2026
Comment thread packages/react-ui/src/components/Shell/shell.scss Outdated
Comment thread packages/react-headless/src/hooks/useArtifact.ts Outdated
Comment thread packages/react-headless/src/hooks/useArtifact.ts Outdated
Comment thread .gitignore Outdated
Comment thread packages/react-headless/src/store/artifactTypes.ts Outdated
Comment thread packages/react-headless/src/store/artifactTypes.ts Outdated
@ankit-thesys
ankit-thesys requested a review from abhithesys March 23, 2026 09:03

@abhithesys abhithesys left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lg.

Comment thread packages/react-headless/src/hooks/__tests__/useArtifact.test.ts Outdated
Comment thread packages/react-headless/src/hooks/__tests__/useArtifact.test.ts Outdated
@ankit-thesys
ankit-thesys merged commit 08dc83e into thesysdev:main Mar 24, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants