Skip to content

fix(sidepanel): fill artifact viewer height#1442

Merged
zerob13 merged 1 commit intodevfrom
codex/fix-artifact-pane-sizing
Apr 9, 2026
Merged

fix(sidepanel): fill artifact viewer height#1442
zerob13 merged 1 commit intodevfrom
codex/fix-artifact-pane-sizing

Conversation

@zerob13
Copy link
Copy Markdown
Collaborator

@zerob13 zerob13 commented Apr 9, 2026

fix #1438

Summary by CodeRabbit

  • Bug Fixes

    • Refined flex layout containers to improve content rendering and scrolling across artifact viewers and editor.
    • Strengthened HTML/SVG sanitization patterns.
    • Enhanced code editor responsiveness to viewport changes.
  • Tests

    • Added test coverage for artifact layouts, preview panes, and component sizing.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

This pull request refactors the component layout hierarchy to fix an issue where the artifact code pane doesn't take the full available window height. The changes apply flexbox constraints (min-h-0, flex-1, flex-col) across App.vue, workspace viewers, artifact components, and side panels to ensure proper height/width scaling and overflow handling in flex containers. Tests are added and updated to validate the new layout class composition.

Changes

Cohort / File(s) Summary
Core Layout Architecture
src/renderer/src/App.vue, src/renderer/src/views/ChatTabView.vue
Updated root containers to use full-height flex column layout with min-h-0 for proper flex-child scaling within viewport constraints.
Artifact Components
src/renderer/src/components/artifacts/HTMLArtifact.vue, MermaidArtifact.vue, ReactArtifact.vue, SvgArtifact.vue
Refactored artifact layouts to use flex-based sizing (min-h-0, flex-1) with viewport/responsive handling; added computed class bindings and data-testid attributes; improved HTML sanitization regexes for MermaidArtifact; removed legacy CSS in favor of Tailwind utilities for SvgArtifact.
Workspace Viewer Components
src/renderer/src/components/sidepanel/viewer/WorkspaceViewer.vue, WorkspaceCodePane.vue, WorkspacePreviewPane.vue, WorkspaceInfoPane.vue
Applied flex height constraints (min-h-0, flex-1, flex-col) to body and pane containers; added ResizeObserver lifecycle to code pane for dynamic Monaco editor layout; adjusted child pane classes to fill flex parent properly.
Side Panel Components
src/renderer/src/components/sidepanel/ChatSidePanel.vue, WorkspacePanel.vue
Added min-h-0 to root and inner containers for proper flex-child height scaling.
Test Coverage
test/renderer/components/HTMLArtifact.test.ts, MermaidArtifact.test.ts, ReactArtifact.test.ts, SvgArtifact.test.ts, WorkspacePreviewPane.test.ts, WorkspaceViewer.test.ts
Added new test files and updated existing tests to assert layout class composition across artifact and workspace viewer components; added mock for vue-i18n in Mermaid tests; replaced selector patterns to use data-testid.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • deepinfect

Poem

🐰 Flexboxes stretching from top to toe,
min-h-0 makes the layout flow,
Code pane soars to window's height,
ResizeObserver keeps views tight,
Artifacts now paint the night!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly addresses the main change: fixing the artifact viewer height filling issue in the sidepanel, which aligns with the PR's primary objective.
Linked Issues check ✅ Passed The PR successfully implements the fix for issue #1438 by updating flex layout utilities (min-h-0, flex-1, flex-col) across artifact components and sidepanel containers to ensure proper height distribution.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing artifact pane sizing and layout; no unrelated modifications detected across component updates and tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-artifact-pane-sizing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/renderer/src/components/sidepanel/viewer/WorkspaceCodePane.vue (1)

283-299: Prefer not to hide Monaco sizing rules in a scoped !important block.

This fix now depends on component-local deep selectors and !important overrides, which makes the layout harder to reason about and maintain than the Tailwind-based template changes above. If these overrides are unavoidable, I'd move them into a shared Monaco/editor stylesheet instead of keeping them embedded in one pane component. As per coding guidelines src/renderer/src/**/*.vue: Use Tailwind for styling.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/src/components/sidepanel/viewer/WorkspaceCodePane.vue` around
lines 283 - 299, The component WorkspaceCodePane.vue currently embeds scoped CSS
with deep selectors and multiple !important rules for
.workspace-code-editor-host and Monaco subselectors; remove these
scoped/deep/!important style overrides and instead move equivalent layout rules
into a shared, non-scoped Monaco/editor stylesheet (e.g., a global CSS or shared
tailwind-compatible file) so Monaco sizing is controlled globally; update the
template to rely on Tailwind utility classes on the .workspace-code-editor-host
element and ensure the shared stylesheet targets the Monaco classes
(.monaco-editor, .overflow-guard, .monaco-scrollable-element) without using
:deep or !important so the layout is consistent across panes.
src/renderer/src/components/artifacts/SvgArtifact.vue (1)

9-9: Optional: deduplicate repeated state container classes.

Loading, error, and empty states reuse the same class string; extracting it to a constant/class binding would reduce drift risk in future tweaks.

Also applies to: 18-18, 35-35

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/src/components/artifacts/SvgArtifact.vue` at line 9, The
repeated state container class string used in the template of SvgArtifact.vue
for loading, error, and empty states should be extracted to a single source to
avoid drift; add a constant or computed property (e.g., containerClass or
stateContainerClass) inside the SvgArtifact component script and replace each
hard-coded class="flex min-h-full w-full flex-1 flex-col items-center
justify-center p-8 text-center" with a binding :class="containerClass" (or use a
named CSS utility class and reference it) so all three places (the loading,
error, and empty state blocks) share the same value.
test/renderer/components/WorkspacePreviewPane.test.ts (1)

85-87: Consider deduplicating repeated pane layout assertions.

The same workspace-preview-pane class expectation appears in multiple tests; extracting a helper/constant will make updates less brittle.

Example refactor
+const expectedPreviewPaneClasses = [
+  'flex',
+  'h-full',
+  'min-h-0',
+  'w-full',
+  'flex-col',
+  'overflow-hidden'
+]
+
+const expectPreviewPaneLayout = (wrapper: ReturnType<typeof mount>) => {
+  expect(wrapper.get('[data-testid="workspace-preview-pane"]').classes()).toEqual(
+    expect.arrayContaining(expectedPreviewPaneClasses)
+  )
+}
...
-    expect(wrapper.get('[data-testid="workspace-preview-pane"]').classes()).toEqual(
-      expect.arrayContaining(['flex', 'h-full', 'min-h-0', 'w-full', 'flex-col', 'overflow-hidden'])
-    )
+    expectPreviewPaneLayout(wrapper)

Also applies to: 150-152, 199-201

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/renderer/components/WorkspacePreviewPane.test.ts` around lines 85 - 87,
Extract the repeated assertion of classes on
wrapper.get('[data-testid="workspace-preview-pane"]').classes() into a shared
helper or constant used by tests to avoid duplication; for example, add a
constant like EXPECTED_WORKSPACE_PREVIEW_PANE_CLASSES (or a helper function
assertWorkspacePreviewPaneLayout(wrapper)) and replace the repeated
expect(...).toEqual(expect.arrayContaining([...])) calls in
WorkspacePreviewPane.test.ts (occurring around the existing checks and at the
other noted locations) with calls to that constant/helper so updates only need
to change one place.
test/renderer/components/ReactArtifact.test.ts (1)

7-16: Avoid mounting to document.body when it isn’t needed.

This test only checks classes, so attachTo: document.body adds avoidable DOM coupling and potential residue between tests.

Proposed simplification
     const wrapper = mount(ReactArtifact, {
       props: {
         block: {
           content: 'export default function App() { return <div>Hello</div> }',
           artifact: { type: 'application/vnd.ant.react', title: 'App' }
         },
         isPreview: true
-      },
-      attachTo: document.body
+      }
     })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/renderer/components/ReactArtifact.test.ts` around lines 7 - 16, The test
for ReactArtifact mounts the component with attachTo: document.body which
creates unnecessary DOM coupling; update the test to remove the attachTo option
(or use shallowMount if you only need class/CSS assertions) so the wrapper is
mounted in the default JSDOM container and won't leave residues between
tests—modify the mount call in the ReactArtifact.test (the mount(...)
invocation) to omit attachTo: document.body or replace mount with shallowMount
when appropriate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/renderer/src/components/artifacts/MermaidArtifact.vue`:
- Around line 77-79: The current global regex that mutates the sanitized string
(the line assigning sanitized =
sanitized.replace(/on\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi, '')) removes on*
attributes from the entire Mermaid source and can strip valid diagram text like
"oncall=alice"; restrict the scrubber to only operate inside HTML tags by first
matching tag contents (e.g. use sanitized.replace(/<[^>]+>/g, tag => /* remove
on* attributes inside tag */)) and then removing on* attributes only within
those matched tag strings (i.e., run the on\w+... remover against the tag
substring in the replace callback), leaving plain Mermaid text untouched.

---

Nitpick comments:
In `@src/renderer/src/components/artifacts/SvgArtifact.vue`:
- Line 9: The repeated state container class string used in the template of
SvgArtifact.vue for loading, error, and empty states should be extracted to a
single source to avoid drift; add a constant or computed property (e.g.,
containerClass or stateContainerClass) inside the SvgArtifact component script
and replace each hard-coded class="flex min-h-full w-full flex-1 flex-col
items-center justify-center p-8 text-center" with a binding
:class="containerClass" (or use a named CSS utility class and reference it) so
all three places (the loading, error, and empty state blocks) share the same
value.

In `@src/renderer/src/components/sidepanel/viewer/WorkspaceCodePane.vue`:
- Around line 283-299: The component WorkspaceCodePane.vue currently embeds
scoped CSS with deep selectors and multiple !important rules for
.workspace-code-editor-host and Monaco subselectors; remove these
scoped/deep/!important style overrides and instead move equivalent layout rules
into a shared, non-scoped Monaco/editor stylesheet (e.g., a global CSS or shared
tailwind-compatible file) so Monaco sizing is controlled globally; update the
template to rely on Tailwind utility classes on the .workspace-code-editor-host
element and ensure the shared stylesheet targets the Monaco classes
(.monaco-editor, .overflow-guard, .monaco-scrollable-element) without using
:deep or !important so the layout is consistent across panes.

In `@test/renderer/components/ReactArtifact.test.ts`:
- Around line 7-16: The test for ReactArtifact mounts the component with
attachTo: document.body which creates unnecessary DOM coupling; update the test
to remove the attachTo option (or use shallowMount if you only need class/CSS
assertions) so the wrapper is mounted in the default JSDOM container and won't
leave residues between tests—modify the mount call in the ReactArtifact.test
(the mount(...) invocation) to omit attachTo: document.body or replace mount
with shallowMount when appropriate.

In `@test/renderer/components/WorkspacePreviewPane.test.ts`:
- Around line 85-87: Extract the repeated assertion of classes on
wrapper.get('[data-testid="workspace-preview-pane"]').classes() into a shared
helper or constant used by tests to avoid duplication; for example, add a
constant like EXPECTED_WORKSPACE_PREVIEW_PANE_CLASSES (or a helper function
assertWorkspacePreviewPaneLayout(wrapper)) and replace the repeated
expect(...).toEqual(expect.arrayContaining([...])) calls in
WorkspacePreviewPane.test.ts (occurring around the existing checks and at the
other noted locations) with calls to that constant/helper so updates only need
to change one place.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c9b812bf-bb8e-4a44-ac05-f0f800a90059

📥 Commits

Reviewing files that changed from the base of the PR and between c5afc64 and 06b907d.

📒 Files selected for processing (18)
  • src/renderer/src/App.vue
  • src/renderer/src/components/artifacts/HTMLArtifact.vue
  • src/renderer/src/components/artifacts/MermaidArtifact.vue
  • src/renderer/src/components/artifacts/ReactArtifact.vue
  • src/renderer/src/components/artifacts/SvgArtifact.vue
  • src/renderer/src/components/sidepanel/ChatSidePanel.vue
  • src/renderer/src/components/sidepanel/WorkspacePanel.vue
  • src/renderer/src/components/sidepanel/WorkspaceViewer.vue
  • src/renderer/src/components/sidepanel/viewer/WorkspaceCodePane.vue
  • src/renderer/src/components/sidepanel/viewer/WorkspaceInfoPane.vue
  • src/renderer/src/components/sidepanel/viewer/WorkspacePreviewPane.vue
  • src/renderer/src/views/ChatTabView.vue
  • test/renderer/components/HTMLArtifact.test.ts
  • test/renderer/components/MermaidArtifact.test.ts
  • test/renderer/components/ReactArtifact.test.ts
  • test/renderer/components/SvgArtifact.test.ts
  • test/renderer/components/WorkspacePreviewPane.test.ts
  • test/renderer/components/WorkspaceViewer.test.ts

@zerob13 zerob13 merged commit dbe0319 into dev Apr 9, 2026
3 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.

[BUG] Artifacts code pane don't take full window height

1 participant